use std::collections::BTreeMap;

use arrayvec::ArrayVec;
use crossbeam_skiplist::SkipMap;
use derive_more::Debug;
use serde::{Deserialize, Serialize};

pub use self::persist::Persist;
use crate::Record;

pub mod persist;

#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct DbInfo {
    pub version: u64,
    pub collections: BTreeMap<String, CollectionInfo>,
}

#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default)]
pub struct CollectionInfo {
    pub seq: u64,
    #[debug("{:#X}", typ_hash)]
    pub typ_hash: u64,
    pub version: u16,
}

pub type FnArray<T> = ArrayVec<T, 8>;

/// item, old_id, new_id
pub type IdChangeEventFn<Item> =
    Box<dyn Fn(&Item, &<Item as Record>::SelfId, &<Item as Record>::SelfId) + Send + Sync>;

pub type UpsertEventFn<Item> = Box<dyn Fn(&<Item as Record>::SelfId, Change<Item>) + Send + Sync>;

pub type RemoveEventFn<Item> = Box<dyn Fn(&<Item as Record>::SelfId, &Item) + Send + Sync>;

#[derive(Debug, Clone, Copy)]
pub struct Change<'o, 'n, Item> {
    pub old: Option<&'o Item>,
    pub new: &'n Item,
}

pub enum MaybeParIter<P, I> {
    Par(P),
    Seq(I),
    Empty,
}

#[derive(Debug, Clone, Copy)]
pub struct GroupVal {
    pub hash: u64,
    // pub updated: Datetime,
    pub changed: bool,
}

pub type CheckSumVec = Vec<(u32, u64)>;
pub type HashPoints = SkipMap<u32, GroupVal>;
