use crate::components::keyboard;
use iced::widget::text::Shaping;
use iced::widget::{column, container, row, scrollable, text};
use iced::{Background, Color, Element, Length, Theme};

use bds_core::i18n::UiLocale;

use crate::app::Message;
use crate::components::inputs;
use crate::i18n::t;

#[derive(Debug, Clone, Default)]
pub struct SiteValidationState {
    pub has_run: bool,
    pub is_running: bool,
    pub is_applying: bool,
    pub missing_files: Vec<String>,
    pub extra_files: Vec<String>,
    pub stale_files: Vec<String>,
    pub error_message: Option<String>,
}

pub fn view<'a>(state: &'a SiteValidationState, locale: UiLocale) -> Element<'a, Message> {
    let run_button = if state.is_running {
        keyboard::button(
            text(t(locale, "siteValidation.running"))
                .size(13)
                .shaping(Shaping::Advanced),
        )
        .style(inputs::primary_button)
        .padding([6, 16])
    } else {
        keyboard::button(
            text(t(locale, "siteValidation.run"))
                .size(13)
                .shaping(Shaping::Advanced),
        )
        .on_press(Message::RunSiteValidation)
        .hotkey('r')
        .style(inputs::primary_button)
        .padding([6, 16])
    };
    let has_issues = !state.missing_files.is_empty()
        || !state.extra_files.is_empty()
        || !state.stale_files.is_empty();
    let apply_button = if state.is_applying {
        keyboard::button(
            text(t(locale, "siteValidation.applying"))
                .size(13)
                .shaping(Shaping::Advanced),
        )
        .style(inputs::secondary_button)
        .padding([6, 16])
    } else if !state.is_running && state.error_message.is_none() && has_issues {
        keyboard::button(
            text(t(locale, "siteValidation.apply"))
                .size(13)
                .shaping(Shaping::Advanced),
        )
        .on_press(Message::ApplySiteValidation)
        .hotkey('a')
        .style(inputs::primary_button)
        .padding([6, 16])
    } else {
        keyboard::button(
            text(t(locale, "siteValidation.apply"))
                .size(13)
                .shaping(Shaping::Advanced),
        )
        .style(inputs::secondary_button)
        .padding([6, 16])
    };

    let mut content = column![
        row![
            text(t(locale, "tabBar.siteValidation"))
                .size(24)
                .shaping(Shaping::Advanced)
                .color(Color::from_rgb(0.88, 0.88, 0.92)),
            row![run_button, apply_button].spacing(12),
        ]
        .spacing(16),
    ]
    .spacing(16);

    if state.is_running {
        content = content.push(help_text(t(locale, "siteValidation.running")));
    } else if let Some(error) = &state.error_message {
        content = content.push(section(
            t(locale, "siteValidation.error"),
            std::slice::from_ref(error),
            Color::from_rgb(0.75, 0.28, 0.28),
        ));
    } else if !state.has_run {
        content = content.push(help_text(t(locale, "siteValidation.idle")));
    } else if state.missing_files.is_empty()
        && state.extra_files.is_empty()
        && state.stale_files.is_empty()
    {
        content = content.push(help_text(t(locale, "siteValidation.clean")));
    } else {
        if !state.missing_files.is_empty() {
            content = content.push(section(
                format!(
                    "{} ({})",
                    t(locale, "siteValidation.missing"),
                    state.missing_files.len()
                ),
                &state.missing_files,
                Color::from_rgb(0.70, 0.25, 0.25),
            ));
        }
        if !state.extra_files.is_empty() {
            content = content.push(section(
                format!(
                    "{} ({})",
                    t(locale, "siteValidation.extra"),
                    state.extra_files.len()
                ),
                &state.extra_files,
                Color::from_rgb(0.68, 0.48, 0.18),
            ));
        }
        if !state.stale_files.is_empty() {
            content = content.push(section(
                format!(
                    "{} ({})",
                    t(locale, "siteValidation.stale"),
                    state.stale_files.len()
                ),
                &state.stale_files,
                Color::from_rgb(0.62, 0.32, 0.18),
            ));
        }
    }

    container(
        scrollable(content)
            .direction(scrollable::Direction::Vertical(inputs::compact_scrollbar()))
            .style(inputs::scrollable_style),
    )
    .width(Length::Fill)
    .height(Length::Fill)
    .padding(24)
    .style(|_theme: &Theme| container::Style {
        background: Some(Background::Color(inputs::APP_BG)),
        ..container::Style::default()
    })
    .into()
}

fn help_text<'a>(value: String) -> Element<'a, Message> {
    inputs::card(
        text(value)
            .size(14)
            .shaping(Shaping::Advanced)
            .color(Color::from_rgb(0.66, 0.66, 0.72)),
    )
    .into()
}

fn section<'a>(title: String, entries: &'a [String], accent: Color) -> Element<'a, Message> {
    let items = entries.iter().fold(column!().spacing(6), |column, entry| {
        column.push(
            text(entry)
                .size(13)
                .shaping(Shaping::Advanced)
                .color(Color::from_rgb(0.82, 0.82, 0.88)),
        )
    });

    inputs::card(
        column![
            text(title.to_string())
                .size(16)
                .shaping(Shaping::Advanced)
                .color(accent),
            items,
        ]
        .spacing(10),
    )
    .into()
}
