use std::path::PathBuf;

use serde::{Deserialize, Serialize};

/// 子代理会话状态
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TaskSessionState {
    /// 正在执行
    Running,
    /// 已完成
    Completed,
    /// 已失败
    Failed,
    /// 已超时
    Timeout,
}

impl Default for TaskSessionState {
    fn default() -> Self {
        Self::Running
    }
}

/// 子代理来源
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SubagentSource {
    /// 内置定义
    Builtin,
    /// 用户级自定义 (~/.picobot/subagents/)
    User,
    /// 项目级自定义 (./.picobot/subagents/)
    Project,
}

/// 子代理完整定义
#[derive(Debug, Clone)]
pub struct SubagentDef {
    /// 名称标识
    pub name: String,
    /// 简短描述（用于 agent 选择）
    pub description: String,
    /// 提示词模板，支持 {{description}} 和 {{prompt}} 插值
    pub prompt_template: String,
    /// 可选的详细指令（body 部分）
    pub body: Option<String>,
    /// 工具白名单（None 表示使用默认）
    pub allowed_tools: Option<Vec<String>>,
    /// 最大执行时间（秒），None 表示使用默认
    pub max_execution_secs: Option<u64>,
    /// 来源
    pub source: SubagentSource,
    /// 文件路径（仅自定义类型）
    pub path: Option<PathBuf>,
}

impl SubagentDef {
    /// 创建内置 general 子代理定义
    pub fn builtin_general() -> Self {
        Self {
            name: "general".to_string(),
            description: "通用型子代理 - 处理复杂多步骤任务".to_string(),
            prompt_template: "你是一个专注的子代理，正在执行一个独立任务。\n\n任务描述: {{description}}\n\n你应该:\n1. 专注于完成任务，不要偏离目标\n2. 使用可用的工具进行必要操作\n3. 完成后给出简洁的总结\n4. 不要尝试创建新的子代理任务\n\n任务追踪:\n你可以使用 `todo_write` 工具追踪子任务进度。规则：同一时间只有一个 in_progress，完成后再标记下一个，3步以上才使用。\n\n注意: 你没有访问主对话历史的权限，这是一个独立的执行上下文。".to_string(),
            body: None,
            allowed_tools: None,
            max_execution_secs: None,
            source: SubagentSource::Builtin,
            path: None,
        }
    }

    /// 创建内置 explore 子代理定义
    pub fn builtin_explore() -> Self {
        Self {
            name: "explore".to_string(),
            description: "探索型子代理 - 只读搜索代理".to_string(),
            prompt_template: "你是一个只读探索代理，用于代码库探索和信息收集。\n\n任务描述: {{description}}\n\n你应该:\n1. 只使用只读工具进行探索\n2. 专注于理解和收集信息\n3. 不要进行任何写操作\n4. 给出简洁的发现总结\n\n注意: 你是一个只读代理，禁止执行任何修改操作。".to_string(),
            body: None,
            allowed_tools: None,
            max_execution_secs: None,
            source: SubagentSource::Builtin,
            path: None,
        }
    }
}

/// 子代理类型标识（用于 API 参数）
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct SubagentType {
    pub name: String,
}

impl SubagentType {
    pub fn new(name: &str) -> Self {
        Self {
            name: if name.is_empty() {
                "general".to_string()
            } else {
                name.to_string()
            },
        }
    }

    pub fn as_str(&self) -> &str {
        &self.name
    }
}

impl Serialize for SubagentType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(&self.name)
    }
}

impl<'de> Deserialize<'de> for SubagentType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(Self::new(&s))
    }
}

/// 任务会话记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskSession {
    /// 任务唯一 ID (UUID)
    pub id: String,
    /// 子代理独立的 session_id（存储在 message 表）
    pub session_id: String,
    /// 父会话 ID (用于关联)
    pub parent_session_id: String,
    /// 父话题 ID (可选，用于关联)
    pub parent_topic_id: Option<String>,
    /// 父 chat_id
    pub parent_chat_id: String,
    /// 父 channel_name
    pub parent_channel_name: String,
    /// 任务描述
    pub description: String,
    /// 子代理类型名称
    pub subagent_type: String,
    /// 当前状态
    pub state: TaskSessionState,
    /// 创建时间
    pub created_at: i64,
    /// 最后更新时间
    pub updated_at: i64,
    /// 执行摘要
    pub summary: Option<String>,
    /// 错误信息
    pub error: Option<String>,
}

impl TaskSession {
    pub fn new(
        parent_session_id: String,
        parent_topic_id: Option<String>,
        parent_chat_id: String,
        parent_channel_name: String,
        description: String,
        subagent_type: SubagentType,
    ) -> Self {
        let id = format!("task:{}", uuid::Uuid::new_v4());
        let session_id = format!("sub:{}:{}", parent_session_id, id);
        let now = current_timestamp();
        Self {
            id,
            session_id,
            parent_session_id,
            parent_topic_id,
            parent_chat_id,
            parent_channel_name,
            description,
            subagent_type: subagent_type.name.clone(),
            state: TaskSessionState::Running,
            created_at: now,
            updated_at: now,
            summary: None,
            error: None,
        }
    }

    /// 标记完成
    pub fn mark_completed(&mut self, summary: String) {
        self.state = TaskSessionState::Completed;
        self.summary = Some(summary);
        self.updated_at = current_timestamp();
    }

    /// 标记失败
    pub fn mark_failed(&mut self, error: String) {
        self.state = TaskSessionState::Failed;
        self.error = Some(error);
        self.updated_at = current_timestamp();
    }

    /// 标记超时
    pub fn mark_timeout(&mut self) {
        self.state = TaskSessionState::Timeout;
        self.error = Some("Task execution timed out".to_string());
        self.updated_at = current_timestamp();
    }
}

/// 任务工具参数
#[derive(Debug, Clone, Deserialize)]
pub struct TaskToolArgs {
    /// 简短描述（3-5词）
    pub description: String,
    /// 详细指令
    pub prompt: String,
    /// 子代理类型名称（默认 general）
    #[serde(default)]
    pub subagent_type: SubagentType,
    /// 恢复现有会话的 task_id
    #[serde(default)]
    pub task_id: Option<String>,
}

/// 任务定义（用于 SubAgentRuntime::spawn）
#[derive(Debug, Clone)]
pub struct TaskDefinition {
    pub description: String,
    pub prompt: String,
    pub subagent_type: SubagentType,
    pub max_execution_secs: Option<u64>,
}

impl From<TaskToolArgs> for TaskDefinition {
    fn from(args: TaskToolArgs) -> Self {
        Self {
            description: args.description,
            prompt: args.prompt,
            subagent_type: args.subagent_type,
            max_execution_secs: None,
        }
    }
}

/// 任务句柄（运行中任务）
#[derive(Debug, Clone)]
pub struct TaskHandle {
    pub task_id: String,
    pub session_id: String,
    pub status: TaskSessionState,
}

/// 任务执行结果
#[derive(Debug, Clone, Serialize)]
pub struct TaskToolResult {
    /// 状态: success/failed/timeout
    pub status: String,
    /// 任务完成总结
    pub summary: String,
    /// 详细输出
    pub output: String,
    /// 会话 ID（用于恢复）
    pub task_id: String,
}

fn current_timestamp() -> i64 {
    std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .expect("system clock before unix epoch")
        .as_millis() as i64
}
