//! Anti-list error modal — shown when user tries to open a rejected format.
//!
//! Rendered as a full-screen overlay with a semi-transparent backdrop and a
//! centered card containing the error details and alternatives.

use iced::widget::{button, column, container, row, text};
use iced::{Element, Length};

use super::icons::Icon;
use super::theme;
use crate::codec::DecodeError;

#[derive(Debug, Clone, Default)]
pub struct ErrorModal {
    pub visible: bool,
    pub error: Option<DecodeError>,
}

impl ErrorModal {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn show(&mut self, error: DecodeError) {
        self.error = Some(error);
        self.visible = true;
    }

    pub fn dismiss(&mut self) {
        self.visible = false;
        self.error = None;
    }

    pub fn view(&self) -> Option<Element<'_, ()>> {
        if !self.visible {
            return None;
        }

        let error = self.error.as_ref()?;

        let (title, body_lines): (String, Vec<String>) = match error {
            DecodeError::AntiListed {
                path,
                format_name,
                reason,
                alternative,
            } => {
                let filename = path
                    .file_name()
                    .map(|s| s.to_string_lossy().to_string())
                    .unwrap_or_else(|| path.display().to_string());
                (
                    format!("{} is not supported", format_name),
                    vec![
                        format!("File: {}", filename),
                        String::new(),
                        format!("This format is on the project's anti-list."),
                        String::new(),
                        format!("Reason: {}", reason),
                        String::new(),
                        format!("What to use instead:"),
                        format!("  {}", alternative),
                    ],
                )
            }
            DecodeError::Unsupported { path, extension } => {
                let filename = path
                    .file_name()
                    .map(|s| s.to_string_lossy().to_string())
                    .unwrap_or_else(|| path.display().to_string());
                (
                    format!(".{} files are not supported", extension),
                    vec![
                        format!("File: {}", filename),
                        String::new(),
                        format!("This format is not in our supported list."),
                        format!(""),
                        format!("Supported: PNG, JPEG, GIF, WebP, AVIF, BMP, ICO"),
                    ],
                )
            }
            DecodeError::Io(msg) => (
                "Could not read file".to_string(),
                vec![msg.clone()],
            ),
            DecodeError::Decode(msg) => (
                "Could not decode image".to_string(),
                vec![msg.clone()],
            ),
        };

        let is_anti_listed = matches!(error, DecodeError::AntiListed { .. });

        let title_color = if is_anti_listed {
            theme::DANGER
        } else {
            theme::ACCENT
        };

        let title_row = row![
            Icon::Error.widget(20.0, &theme::danger_hex()),
            text(title)
                .color(title_color)
                .size(16),
        ]
        .align_y(iced::Alignment::Center)
        .spacing(10.0);

        let body_texts: Vec<Element<'_, ()>> = body_lines
            .iter()
            .map(|line| {
                if line.is_empty() {
                    text("").height(Length::Fixed(8.0)).into()
                } else {
                    text(line.clone())
                        .color(if line.starts_with("  ") {
                            theme::TEXT_PRIMARY
                        } else {
                            theme::TEXT_SECONDARY
                        })
                        .size(13)
                        .into()
                }
            })
            .collect();

        let body = column(body_texts).spacing(2.0);

        let close_btn = button(
            row![
                Icon::Close.widget(14.0, &theme::text_primary_hex()),
                text("Close").color(theme::TEXT_PRIMARY).size(12),
            ]
            .align_y(iced::Alignment::Center)
            .spacing(6.0),
        )
        .on_press(())
        .padding(iced::Padding {
            top: 6.0,
            right: 16.0,
            bottom: 6.0,
            left: 16.0,
        })
        .style(|_theme, status| {
            let bg = match status {
                button::Status::Hovered => Some(theme::BG_CHROME_HOVER),
                button::Status::Pressed => Some(theme::ACCENT_DIM),
                _ => None,
            };
            button::Style {
                background: bg.map(iced::Background::Color),
                border: iced::Border {
                    color: theme::BG_CHROME_BORDER,
                    width: 1.0,
                    radius: 4.0.into(),
                },
                ..Default::default()
            }
        });

        let card = column![
            title_row,
            text("").height(Length::Fixed(12.0)),
            body,
            text("").height(Length::Fixed(16.0)),
            container(close_btn).align_x(iced::Alignment::Center),
        ]
        .padding(iced::Padding {
            top: 20.0,
            right: 24.0,
            bottom: 20.0,
            left: 24.0,
        });

        let card_container = container(card)
            .max_width(460.0)
            .style(|_| container::Style {
                background: Some(theme::BG_CHROME.into()),
                border: iced::Border {
                    color: theme::BG_CHROME_BORDER,
                    width: 1.0,
                    radius: 8.0.into(),
                },
                shadow: iced::Shadow {
                    color: iced::Color::from_rgba(0.0, 0.0, 0.0, 0.7),
                    offset: iced::Vector::new(0.0, 8.0),
                    blur_radius: 32.0,
                },
                ..Default::default()
            });

        // Center the card in the full-screen overlay.
        let centered = container(card_container)
            .width(Length::Fill)
            .height(Length::Fill)
            .align_x(iced::Alignment::Center)
            .align_y(iced::Alignment::Center)
            .style(|_| container::Style {
                background: Some(
                    iced::Color::from_rgba(0.0, 0.0, 0.0, 0.75).into(),
                ),
                ..Default::default()
            });

        Some(centered.into())
    }
}
