use ratatui::{
    buffer::Buffer,
    layout::Rect,
    style::{Color, Modifier, Style},
    widgets::{Block, Borders, Clear, Widget},
};

use crate::import::analyzer::{DateComponent, FieldKind};
use crate::import::wizard::{ImportWizard, WizardStep};

pub struct ImportWizardWidget<'a> {
    pub wizard: &'a ImportWizard,
}

impl<'a> ImportWizardWidget<'a> {
    pub fn new(wizard: &'a ImportWizard) -> Self {
        Self { wizard }
    }
}

impl<'a> Widget for ImportWizardWidget<'a> {
    fn render(self, area: Rect, buf: &mut Buffer) {
        let popup_w = area.width.min(80);
        let popup_h = area.height.min(30);
        let x = area.x + area.width.saturating_sub(popup_w) / 2;
        let y = area.y + area.height.saturating_sub(popup_h) / 2;
        let popup_area = Rect::new(x, y, popup_w, popup_h);

        Clear.render(popup_area, buf);

        let title = match self.wizard.step {
            WizardStep::Preview => " Import Wizard — Preview ",
            WizardStep::SelectArrayPath => " Import Wizard — Select Array ",
            WizardStep::ReviewProposals => " Import Wizard — Review Fields ",
            WizardStep::ConfigureDates => " Import Wizard — Date Components ",
            WizardStep::DefineFormulas => " Import Wizard — Formulas ",
            WizardStep::NameModel => " Import Wizard — Name Model ",
            WizardStep::Done => " Import Wizard — Done ",
        };

        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(Color::Magenta))
            .title(title);
        let inner = block.inner(popup_area);
        block.render(popup_area, buf);

        let mut y = inner.y;
        let x = inner.x;
        let w = inner.width as usize;

        match &self.wizard.step {
            WizardStep::Preview => {
                let summary = self.wizard.pipeline.preview_summary();
                buf.set_string(x, y, truncate(&summary, w), Style::default());
                y += 2;
                buf.set_string(
                    x,
                    y,
                    "Press Enter to continue\u{2026}",
                    Style::default().fg(Color::Yellow),
                );
            }
            WizardStep::SelectArrayPath => {
                buf.set_string(
                    x,
                    y,
                    "Select the path containing records:",
                    Style::default().fg(Color::Yellow),
                );
                y += 1;
                for (i, path) in self.wizard.pipeline.array_paths.iter().enumerate() {
                    if y >= inner.y + inner.height {
                        break;
                    }
                    let is_sel = i == self.wizard.cursor;
                    let style = if is_sel {
                        Style::default()
                            .fg(Color::Black)
                            .bg(Color::Magenta)
                            .add_modifier(Modifier::BOLD)
                    } else {
                        Style::default()
                    };
                    let label = format!("  {}", if path.is_empty() { "(root)" } else { path });
                    buf.set_string(x, y, truncate(&label, w), style);
                    y += 1;
                }
                y += 1;
                buf.set_string(
                    x,
                    y,
                    "\u{2191}\u{2193} select  Enter confirm",
                    Style::default().fg(Color::DarkGray),
                );
            }
            WizardStep::ReviewProposals => {
                buf.set_string(
                    x,
                    y,
                    "Review field proposals (Space toggle, c cycle kind):",
                    Style::default().fg(Color::Yellow),
                );
                y += 1;
                let header = format!("  {:<20} {:<22} {:<6}", "Field", "Kind", "Accept");
                buf.set_string(
                    x,
                    y,
                    truncate(&header, w),
                    Style::default()
                        .fg(Color::Gray)
                        .add_modifier(Modifier::UNDERLINED),
                );
                y += 1;

                for (i, proposal) in self.wizard.pipeline.proposals.iter().enumerate() {
                    if y >= inner.y + inner.height - 2 {
                        break;
                    }
                    let is_sel = i == self.wizard.cursor;

                    let kind_color = match proposal.kind {
                        FieldKind::Category => Color::Green,
                        FieldKind::Measure => Color::Cyan,
                        FieldKind::TimeCategory => Color::Magenta,
                        FieldKind::Label => Color::DarkGray,
                    };

                    let accept_str = if proposal.accepted {
                        "[\u{2713}]"
                    } else {
                        "[ ]"
                    };
                    let row = format!(
                        "  {:<20} {:<22} {}",
                        truncate(&proposal.field, 20),
                        truncate(proposal.kind_label(), 22),
                        accept_str
                    );

                    let style = if is_sel {
                        Style::default()
                            .fg(Color::Black)
                            .bg(Color::Cyan)
                            .add_modifier(Modifier::BOLD)
                    } else if proposal.accepted {
                        Style::default().fg(kind_color)
                    } else {
                        Style::default().fg(Color::DarkGray)
                    };

                    buf.set_string(x, y, truncate(&row, w), style);
                    y += 1;
                }
                let hint_y = inner.y + inner.height - 1;
                buf.set_string(
                    x,
                    hint_y,
                    "Enter: next  Space: toggle  c: cycle kind  Esc: cancel",
                    Style::default().fg(Color::DarkGray),
                );
            }
            WizardStep::ConfigureDates => {
                buf.set_string(
                    x,
                    y,
                    "Select date components to extract (Space toggle):",
                    Style::default().fg(Color::Yellow),
                );
                y += 1;

                let tc_proposals = self.wizard.time_category_proposals();
                let mut item_idx = 0;
                for proposal in &tc_proposals {
                    if y >= inner.y + inner.height - 2 {
                        break;
                    }
                    let fmt_str = proposal.date_format.as_deref().unwrap_or("?");
                    let header = format!("  {} (format: {})", proposal.field, fmt_str);
                    buf.set_string(
                        x,
                        y,
                        truncate(&header, w),
                        Style::default()
                            .fg(Color::Magenta)
                            .add_modifier(Modifier::BOLD),
                    );
                    y += 1;

                    for component in &[
                        DateComponent::Year,
                        DateComponent::Month,
                        DateComponent::Quarter,
                    ] {
                        if y >= inner.y + inner.height - 2 {
                            break;
                        }
                        let enabled = proposal.date_components.contains(component);
                        let check = if enabled { "[\u{2713}]" } else { "[ ]" };
                        let label = match component {
                            DateComponent::Year => "Year",
                            DateComponent::Month => "Month",
                            DateComponent::Quarter => "Quarter",
                        };
                        let row = format!("    {} {}", check, label);
                        let is_sel = item_idx == self.wizard.cursor;
                        let style = if is_sel {
                            Style::default()
                                .fg(Color::Black)
                                .bg(Color::Cyan)
                                .add_modifier(Modifier::BOLD)
                        } else if enabled {
                            Style::default().fg(Color::Green)
                        } else {
                            Style::default().fg(Color::DarkGray)
                        };
                        buf.set_string(x, y, truncate(&row, w), style);
                        y += 1;
                        item_idx += 1;
                    }
                }
                let hint_y = inner.y + inner.height - 1;
                buf.set_string(
                    x,
                    hint_y,
                    "Space: toggle  Enter: next  Esc: cancel",
                    Style::default().fg(Color::DarkGray),
                );
            }
            WizardStep::DefineFormulas => {
                buf.set_string(
                    x,
                    y,
                    "Define formulas (optional):",
                    Style::default().fg(Color::Yellow),
                );
                y += 1;

                // Show existing formulas
                if self.wizard.pipeline.formulas.is_empty() && !self.wizard.formula_editing {
                    buf.set_string(
                        x,
                        y,
                        "  (no formulas yet)",
                        Style::default().fg(Color::DarkGray),
                    );
                    y += 1;
                }
                for (i, formula) in self.wizard.pipeline.formulas.iter().enumerate() {
                    if y >= inner.y + inner.height - 5 {
                        break;
                    }
                    let is_sel = i == self.wizard.cursor && !self.wizard.formula_editing;
                    let style = if is_sel {
                        Style::default()
                            .fg(Color::Black)
                            .bg(Color::Cyan)
                            .add_modifier(Modifier::BOLD)
                    } else {
                        Style::default().fg(Color::Green)
                    };
                    buf.set_string(x, y, truncate(&format!("  {}", formula), w), style);
                    y += 1;
                }

                // Formula input area
                if self.wizard.formula_editing {
                    y += 1;
                    buf.set_string(
                        x,
                        y,
                        "Formula (e.g., Profit = Revenue - Cost):",
                        Style::default().fg(Color::Yellow),
                    );
                    y += 1;
                    let input = format!("> {}\u{2588}", self.wizard.formula_buffer);
                    buf.set_string(x, y, truncate(&input, w), Style::default().fg(Color::Green));
                    y += 1;
                }

                // Sample formulas
                let samples = self.wizard.sample_formulas();
                if !samples.is_empty() {
                    y += 1;
                    buf.set_string(x, y, "Examples:", Style::default().fg(Color::DarkGray));
                    y += 1;
                    for sample in &samples {
                        if y >= inner.y + inner.height - 1 {
                            break;
                        }
                        buf.set_string(
                            x,
                            y,
                            truncate(&format!("  {}", sample), w),
                            Style::default().fg(Color::DarkGray),
                        );
                        y += 1;
                    }
                }

                let hint_y = inner.y + inner.height - 1;
                let hint = if self.wizard.formula_editing {
                    "Enter: add  Esc: cancel"
                } else {
                    "n: new formula  d: delete  Enter: next  Esc: cancel"
                };
                buf.set_string(x, hint_y, hint, Style::default().fg(Color::DarkGray));
            }
            WizardStep::NameModel => {
                buf.set_string(x, y, "Model name:", Style::default().fg(Color::Yellow));
                y += 1;
                let name_str = format!("> {}\u{2588}", self.wizard.pipeline.model_name);
                buf.set_string(
                    x,
                    y,
                    truncate(&name_str, w),
                    Style::default().fg(Color::Green),
                );
                y += 2;
                buf.set_string(
                    x,
                    y,
                    "Enter to import, Esc to cancel",
                    Style::default().fg(Color::DarkGray),
                );

                if let Some(msg) = &self.wizard.message {
                    let msg_y = inner.y + inner.height - 1;
                    buf.set_string(x, msg_y, truncate(msg, w), Style::default().fg(Color::Red));
                }
            }
            WizardStep::Done => {
                buf.set_string(x, y, "Import complete!", Style::default().fg(Color::Green));
            }
        }
    }
}

fn truncate(s: &str, max: usize) -> String {
    if s.len() <= max {
        s.to_string()
    } else if max > 1 {
        format!("{}\u{2026}", &s[..max - 1])
    } else {
        s[..max].to_string()
    }
}
