use eframe::egui::{self, Color32};
use rust_i18n::t;
use crate::installer::{GlobalState, InstallerStep};
use crate::ui::theme;

/// Klavye düzeni ve varyantı seçimi.
/// Mevcut düzenler `/usr/share/X11/xkb/rules/evdev.lst` dosyasından okunur.
/// Dosya okunamazsa sabit bir temel liste kullanılır.
pub struct KeyboardStep {
    test_input: String,
    layouts: Vec<(String, String)>,                // (kod, gösterim adı)
    variants: Vec<(String, String, String)>,       // (layout, variant, gösterim adı)
}

fn default_keyboard_layouts() -> Vec<(String, String)> {
    vec![
        ("tr".to_string(), "Türkçe (Q)".to_string()),
        ("az".to_string(), "Azərbaycanca".to_string()),
        ("us".to_string(), "İngilizce (US)".to_string()),
        ("de".to_string(), "Almanca".to_string()),
        ("fr".to_string(), "Fransızca".to_string()),
        ("es".to_string(), "İspanyolca".to_string()),
        ("ru".to_string(), "Rusça".to_string()),
        ("ar".to_string(), "Arapça".to_string()),
    ]
}

fn default_keyboard_variants() -> Vec<(String, String, String)> {
    vec![
        ("tr".to_string(), "f".to_string(), "Türkçe (F)".to_string()),
        ("az".to_string(), "cyrillic".to_string(), "Azərbaycan (Kiril)".to_string()),
    ]
}

fn load_keyboard_layouts() -> (Vec<(String, String)>, Vec<(String, String, String)>) {
    let path = "/usr/share/X11/xkb/rules/evdev.lst";
    let contents = std::fs::read_to_string(path).ok();

    let mut layouts = Vec::new();
    let mut variants = Vec::new();
    let mut section: Option<&str> = None;

    if let Some(text) = contents {
        for line in text.lines() {
            let line = line.trim_end();
            if line.starts_with('!') {
                section = if line.starts_with("! layout") {
                    Some("layout")
                } else if line.starts_with("! variant") {
                    Some("variant")
                } else {
                    None
                };
                continue;
            }

            let trimmed = line.trim();
            if trimmed.is_empty() {
                continue;
            }

            if let Some(section) = section {
                if let Some((code, desc)) = split_code_desc(trimmed) {
                    match section {
                        "layout" => layouts.push((code.to_string(), desc.to_string())),
                        "variant" => {
                            if let Some((layout, display)) = desc.split_once(':') {
                                variants.push((layout.trim().to_string(), code.to_string(), display.trim().to_string()));
                            }
                        }
                        _ => {}
                    }
                }
            }
        }
    }

    if layouts.is_empty() {
        (default_keyboard_layouts(), default_keyboard_variants())
    } else {
        (layouts, variants)
    }
}

fn split_code_desc(line: &str) -> Option<(&str, &str)> {
    let mut parts = line.splitn(2, char::is_whitespace);
    let code = parts.next()?.trim();
    let desc = parts.next()?.trim();
    if code.is_empty() || desc.is_empty() {
        None
    } else {
        Some((code, desc))
    }
}
fn layout_display_name(layout: &str, layouts: &[(String, String)]) -> String {
    layouts
        .iter()
        .find(|(code, _)| code == layout)
        .map(|(_, display)| display.clone())
        .unwrap_or_else(|| layout.to_string())
}

fn variant_display_name(
    layout: &str,
    variant: &str,
    variants: &[(String, String, String)],
) -> String {
    variants
        .iter()
        .find(|(layout_code, v_code, _)| layout_code == layout && v_code == variant)
        .map(|(_, _, display)| display.clone())
        .unwrap_or_else(|| variant.to_string())
}


fn apply_system_keyboard_layout(layout: &str, variant: &str) {
    if std::env::var("DISPLAY").is_ok() {
        let mut cmd = std::process::Command::new("setxkbmap");
        cmd.arg(layout);
        if !variant.is_empty() {
            cmd.arg("-variant").arg(variant);
        }
        let _ = cmd.output();
    }
}

impl Default for KeyboardStep {
    fn default() -> Self {
        let (layouts, variants) = load_keyboard_layouts();
        Self {
            test_input: String::new(),
            layouts,
            variants,
        }
    }
}

impl InstallerStep for KeyboardStep {
    fn name(&self) -> String {
        t!("keyboard").to_string()
    }

    fn on_enter(&mut self, state: &mut GlobalState) {
        // Varsayılan düzen sistemi diline göre seçilir
        if state.keyboard_layout.is_empty() {
            state.keyboard_layout = if state.language == "tr" {
                "tr".to_string()
            } else {
                "us".to_string()
            };
        }
        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
    }

    fn show(&mut self, ui: &mut egui::Ui, state: &mut GlobalState) {
        if state.keyboard_layout.is_empty() {
            state.keyboard_layout = if state.language == "tr" { "tr" } else { "us" }.to_string();
        }

        ui.heading(t!("keyboard_title"));
        ui.label(t!("keyboard_description"));

        ui.add_space(12.0);

        // ── Klavye görseli (xkbcommon ile çizilir, temaya uyumlu) ─
        if let Some(kle) = crate::ui::kle_svg::compile_layout(&state.keyboard_layout, &state.keyboard_variant) {
            let max = egui::Vec2::new(ui.available_width(), ui.available_height().max(100.0));
            crate::ui::kle_svg::draw_layout(ui, &kle, max);
        }

        ui.add_space(12.0);

        // ── Layout ve Varyant ComboBox'ları yan yana ──────────────
        let available_variants: Vec<_> = self
            .variants
            .iter()
            .filter(|(layout, _, _)| layout == &state.keyboard_layout)
            .collect();

        let current_variant_name = if state.keyboard_variant.is_empty() {
            t!("keyboard_variant_default").to_string()
        } else {
            let vn = variant_display_name(&state.keyboard_layout, &state.keyboard_variant, &self.variants);
            if vn.is_empty() { state.keyboard_variant.clone() } else { vn }
        };
        let current_layout_name = layout_display_name(&state.keyboard_layout, &self.layouts);

        ui.horizontal(|ui| {
            ui.vertical(|ui| {
                ui.add_space(6.0);
                ui.label(egui::RichText::new(t!("keyboard_layout_label")).strong().color(theme::c_text()));
            });
            ui.add_space(8.0);
            let lw = ui.available_width().min(200.0);
            theme::show_combo_box(ui, "kbd_layout", current_layout_name.as_str(), lw, |ui, w| {
                for (code, display) in &self.layouts {
                    if theme::selectable_value(ui, &mut state.keyboard_layout, code.clone(), display.as_str(), w).clicked() {
                        if !self.variants.iter().any(|(layout, _, _)| layout == code) {
                            state.keyboard_variant.clear();
                        }
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }
                }
            });

            ui.add_space(16.0);

            ui.vertical(|ui| {
                ui.add_space(6.0);
                ui.label(egui::RichText::new(t!("keyboard_variant_label")).strong().color(theme::c_text()));
            });
            ui.add_space(8.0);
            let vw = ui.available_width().min(200.0);
            theme::show_combo_box(ui, "kbd_variant", current_variant_name.as_str(), vw, |ui, w| {
                let default_variant = String::new();
                if theme::selectable_value(ui, &mut state.keyboard_variant, default_variant, &t!("keyboard_variant_default"), w).clicked() {
                    apply_system_keyboard_layout(&state.keyboard_layout, "");
                }
                for (_, variant, display) in &available_variants {
                    if theme::selectable_value(ui, &mut state.keyboard_variant, variant.clone(), display.as_str(), w).clicked() {
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }
                }
            });
        });

        ui.add_space(12.0);
        ui.label(t!("keyboard_test_label"));
        ui.add_space(4.0);
        egui::Frame::group(ui.style())
            .fill(Color32::from_rgb(255, 255, 255))
            .rounding(6.0)
            .show(ui, |ui| {
                ui.add(
                    egui::TextEdit::singleline(&mut self.test_input)
                        .desired_width(ui.available_width())
                        .hint_text(t!("keyboard_test_hint"))
                        .frame(false),
                );
            });

        ui.add_space(8.0);
        ui.label(format!("{}: {}", t!("keyboard_selected"), {
            let layout_name = layout_display_name(&state.keyboard_layout, &self.layouts);
            if state.keyboard_variant.is_empty() {
                layout_name
            } else {
                let variant_name = variant_display_name(&state.keyboard_layout, &state.keyboard_variant, &self.variants);
                format!("{} ({})", layout_name, variant_name)
            }
        }));
    }

    fn is_complete(&self, state: &GlobalState) -> bool {
        !state.keyboard_layout.is_empty()
    }
}
