use std::path::Path;

use crate::plugin::{CleanAction, CleanTarget, Plugin, Safety};
use crate::utils;

pub struct ClaudePlugin;

impl Plugin for ClaudePlugin {
    fn name(&self) -> &str {
        "claude"
    }

    fn description(&self) -> &str {
        "Claude Code caches, logs, conversations, and worktrees"
    }

    fn scan_directory(&self, dir: &Path) -> Vec<CleanTarget> {
        let mut targets = Vec::new();

        let claude_dir = dir.join(".claude");
        if !claude_dir.is_dir() {
            return targets;
        }

        // Worktrees — large, recoverable (just checked-out copies)
        let worktrees = claude_dir.join("worktrees");
        if worktrees.is_dir() {
            let size = utils::dir_size(&worktrees);
            if size > 0 {
                targets.push(CleanTarget {
                    label: format!("{} (worktrees)", worktrees.display()),
                    size_bytes: size,
                    action: CleanAction::DeletePath(worktrees),
                    plugin_name: self.name().to_string(),
                    safety: Safety::Recoverable,
                    explanation: "Claude Code worktrees, recreated as needed".to_string(),
                });
            }
        }

        targets
    }

    fn global_targets(&self) -> Vec<CleanTarget> {
        let mut targets = Vec::new();

        let home_claude = utils::home_dir().join(".claude");
        if !home_claude.is_dir() {
            return targets;
        }

        // Debug logs — safe to delete, can be large
        add_dir_target(
            &mut targets,
            &home_claude.join("debug"),
            "debug logs",
            Safety::Recoverable,
            "claude",
            "Claude Code debug logs",
        );

        // Telemetry data
        add_dir_target(
            &mut targets,
            &home_claude.join("telemetry"),
            "telemetry",
            Safety::Recoverable,
            "claude",
            "Claude Code telemetry data",
        );

        // Conversation history / projects (contains session transcripts)
        add_dir_target(
            &mut targets,
            &home_claude.join("projects"),
            "conversation logs",
            Safety::Unsafe,
            "claude",
            "Claude Code conversation logs",
        );

        // File history snapshots
        add_dir_target(
            &mut targets,
            &home_claude.join("file-history"),
            "file history",
            Safety::Recoverable,
            "claude",
            "Claude Code file history cache",
        );

        // Shell snapshots
        add_dir_target(
            &mut targets,
            &home_claude.join("shell-snapshots"),
            "shell snapshots",
            Safety::Recoverable,
            "claude",
            "Claude Code shell state snapshots",
        );

        // Session environment cache
        add_dir_target(
            &mut targets,
            &home_claude.join("session-env"),
            "session env cache",
            Safety::Recoverable,
            "claude",
            "Claude Code session environment cache",
        );

        // Paste cache
        add_dir_target(
            &mut targets,
            &home_claude.join("paste-cache"),
            "paste cache",
            Safety::Recoverable,
            "claude",
            "Claude Code paste cache",
        );

        // Plans
        add_dir_target(
            &mut targets,
            &home_claude.join("plans"),
            "plans",
            Safety::Unsafe,
            "claude",
            "Claude Code plans",
        );

        // Todos
        add_dir_target(
            &mut targets,
            &home_claude.join("todos"),
            "todos",
            Safety::Unsafe,
            "claude",
            "Claude Code todos",
        );

        // Tasks
        add_dir_target(
            &mut targets,
            &home_claude.join("tasks"),
            "tasks",
            Safety::Unsafe,
            "claude",
            "Claude Code tasks",
        );

        // Cache
        add_dir_target(
            &mut targets,
            &home_claude.join("cache"),
            "cache",
            Safety::Recoverable,
            "claude",
            "Claude Code cache",
        );

        targets
    }

    fn skip_subdirectories(&self) -> &'static [&'static str] {
        &[".claude"]
    }

    fn markers(&self) -> &'static [&'static str] {
        &[".claude"]
    }
}

fn add_dir_target(
    targets: &mut Vec<CleanTarget>,
    path: &std::path::Path,
    label_suffix: &str,
    safety: Safety,
    plugin_name: &str,
    explanation: &str,
) {
    if path.is_dir() {
        let size = utils::dir_size(path);
        if size > 0 {
            targets.push(CleanTarget {
                label: format!("{} ({})", path.display(), label_suffix),
                size_bytes: size,
                action: CleanAction::DeletePath(path.to_path_buf()),
                plugin_name: plugin_name.to_string(),
                safety,
                explanation: explanation.to_string(),
            });
        }
    }
}
