use ratatui::{
    Frame,
    layout::{Alignment, Constraint, Direction, Layout},
    style::{Color, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Clear, Paragraph, Wrap},
};

use crate::core::Result;
use crate::core::store::Store;

/// The vault initialization screen state.
pub struct InitScreen {
    /// Current phase: confirm -> enter_password -> confirm_password
    pub phase: InitPhase,
    /// The new password being entered.
    pub password: String,
    /// The password confirmation being entered.
    pub confirm: String,
    /// An optional error message to display.
    pub error: Option<String>,
}

/// The current phase of the vault initialization flow.
pub enum InitPhase {
    /// Ask user y/n whether to create a vault
    Confirm,
    /// User is typing the new password
    EnterPassword,
    /// User is confirming the password
    ConfirmPassword,
}

impl InitScreen {
    /// Creates a new InitScreen starting at the Confirm phase.
    pub fn new() -> Self {
        Self {
            phase: InitPhase::Confirm,
            password: String::new(),
            confirm: String::new(),
            error: None,
        }
    }

    /// Handles character input for the current init phase.
    /// Returns Ok(Some(true)) when init completes, Ok(Some(false)) when declined,
    /// and Ok(None) to continue the current phase.
    pub fn handle_input(&mut self, c: char, store: &Store) -> Result<Option<bool>> {
        match self.phase {
            InitPhase::Confirm => match c {
                'y' | 'Y' => {
                    self.phase = InitPhase::EnterPassword;
                    self.error = None;
                    Ok(None)
                }
                'n' | 'N' => Ok(Some(false)), // user declined
                _ => Ok(None),
            },
            InitPhase::EnterPassword => {
                if c == '\n' {
                    if self.password.len() < 4 {
                        self.error = Some("Password too short (min 4 chars).".to_string());
                        self.password.clear();
                    } else {
                        self.phase = InitPhase::ConfirmPassword;
                        self.error = None;
                    }
                } else {
                    self.password.push(c);
                }
                Ok(None)
            }
            InitPhase::ConfirmPassword => {
                if c == '\n' {
                    if self.password != self.confirm {
                        self.error = Some("Passwords don't match. Try again.".to_string());
                        self.password.clear();
                        self.confirm.clear();
                        self.phase = InitPhase::EnterPassword;
                    } else {
                        store.init(&self.password)?;
                        return Ok(Some(true)); // init complete
                    }
                } else {
                    self.confirm.push(c);
                }
                Ok(None)
            }
        }
    }

    /// Removes the last character from the current input buffer.
    pub fn handle_backspace(&mut self) {
        match self.phase {
            InitPhase::EnterPassword => {
                self.password.pop();
            }
            InitPhase::ConfirmPassword => {
                self.confirm.pop();
            }
            _ => {}
        }
    }
}

/// Draws the init screen with a centered vault setup dialog.
pub fn draw(frame: &mut Frame, screen: &InitScreen) {
    let area = frame.area();

    let popup_area = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Percentage(35),
            Constraint::Length(10),
            Constraint::Percentage(35),
        ])
        .split(area)[1];

    let popup = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Percentage(25),
            Constraint::Percentage(50),
            Constraint::Percentage(25),
        ])
        .split(popup_area)[1];

    frame.render_widget(Clear, popup);

    let text = match screen.phase {
        InitPhase::Confirm => {
            if screen.error.is_some() {
                screen.error.as_deref().unwrap_or("").to_string()
            } else {
                "Welcome to Closure.\n\nNo vault found.\n\nCreate one? (y/n)".to_string()
            }
        }
        InitPhase::EnterPassword => {
            let masked: String = screen.password.chars().map(|_| '*').collect();
            let mut t = format!("Set vault password:\n{}", masked);
            if let Some(ref err) = screen.error {
                t.push_str(&format!("\n\n{}", err));
            }
            t
        }
        InitPhase::ConfirmPassword => {
            let masked: String = screen.confirm.chars().map(|_| '*').collect();
            let mut t = format!("Confirm password:\n{}", masked);
            if let Some(ref err) = screen.error {
                t.push_str(&format!("\n\n{}", err));
            }
            t
        }
    };

    let paragraph = Paragraph::new(text)
        .block(
            Block::default()
                .title("Closure - Vault Setup")
                .borders(Borders::ALL),
        )
        .alignment(Alignment::Left)
        .wrap(Wrap { trim: true });

    frame.render_widget(paragraph, popup);

    // Footer
    let footer_text = Line::from(Span::styled(
        " Rhodes Island Eng. v0.2  |  Esc to quit",
        Style::default().fg(Color::DarkGray),
    ));
    let footer_area = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Min(0), Constraint::Length(1)])
        .split(area)[1];
    frame.render_widget(footer_text, footer_area);
}
