// Copyright (c) 2026 Joydev GmbH (joydev.com)
// SPDX-License-Identifier: MIT

use anyhow::Result;
use chrono::{DateTime, Local};
use clap::Args;

use joy_core::items;
use joy_core::store;

use crate::color;

#[derive(Args)]
pub struct ShowArgs {
    /// Item ID (e.g. IT-0001)
    #[arg(add = clap_complete::engine::ArgValueCompleter::new(crate::complete::complete_item_id))]
    id: String,

    /// Compact output: emoji-only or abbreviations
    #[arg(short = 'S', long)]
    pub short: bool,
}

pub fn run(args: ShowArgs) -> Result<()> {
    let cwd = std::env::current_dir()?;
    let root = store::find_project_root(&cwd).ok_or(joy_core::error::JoyError::NotInitialized)?;

    let item = items::load_item(&root, &args.id)?;
    let all_items = items::load_items(&root)?;

    let w = color::terminal_width();
    println!("{}", color::label(&"-".repeat(w)));
    println!("{} {}", color::id(&item.id), color::label(&item.title));
    println!("{}", color::label(&"-".repeat(w)));
    let (_, type_display) = color::item_type_display(&item.item_type);
    let (_, status_display) = color::status_display(&item.status);
    let (_, priority_display) = color::priority_display(&item.priority);
    println!("{} {}", color::label("Type:    "), type_display);
    println!("{} {}", color::label("Status:  "), status_display);
    println!("{} {}", color::label("Priority:"), priority_display);

    if let Some(ref parent) = item.parent {
        println!("{} {}", color::label("Parent:  "), color::id(parent));
    }
    if !item.assignees.is_empty() {
        if item.assignees.len() == 1 && item.assignees[0].capabilities.is_empty() {
            println!("{} {}", color::label("Assignee:"), item.assignees[0].member);
        } else {
            println!("{}:", color::label("Assignees"));
            for a in &item.assignees {
                if a.capabilities.is_empty() {
                    println!("  {}", a.member);
                } else {
                    let caps: Vec<String> = a.capabilities.iter().map(|c| c.to_string()).collect();
                    println!("  {}  {}", a.member, caps.join(", "));
                }
            }
        }
    }
    if let Some(ref milestone) = item.milestone {
        println!("{} {}", color::label("Milestone:"), color::id(milestone));
    }
    if !item.tags.is_empty() {
        println!("{} {}", color::label("Tags:    "), item.tags.join(", "));
    }
    if let Some(ref version) = item.version {
        println!("{} {}", color::label("Version: "), version);
    }
    if !item.capabilities.is_empty() {
        let caps: Vec<String> = item.capabilities.iter().map(|c| c.to_string()).collect();
        println!("{} {}", color::label("Capabilities:"), caps.join(", "));
    }

    // Show item-level mode override (only if explicitly set on the item)
    if let Some(ref mode) = item.mode {
        // Check if clamped by max-mode of first assignee
        let clamped = item.assignees.first().and_then(|a| {
            let project = joy_core::store::load_project(&root).ok()?;
            let member = project.members.get(&a.member)?;
            match &member.capabilities {
                joy_core::model::project::MemberCapabilities::Specific(map) => {
                    // Find the capability for the current status
                    item.capabilities.iter().find_map(|cap| {
                        let config = map.get(cap)?;
                        let max = config.max_mode?;
                        if mode < &max {
                            Some((max, *mode))
                        } else {
                            None
                        }
                    })
                }
                _ => None,
            }
        });

        if let Some((effective, original)) = clamped {
            println!(
                "{} {} {}",
                color::label("Mode:"),
                effective,
                color::inactive(&format!("[project max, item: {original}]"))
            );
        } else {
            println!("{} {}", color::label("Mode:"), mode);
        }
    }

    if !item.deps.is_empty() {
        println!("\n{}:", color::label("Dependencies"));
        for dep_id in &item.deps {
            let dep_info = all_items
                .iter()
                .find(|i| &i.id == dep_id)
                .map(|i| format!("{} [{}]", i.title, color::status(&i.status)))
                .unwrap_or_else(|| "(not found)".to_string());
            println!("  {} {}", color::id(dep_id), dep_info);
        }
    }

    if item.is_blocked_by(&all_items) {
        let blockers: Vec<_> = all_items
            .iter()
            .filter(|i| item.deps.contains(&i.id) && i.is_active())
            .collect();
        println!("\n  {}", color::blocked("BLOCKED"));
        for blocker in &blockers {
            println!(
                "    {} {} [{}]",
                color::id(&blocker.id),
                blocker.title,
                color::status(&blocker.status)
            );
        }
    }

    if let Some(ref desc) = item.description {
        println!("\n{}", desc.trim_end());
    }

    if !item.comments.is_empty() {
        println!("\n{}:", color::label("Comments"));
        for (i, comment) in item.comments.iter().enumerate() {
            if i > 0 {
                println!();
            }
            let local_dt: DateTime<Local> = comment.date.with_timezone(&Local);
            let date_str = local_dt.format("%Y-%m-%d %H:%M").to_string();
            println!(
                "{} [{}]",
                color::label(&date_str),
                color::user(&comment.author),
            );
            for line in comment.text.lines() {
                println!("{line}");
            }
        }
    }

    println!("{}", color::label(&"-".repeat(w)));
    let created_info = match &item.created_by {
        Some(by) => format!(
            "{} {} by {}  {} {}",
            color::label("Created:"),
            color::label(&item.created.format("%Y-%m-%d %H:%M").to_string()),
            color::user(by),
            color::label("Updated:"),
            color::label(&item.updated.format("%Y-%m-%d %H:%M").to_string())
        ),
        None => format!(
            "{} {}  {} {}",
            color::label("Created:"),
            color::label(&item.created.format("%Y-%m-%d %H:%M").to_string()),
            color::label("Updated:"),
            color::label(&item.updated.format("%Y-%m-%d %H:%M").to_string())
        ),
    };
    println!("{created_info}");

    Ok(())
}
