use ai::error::{AiError, AiResult};
use ai::tool::register::ToolRegister;
use db::sqlx;
use serde_json::Value;
use uuid::Uuid;

use crate::agent::run::{AppAgentContext, GitAgentContext};

pub fn register_issue_tools(tools: &mut ToolRegister<AppAgentContext>) {
    tools.register(super::issue::IssueListTool::new());
    tools.register(super::issue::IssueGetTool::new());
    tools.register(super::issue::IssueCommentsTool::new());
    tools.register(super::issue::IssueEventsTool::new());
}

pub(super) async fn require_workspace_member(
    git: &GitAgentContext,
    user_id: Uuid,
    workspace_name: &str,
) -> AiResult<Uuid> {
    let wk_id: Uuid =
        sqlx::query_scalar("SELECT id FROM workspace WHERE name = $1")
            .bind(workspace_name)
            .fetch_optional(git.db.reader())
            .await
            .map_err(AiError::Database)?
            .ok_or_else(|| {
                AiError::Config(format!(
                    "workspace '{workspace_name}' not found"
                ))
            })?;

    let is_member: i64 = sqlx::query_scalar(
        "SELECT COUNT(*) FROM wk_member \
         WHERE wk = $1 AND \"user\" = $2 AND leave_at IS NULL",
    )
    .bind(wk_id)
    .bind(user_id)
    .fetch_one(git.db.reader())
    .await
    .map_err(AiError::Database)?;

    if is_member == 0 {
        return Err(AiError::Config(format!(
            "user is not a member of workspace '{workspace_name}'"
        )));
    }

    Ok(wk_id)
}

pub(super) fn git_ctx(ctx: &AppAgentContext) -> AiResult<&GitAgentContext> {
    ctx.git.as_ref().ok_or_else(|| {
        AiError::Config(
            "issue tools are not available in this session".to_string(),
        )
    })
}

pub(super) fn arg_str<'a>(args: &'a Value, key: &str) -> AiResult<&'a str> {
    args.get(key).and_then(|v| v.as_str()).ok_or_else(|| {
        AiError::Config(format!("'{key}' parameter is required"))
    })
}
