use std::path::Path;

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

pub struct DotnetPlugin;

impl Plugin for DotnetPlugin {
    fn name(&self) -> &str {
        "dotnet"
    }

    fn description(&self) -> &str {
        ".NET build outputs (bin/obj) and NuGet cache"
    }

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

        // Verify this is a .NET project directory
        let is_dotnet = std::fs::read_dir(dir)
            .into_iter()
            .flatten()
            .flatten()
            .any(|entry| {
                let name = entry.file_name();
                let name = name.to_string_lossy();
                name.ends_with(".csproj") || name.ends_with(".fsproj") || name.ends_with(".vbproj")
            });

        if !is_dotnet {
            return targets;
        }

        for subdir_name in &["bin", "obj"] {
            let subdir = dir.join(subdir_name);
            if subdir.is_dir() {
                let size = utils::dir_size(&subdir);
                targets.push(CleanTarget {
                    label: format!("{}", subdir.display()),
                    size_bytes: size,
                    action: CleanAction::DeletePath(subdir),
                    plugin_name: self.name().to_string(),
                    safety: Safety::Recoverable,
                    explanation: ".NET build output, recreate with `dotnet build`".to_string(),
                });
            }
        }

        targets
    }

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

        let nuget_cache = home.join(".nuget/packages");
        if nuget_cache.is_dir() {
            let size = utils::dir_size(&nuget_cache);
            targets.push(CleanTarget {
                label: format!("{}", nuget_cache.display()),
                size_bytes: size,
                action: CleanAction::DeletePath(nuget_cache),
                plugin_name: self.name().to_string(),
                safety: Safety::Recoverable,
                explanation: "NuGet package cache, re-downloaded as needed".to_string(),
            });
        }

        targets
    }

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

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