use eframe::egui;
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) {
        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 ────────────────────────────────────
        let kle = crate::ui::kle_svg::compile_layout(&state.keyboard_layout, &state.keyboard_variant)
            .unwrap_or_else(|| crate::ui::kle_svg::empty_layout());
        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);

        // ── Label genişlik hesaplama ──────────────────────────
        let layout_label = t!("keyboard_layout_label").to_string();
        let variant_label = t!("keyboard_variant_label").to_string();
        let label_w = ui.fonts(|f| {
            let measure = |s: &str| -> f32 {
                f.layout_no_wrap(s.to_string(), egui::FontId::proportional(14.0), egui::Color32::WHITE)
                    .size().x
            };
            measure(&layout_label).max(measure(&variant_label)).ceil()
        }) + 16.0;

        // ── Düzen (Layout) ────────────────────────────────────
        ui.horizontal(|ui| {
            ui.add_space(6.0);
            ui.allocate_ui_with_layout(
                egui::Vec2::new(label_w, ui.available_height()),
                egui::Layout::left_to_right(egui::Align::Center),
                |ui| {
                    ui.label(egui::RichText::new(&layout_label).strong().color(theme::c_text()));
                },
            );
            ui.add_space(8.0);
            
            let lw = ui.available_width();
            let current_layout = layout_display_name(&state.keyboard_layout, &self.layouts);
            
            theme::show_combo_box(ui, "kbd_layout", &current_layout, lw, |ui, w| {
                let mut pressed_char = None;
                ui.input(|i| {
                    for event in &i.events {
                        if let egui::Event::Text(text) = event {
                            pressed_char = Some(text.to_lowercase());
                        }
                    }
                });

                for (code, display) in &self.layouts {
                    let is_selected = state.keyboard_layout == *code;
                    let is_target = if let Some(ref c) = pressed_char {
                        display.to_lowercase().starts_with(c)
                    } else {
                        false
                    };

                    if is_target {
                        state.keyboard_layout = code.clone();
                        if !self.variants.iter().any(|(layout, _, _)| layout == code) {
                            state.keyboard_variant.clear();
                        }
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }

                    let response = theme::selectable_value(ui, &mut state.keyboard_layout, code.clone(), display.as_str(), w);
                    
                    if response.clicked() {
                        if !self.variants.iter().any(|(layout, _, _)| layout == code) {
                            state.keyboard_variant.clear();
                        }
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }

                    if is_target || (is_selected && pressed_char.is_none()) {
                        response.scroll_to_me(None);
                    }
                }
            });
        });

        ui.add_space(8.0);

        // ── Varyant ───────────────────────────────────────────
        ui.horizontal(|ui| {
            ui.add_space(6.0);
            ui.allocate_ui_with_layout(
                egui::Vec2::new(label_w, ui.available_height()),
                egui::Layout::left_to_right(egui::Align::Center),
                |ui| {
                    ui.label(egui::RichText::new(&variant_label).strong().color(theme::c_text()));
                },
            );
            ui.add_space(8.0);
            
            let vw = ui.available_width();
            let available_variants: Vec<(String, String)> = self
                .variants
                .iter()
                .filter(|(layout, _, _)| layout == &state.keyboard_layout)
                .map(|(_, v_code, display)| (v_code.clone(), display.clone()))
                .collect();
                
            let current_variant = 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 default_label = t!("keyboard_variant_default").to_string();
            
            theme::show_combo_box(ui, "kbd_variant", &current_variant, vw, |ui, w| {
                let mut pressed_char = None;
                ui.input(|i| {
                    for event in &i.events {
                        if let egui::Event::Text(text) = event {
                            pressed_char = Some(text.to_lowercase());
                        }
                    }
                });

                // Varsayılan Varyant Elemanı
                let is_default_selected = state.keyboard_variant.is_empty();
                let is_default_target = if let Some(ref c) = pressed_char {
                    default_label.to_lowercase().starts_with(c)
                } else {
                    false
                };

                if is_default_target {
                    state.keyboard_variant.clear();
                    apply_system_keyboard_layout(&state.keyboard_layout, "");
                }

                let def_response = theme::selectable_value(ui, &mut state.keyboard_variant, String::new(), &default_label, w);
                if def_response.clicked() {
                    apply_system_keyboard_layout(&state.keyboard_layout, "");
                }

                if is_default_target || (is_default_selected && pressed_char.is_none()) {
                    def_response.scroll_to_me(None);
                }

                // Diğer Varyantlar
                for (v_code, display) in &available_variants {
                    let is_selected = state.keyboard_variant == *v_code;
                    let is_target = if let Some(ref c) = pressed_char {
                        display.to_lowercase().starts_with(c)
                    } else {
                        false
                    };

                    if is_target {
                        state.keyboard_variant = v_code.clone();
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }

                    let response = theme::selectable_value(ui, &mut state.keyboard_variant, v_code.clone(), display.as_str(), w);
                    if response.clicked() {
                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                    }

                    if is_target || (is_selected && pressed_char.is_none()) {
                        response.scroll_to_me(None);
                    }
                }
            });
        });

        ui.add_space(12.0);
        ui.label(t!("keyboard_test_label"));
        ui.add_space(4.0);
        egui::Frame::group(ui.style())
            .fill(theme::c_keyboard_bg())
            .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()
    }
}