use std::path::PathBuf;

use app_tauri_lib::state::AppState;
use application::CreateProjectInput;
use base64::Engine as _;
use infrastructure::TicketToolProvider;
use serde_json::json;
use uuid::Uuid;

fn temp_path(tag: &str) -> PathBuf {
    std::env::temp_dir().join(format!("idea-app-tauri-test-{tag}-{}", Uuid::new_v4()))
}

#[tokio::test]
async fn idea_ticket_attachment_tools_add_read_and_mark_summarized() {
    let state = AppState::build(temp_path("appdata"));
    let project_root = temp_path("project");
    let project = state
        .create_project
        .execute(CreateProjectInput {
            name: "App Tauri Attachments".to_owned(),
            root: project_root.to_string_lossy().into_owned(),
            remote: None,
            default_profile_id: None,
        })
        .await
        .expect("test project is created")
        .project;

    let created = state
        .ticket_tool_binder
        .handle_ticket_tool(
            &project,
            "qa-agent",
            "idea_ticket_create",
            json!({ "title": "Attachment over tool provider" }),
        )
        .await
        .expect("ticket create succeeds");
    let ticket_ref = created["ref"].as_str().expect("ticket ref").to_owned();
    let ticket_version = created["version"].as_u64().expect("ticket version");

    let source = project_root.join("tool-attachment.txt");
    std::fs::write(&source, b"app tauri attachment payload")
        .expect("test writes source attachment");

    let attached = state
        .ticket_tool_binder
        .handle_ticket_tool(
            &project,
            "qa-agent",
            "idea_ticket_attachment_add",
            json!({
                "ref": ticket_ref,
                "path": source.to_string_lossy(),
                "mime": "text/plain",
                "expectedVersion": ticket_version
            }),
        )
        .await
        .expect("attachment add succeeds");
    let attachment = &attached["attachments"].as_array().expect("attachments")[0];
    assert_eq!(attachment["filename"], "tool-attachment.txt");
    assert_eq!(attachment["mime"], "text/plain");
    assert_eq!(attachment["summarizedInCarnet"], false);
    let attachment_id = attachment["id"].as_str().expect("attachment id").to_owned();
    let updated_version = attached["version"].as_u64().expect("updated version");

    let content = state
        .ticket_tool_binder
        .handle_ticket_tool(
            &project,
            "qa-agent",
            "idea_ticket_attachment_read",
            json!({
                "ref": ticket_ref,
                "attachmentId": attachment_id
            }),
        )
        .await
        .expect("attachment read succeeds");
    assert_eq!(content["attachment"]["filename"], "tool-attachment.txt");
    assert_eq!(
        content["contentBase64"],
        base64::engine::general_purpose::STANDARD_NO_PAD.encode(b"app tauri attachment payload")
    );

    let summarized = state
        .ticket_tool_binder
        .handle_ticket_tool(
            &project,
            "qa-agent",
            "idea_ticket_attachment_mark_summarized",
            json!({
                "ref": ticket_ref,
                "attachmentId": content["attachment"]["id"],
                "expectedVersion": updated_version
            }),
        )
        .await
        .expect("mark summarized succeeds");
    let summarized_attachment = &summarized["attachments"].as_array().expect("attachments")[0];
    assert_eq!(summarized_attachment["summarizedInCarnet"], true);
    assert_eq!(summarized_attachment["summarizedBy"]["kind"], "user");
    assert!(summarized_attachment["summarizedAt"].as_u64().is_some());
}
