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,
    layout_filter: String,
    variant_filter: 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()),
        ("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()),
    ]
}

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(),
            layout_filter: String::new(),
            variant_filter: 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) {
        ui.heading(t!("keyboard_title"));
        ui.label(t!("keyboard_description"));

        ui.add_space(12.0);

        let available_variants: Vec<_> = self
            .variants
            .iter()
            .filter(|(layout, _, _)| layout == &state.keyboard_layout)
            .collect();

        ui.columns(2, |cols| {
            cols[0].vertical(|ui| {
                egui::Frame::group(ui.style())
                    .fill(theme::c_bg_widget())
                    .stroke(egui::Stroke::new(1.0, egui::Color32::from_gray(200)))
                    .rounding(egui::Rounding::same(8.0))
                    .inner_margin(egui::Margin::same(8.0))
                    .show(ui, |ui| {
                        ui.label(t!("keyboard_layout_label"));
                        ui.add(
                            egui::TextEdit::singleline(&mut self.layout_filter)
                                .hint_text(t!("keyboard_layout_search_hint")),
                        );
                        ui.add_space(4.0);

                        egui::ScrollArea::vertical()
                            .id_source("kbd_layout_scroll")
                            .auto_shrink([false, false])
                            .max_height(240.0)
                            .show(ui, |ui| {
                                let filter = self.layout_filter.to_lowercase();
                                let filtered_layouts: Vec<_> = self.layouts.iter()
                                    .filter(|(code, display)| {
                                        filter.is_empty()
                                            || code.to_lowercase().contains(&filter)
                                            || display.to_lowercase().contains(&filter)
                                    })
                                    .collect();

                                if filtered_layouts.is_empty() {
                                    ui.label(t!("keyboard_layout_search_no_match"));
                                }
                                for (code, display) in filtered_layouts {
                                    let is_selected = state.keyboard_layout == *code;
                                    if ui.selectable_label(is_selected, display).clicked() {
                                        state.keyboard_layout = code.to_string();
                                        self.variant_filter.clear();
                                        if !self.variants.iter().any(|(layout, _, _)| layout == code) {
                                            state.keyboard_variant.clear();
                                        }
                                        apply_system_keyboard_layout(&state.keyboard_layout, &state.keyboard_variant);
                                    }
                                }
                            });
                    });
            });

            cols[1].vertical(|ui| {
                egui::Frame::group(ui.style())
                    .fill(theme::c_bg_widget())
                    .stroke(egui::Stroke::new(1.0, egui::Color32::from_gray(200)))
                    .rounding(egui::Rounding::same(8.0))
                    .inner_margin(egui::Margin::same(8.0))
                    .show(ui, |ui| {
                        ui.label(t!("keyboard_variant_label"));
                        ui.add(
                            egui::TextEdit::singleline(&mut self.variant_filter)
                                .hint_text(t!("keyboard_variant_search_hint")),
                        );
                        ui.add_space(4.0);

                        egui::ScrollArea::vertical()
                            .id_source("kbd_variant_scroll")
                            .auto_shrink([false, false])
                            .max_height(240.0)
                            .show(ui, |ui| {
                                let variant_filter = self.variant_filter.to_lowercase();
                                let filtered_variants: Vec<_> = available_variants
                                    .into_iter()
                                    .filter(|(_, variant, display)| {
                                        variant_filter.is_empty()
                                            || variant.to_lowercase().contains(&variant_filter)
                                            || display.to_lowercase().contains(&variant_filter)
                                    })
                                    .collect();

                                let mut selected_default = state.keyboard_variant.is_empty();
                                if ui.selectable_value(&mut selected_default, true, t!("keyboard_variant_default")).clicked() {
                                    state.keyboard_variant.clear();
                                    apply_system_keyboard_layout(&state.keyboard_layout, "");
                                }
                                if filtered_variants.is_empty() {
                                    ui.label(t!("keyboard_variant_search_no_match"));
                                }
                                for (_, variant, display) in filtered_variants {
                                    let is_selected = state.keyboard_variant == *variant;
                                    if ui.selectable_label(is_selected, display).clicked() {
                                        state.keyboard_variant = variant.to_string();
                                        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);
        ui.add(
            egui::TextEdit::multiline(&mut self.test_input)
                .desired_rows(5)
                .desired_width(ui.available_width())
                .hint_text(t!("keyboard_test_hint")),
        );

        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()
    }
}
