//! 任务创建参数校验(共享层)
//!
//! GUI AI 工具(ai/tools/task.rs)与 MCP 工具(crates/df-mcp/src/tools.rs)曾各自内联
//! 一套 create_task 校验(queue 白名单 / parent_id 嵌套铁律 / content_json 合法性),
//! 演进易漂移。抽到本模块后两套工具同源复用,一处修改全局生效。

use crate::crud::task_repo::TaskRepo;

/// queue 合法值白名单(queue 是独立管理维度,与 status 执行维度正交)
pub const TASK_QUEUE_VALUES: &[&str] = &["backlog", "todo", "decision", "active", "done"];

/// 默认优先级(medium)— 新任务默认中优先级,与 IPC create_task 一致
pub const DEFAULT_TASK_PRIORITY: i32 = 2;

/// 校验并归一化 create_task 的 queue:空串/缺省 → "todo";
/// 白名单校验 + create 一致性(新建仅 backlog/todo/decision,active/done 须经 move_task_queue 流转)。
pub fn normalize_queue_for_create(queue: Option<&str>) -> Result<String, String> {
    match queue {
        None | Some("") => Ok("todo".to_string()),
        Some(q) => {
            let q = q.trim();
            if !TASK_QUEUE_VALUES.contains(&q) {
                return Err(format!("非法 queue 值 {:?},合法值: {:?}", q, TASK_QUEUE_VALUES));
            }
            match q {
                "backlog" | "todo" | "decision" => Ok(q.to_string()),
                other => Err(format!(
                    "新建任务 queue 不可直接落 {:?}(须经 move_task_queue 流转),当前仅允许 backlog/todo/decision",
                    other
                )),
            }
        }
    }
}

/// 校验 content_json(非空时须是合法 JSON),返回规范化值(None=未传)。
pub fn validate_content_json(content: Option<&str>) -> Result<Option<String>, String> {
    match content {
        Some(c) if !c.trim().is_empty() => {
            serde_json::from_str::<serde_json::Value>(c)
                .map_err(|e| format!("content_json 不是合法 JSON: {e}"))?;
            Ok(Some(c.to_string()))
        }
        _ => Ok(None),
    }
}

/// 校验 parent_id 1 级嵌套铁律:父任务存在 + 父任务自身不是子任务(防孙任务)。
/// 返回归一化 parent_id(空串/缺省 → None)。
pub async fn validate_parent_id(
    repo: &TaskRepo,
    parent_id: Option<&str>,
) -> Result<Option<String>, String> {
    let pid = parent_id
        .map(|s| s.trim().to_string())
        .filter(|s| !s.is_empty());
    if let Some(pid) = &pid {
        let parent = repo
            .get_by_id(pid)
            .await
            .map_err(|e| e.to_string())?
            .ok_or_else(|| format!("父任务 {pid} 不存在,无法创建子任务"))?;
        if parent.parent_id.is_some() {
            return Err(format!(
                "违反 1 级嵌套铁律:父任务 {pid} 自身是子任务(parent_id={:?}),不允许在其下创建孙任务",
                parent.parent_id
            ));
        }
    }
    Ok(pid)
}

/// 校验并归一化 create_task 的 priority:缺省 → DEFAULT_TASK_PRIORITY;越界值拒绝(值域 0..=3)。
pub fn normalize_priority(priority: Option<i64>) -> Result<i32, String> {
    match priority {
        None => Ok(DEFAULT_TASK_PRIORITY),
        Some(p) if (0..=3).contains(&p) => Ok(p as i32),
        Some(p) => Err(format!(
            "非法 priority 值 {p},合法值: 整数 0..=3(0=critical, 1=high, 2=medium, 3=low)"
        )),
    }
}
