use anyhow::Result;
use async_trait::async_trait;

pub mod schema;

use crate::core::chunk::Chunk;

#[derive(Debug, Clone)]
pub struct SearchResult {
    pub uuid: String,
    pub chunk_id: String,
    pub score: f32,
}

#[async_trait]
pub trait Database: Send + Sync {
    async fn init() -> Result<Self>
    where
        Self: Sized;
}

#[async_trait]
pub trait ChunkStore: Send + Sync {
    async fn store_chunk(&self, chunk: &Chunk) -> Result<()>;
    async fn get_chunks_by_uuid(&self, uuid: &str) -> Result<Vec<Chunk>>;
    async fn get_all_chunks(&self) -> Result<Vec<Chunk>>;
}

#[async_trait]
pub trait VectorStore: Send + Sync {
    async fn store_vector(&self, chunk_id: &str, vector: &[f32]) -> Result<()>;
    async fn search(&self, query_vector: &[f32], limit: usize) -> Result<Vec<SearchResult>>;
}

pub mod mongodb_db;
pub mod postgres_db;
pub mod qdrant_db;
pub mod redis_client;
pub mod redis_db;
pub mod sync_db;

pub use mongodb_db::MongoDb;
pub use postgres_db::{
    Bm25Result, CandidateRecord, CreateApiKeyConfig, FileIdentityRecord, FileRecord,
    HybridSearchResult, IdentityChunkRecord, IdentityDetailRecord, IdentityFaceRecord,
    IdentityFileRecord, MonitorJob, MonitorJobStats, MonitorJobStatus, PostgresDb,
    ProcessorJobStatus, ProcessorResult, ProcessorType, ResourceRecord, VideoRecord, VideoStatus,
};
pub use qdrant_db::{QdrantDb, VectorPayload};
pub use redis_client::{
    JobErrorMessage, MonitorJobRedis, ProcessorStatus as RedisProcessorStatus, ProgressData,
    ProgressMessage, RedisClient,
};
pub use redis_db::RedisDb;
pub use sync_db::SyncDb;
