use crate::error::Result;
use crate::format::{self, FormatOptions, Formatter};
use crate::model::{Lang, TwineFile};
use crate::output::OutputProcessor;

pub struct FlashFormatter;

impl Formatter for FlashFormatter {
    fn name(&self) -> &'static str {
        "flash"
    }
    fn extension(&self) -> &'static str {
        ".properties"
    }
    fn default_file_name(&self) -> &'static str {
        "resources.properties"
    }

    fn read(&self, content: &str, lang: &str, twine_file: &mut TwineFile) -> Result<()> {
        let kv_re = regex::Regex::new(r#"((?:[^"\\]|\\.)+)\s*=\s*((?:[^"\\]|\\.)*)"#).unwrap();
        let comment_re = regex::Regex::new(r"# *(.*)").unwrap();
        let mut last_comment: Option<String> = None;

        for line in content.lines() {
            if let Some(caps) = kv_re.captures(line) {
                let key = caps[1].to_string();
                let value = caps[2].trim().to_string();
                let value = crate::placeholders::convert_placeholders_from_flash_to_twine(&value);
                format::set_translation(twine_file, &key, lang, &value);
                if let Some(ref c) = last_comment {
                    format::set_comment(twine_file, &key, c);
                }
            }
            if let Some(caps) = comment_re.captures(line) {
                last_comment = Some(caps[1].to_string());
            } else {
                last_comment = None;
            }
        }
        Ok(())
    }

    fn format(&self, lang: &str, twine_file: &TwineFile, options: &FormatOptions) -> Result<Option<String>> {
        let processor = OutputProcessor::new(twine_file.clone(), options.clone());
        let processed = processor.process(lang);

        let mut out = format!(
            "## Flash Strings File\n## Generated by Twinex\n## Language: {}\n\n",
            lang
        );
        let mut has_content = false;

        for section in &processed.sections {
            if section.definitions.is_empty() {
                continue;
            }
            if !section.name.as_str().is_empty() {
                out.push_str(&format!("## {} ##\n", section.name));
            }
            for def in &section.definitions {
                if let Some(ref comment) = def.comment {
                    out.push_str(&format!("# {}\n", comment));
                }
                let value = def.translations.get(&Lang::new(lang)).map(|s| s.as_str()).unwrap_or("");
                let value = crate::placeholders::convert_placeholders_from_twine_to_flash(value);
                out.push_str(&format!("{}={}\n", def.key, value));
                has_content = true;
            }
        }
        if has_content { Ok(Some(out)) } else { Ok(None) }
    }
}