use super::{
    MemoryRecord, MemoryUpsert, SchedulerJobRecord, SchedulerJobState, SchedulerJobStatus,
    SchedulerJobUpsert, SessionRecord, SkillEventRecord, StorageError, TodoRecord,
};
use crate::bus::ChatMessage;

pub trait ConversationRepository: Send + Sync + 'static {
    fn ensure_channel_session(
        &self,
        channel_name: &str,
        chat_id: &str,
    ) -> Result<SessionRecord, StorageError>;

    /// 确保指定 session_id 的会话存在（如果不存在则创建）
    fn ensure_session(
        &self,
        session_id: &str,
        channel_name: &str,
        chat_id: &str,
        title: &str,
    ) -> Result<SessionRecord, StorageError>;

    fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError>;

    fn load_messages_for_topic(
        &self,
        topic_id: &str,
        session_id: Option<&str>,
    ) -> Result<Vec<ChatMessage>, StorageError>;

    fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError>;

    fn append_message_with_topic(
        &self,
        session_id: &str,
        topic_id: Option<&str>,
        message: &ChatMessage,
    ) -> Result<(), StorageError>;

    fn append_messages_batch(
        &self,
        session_id: &str,
        topic_id: Option<&str>,
        messages: &[ChatMessage],
    ) -> Result<(), StorageError>;

    fn clear_messages(&self, session_id: &str) -> Result<(), StorageError>;

    fn compact_active_history(
        &self,
        session_id: &str,
        snapshot_end_seq: i64,
        preserved_system_messages: &[ChatMessage],
        summary_message: &ChatMessage,
        preserved_messages: &[ChatMessage],
    ) -> Result<bool, StorageError>;
}

pub trait PromptInjectionRepository: Send + Sync + 'static {
    fn get_session(&self, session_id: &str) -> Result<Option<SessionRecord>, StorageError>;

    fn count_active_user_messages(&self, session_id: &str) -> Result<i64, StorageError>;

    fn mark_agent_prompt_reinjected(&self, session_id: &str) -> Result<(), StorageError>;
}

pub trait MemoryRepository: Send + Sync + 'static {
    fn put_memory(&self, input: &MemoryUpsert) -> Result<MemoryRecord, StorageError>;

    fn update_memory(&self, input: &MemoryUpsert) -> Result<Option<MemoryRecord>, StorageError>;

    fn delete_memory(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: &str,
        memory_key: &str,
    ) -> Result<bool, StorageError>;

    fn get_memory(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: &str,
        memory_key: &str,
    ) -> Result<Option<MemoryRecord>, StorageError>;

    fn list_memories(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: Option<&str>,
        limit: usize,
    ) -> Result<Vec<MemoryRecord>, StorageError>;

    fn search_memories_any(
        &self,
        scope_kind: &str,
        scope_key: &str,
        queries: &[String],
        namespace: Option<&str>,
        limit: usize,
    ) -> Result<Vec<MemoryRecord>, StorageError>;
}

pub trait SchedulerJobRepository: Send + Sync + 'static {
    fn upsert_scheduler_job(
        &self,
        input: &SchedulerJobUpsert,
    ) -> Result<SchedulerJobRecord, StorageError>;

    fn get_scheduler_job(&self, job_id: &str) -> Result<Option<SchedulerJobRecord>, StorageError>;

    fn list_scheduler_jobs(
        &self,
        enabled_only: bool,
    ) -> Result<Vec<SchedulerJobRecord>, StorageError>;

    fn list_running_scheduler_jobs(&self) -> Result<Vec<SchedulerJobRecord>, StorageError>;

    fn delete_scheduler_job(&self, job_id: &str) -> Result<(), StorageError>;

    fn update_scheduler_job_runtime(
        &self,
        job_id: &str,
        state: SchedulerJobState,
        last_status: Option<SchedulerJobStatus>,
        last_error: Option<&str>,
        run_count: i64,
        last_fired_at: Option<i64>,
        next_fire_at: Option<i64>,
        paused_at: Option<i64>,
        completed_at: Option<i64>,
    ) -> Result<(), StorageError>;
}

pub trait SkillEventRepository: Send + Sync + 'static {
    fn append_skill_event(
        &self,
        session_id: Option<&str>,
        event_type: &str,
        skill_name: Option<&str>,
        payload: &serde_json::Value,
    ) -> Result<(), StorageError>;

    fn list_skill_events(
        &self,
        session_id: Option<&str>,
    ) -> Result<Vec<SkillEventRecord>, StorageError>;
}

pub trait TodoRepository: Send + Sync + 'static {
    /// Replace all todos for a scope (full replacement pattern).
    fn replace_todos(
        &self,
        scope_key: &str,
        todo_records: &[TodoRecord],
    ) -> Result<Vec<TodoRecord>, StorageError>;

    /// Load all todos for a scope, ordered by created_at.
    fn list_todos(&self, scope_key: &str) -> Result<Vec<TodoRecord>, StorageError>;
}

impl ConversationRepository for super::SessionStore {
    fn ensure_channel_session(
        &self,
        channel_name: &str,
        chat_id: &str,
    ) -> Result<SessionRecord, StorageError> {
        super::SessionStore::ensure_channel_session(self, channel_name, chat_id)
    }

    fn ensure_session(
        &self,
        session_id: &str,
        channel_name: &str,
        chat_id: &str,
        title: &str,
    ) -> Result<SessionRecord, StorageError> {
        super::SessionStore::ensure_session(self, session_id, channel_name, chat_id, title)
    }

    fn load_messages(&self, session_id: &str) -> Result<Vec<ChatMessage>, StorageError> {
        super::SessionStore::load_messages(self, session_id)
    }

    fn load_messages_for_topic(
        &self,
        topic_id: &str,
        session_id: Option<&str>,
    ) -> Result<Vec<ChatMessage>, StorageError> {
        super::SessionStore::load_messages_for_topic(self, topic_id, session_id)
    }

    fn append_message(&self, session_id: &str, message: &ChatMessage) -> Result<(), StorageError> {
        super::SessionStore::append_message(self, session_id, message)
    }

    fn append_message_with_topic(
        &self,
        session_id: &str,
        topic_id: Option<&str>,
        message: &ChatMessage,
    ) -> Result<(), StorageError> {
        super::SessionStore::append_message_with_topic(self, session_id, topic_id, message)
    }

    fn append_messages_batch(
        &self,
        session_id: &str,
        topic_id: Option<&str>,
        messages: &[ChatMessage],
    ) -> Result<(), StorageError> {
        super::SessionStore::append_messages_batch(self, session_id, topic_id, messages)
    }

    fn clear_messages(&self, session_id: &str) -> Result<(), StorageError> {
        super::SessionStore::clear_messages(self, session_id)
    }

    fn compact_active_history(
        &self,
        session_id: &str,
        snapshot_end_seq: i64,
        preserved_system_messages: &[ChatMessage],
        summary_message: &ChatMessage,
        preserved_messages: &[ChatMessage],
    ) -> Result<bool, StorageError> {
        super::SessionStore::compact_active_history(
            self,
            session_id,
            snapshot_end_seq,
            preserved_system_messages,
            summary_message,
            preserved_messages,
        )
    }
}

impl PromptInjectionRepository for super::SessionStore {
    fn get_session(&self, session_id: &str) -> Result<Option<SessionRecord>, StorageError> {
        super::SessionStore::get_session(self, session_id)
    }

    fn count_active_user_messages(&self, session_id: &str) -> Result<i64, StorageError> {
        super::SessionStore::count_active_user_messages(self, session_id)
    }

    fn mark_agent_prompt_reinjected(&self, session_id: &str) -> Result<(), StorageError> {
        super::SessionStore::mark_agent_prompt_reinjected(self, session_id)
    }
}

impl MemoryRepository for super::SessionStore {
    fn put_memory(&self, input: &MemoryUpsert) -> Result<MemoryRecord, StorageError> {
        super::SessionStore::put_memory(self, input)
    }

    fn update_memory(&self, input: &MemoryUpsert) -> Result<Option<MemoryRecord>, StorageError> {
        super::SessionStore::update_memory(self, input)
    }

    fn delete_memory(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: &str,
        memory_key: &str,
    ) -> Result<bool, StorageError> {
        super::SessionStore::delete_memory(self, scope_kind, scope_key, namespace, memory_key)
    }

    fn get_memory(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: &str,
        memory_key: &str,
    ) -> Result<Option<MemoryRecord>, StorageError> {
        super::SessionStore::get_memory(self, scope_kind, scope_key, namespace, memory_key)
    }

    fn list_memories(
        &self,
        scope_kind: &str,
        scope_key: &str,
        namespace: Option<&str>,
        limit: usize,
    ) -> Result<Vec<MemoryRecord>, StorageError> {
        super::SessionStore::list_memories(self, scope_kind, scope_key, namespace, limit)
    }

    fn search_memories_any(
        &self,
        scope_kind: &str,
        scope_key: &str,
        queries: &[String],
        namespace: Option<&str>,
        limit: usize,
    ) -> Result<Vec<MemoryRecord>, StorageError> {
        super::SessionStore::search_memories_any(
            self, scope_kind, scope_key, queries, namespace, limit,
        )
    }
}

impl SchedulerJobRepository for super::SessionStore {
    fn upsert_scheduler_job(
        &self,
        input: &SchedulerJobUpsert,
    ) -> Result<SchedulerJobRecord, StorageError> {
        super::SessionStore::upsert_scheduler_job(self, input)
    }

    fn get_scheduler_job(&self, job_id: &str) -> Result<Option<SchedulerJobRecord>, StorageError> {
        super::SessionStore::get_scheduler_job(self, job_id)
    }

    fn list_scheduler_jobs(
        &self,
        enabled_only: bool,
    ) -> Result<Vec<SchedulerJobRecord>, StorageError> {
        super::SessionStore::list_scheduler_jobs(self, enabled_only)
    }

    fn list_running_scheduler_jobs(&self) -> Result<Vec<SchedulerJobRecord>, StorageError> {
        super::SessionStore::list_running_scheduler_jobs(self)
    }

    fn delete_scheduler_job(&self, job_id: &str) -> Result<(), StorageError> {
        super::SessionStore::delete_scheduler_job(self, job_id)
    }

    fn update_scheduler_job_runtime(
        &self,
        job_id: &str,
        state: SchedulerJobState,
        last_status: Option<SchedulerJobStatus>,
        last_error: Option<&str>,
        run_count: i64,
        last_fired_at: Option<i64>,
        next_fire_at: Option<i64>,
        paused_at: Option<i64>,
        completed_at: Option<i64>,
    ) -> Result<(), StorageError> {
        super::SessionStore::update_scheduler_job_runtime(
            self,
            job_id,
            state,
            last_status,
            last_error,
            run_count,
            last_fired_at,
            next_fire_at,
            paused_at,
            completed_at,
        )
    }
}

impl SkillEventRepository for super::SessionStore {
    fn append_skill_event(
        &self,
        session_id: Option<&str>,
        event_type: &str,
        skill_name: Option<&str>,
        payload: &serde_json::Value,
    ) -> Result<(), StorageError> {
        super::SessionStore::append_skill_event(self, session_id, event_type, skill_name, payload)
    }

    fn list_skill_events(
        &self,
        session_id: Option<&str>,
    ) -> Result<Vec<SkillEventRecord>, StorageError> {
        super::SessionStore::list_skill_events(self, session_id)
    }
}

impl TodoRepository for super::SessionStore {
    fn replace_todos(
        &self,
        scope_key: &str,
        todo_records: &[TodoRecord],
    ) -> Result<Vec<TodoRecord>, StorageError> {
        super::SessionStore::replace_todos(self, scope_key, todo_records)
    }

    fn list_todos(&self, scope_key: &str) -> Result<Vec<TodoRecord>, StorageError> {
        super::SessionStore::list_todos(self, scope_key)
    }
}
