use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
use std::fs;
use crate::FluentPlugin;

pub struct ListLocales;

impl SimplePluginCommand for ListLocales {
    type Plugin = FluentPlugin;

    fn name(&self) -> &str {
        "fluent-list-locales"
    }

    fn signature(&self) -> Signature {
        Signature::build(PluginCommand::name(self))
            .input_output_type(Type::Any, Type::List(Box::new(Type::String)))
            .required("directory", SyntaxShape::Directory, "Directory containing locale folders")
            .category(Category::Strings)
    }

    fn description(&self) -> &str {
        "List available locales from a directory structure"
    }

    fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
        vec![
            nu_protocol::Example {
                description: "List available locales",
                example: "fluent-list-locales ./locales",
                result: None,
            },
        ]
    }

    fn run(
        &self,
        _plugin: &Self::Plugin,
        _engine: &EngineInterface,
        call: &EvaluatedCall,
        _input: &Value,
    ) -> Result<Value, LabeledError> {
        let directory: String = call.req(0)?;

        let entries = fs::read_dir(&directory)
            .map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read directory '{}': {}", directory, e), call.head))?;

        let mut locales = Vec::new();

        for entry in entries {
            let entry = entry
                .map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read directory entry: {}", e), call.head))?;

            if entry.file_type()
                .map_err(|e| LabeledError::new("File type error").with_label(format!("Failed to get file type: {}", e), call.head))?
                .is_dir()
            {
                if let Some(name) = entry.file_name().to_str() {
                    // Basic locale pattern matching (e.g., en-US, es-ES)
                    if name.len() == 5 && name.chars().nth(2) == Some('-') {
                        locales.push(Value::string(name.to_string(), call.head));
                    }
                }
            }
        }

        Ok(Value::list(locales, call.head))
    }
}