//! Single-line text input modal with optional hint.

use crate::theme;
use ratatui::layout::{Constraint, Layout, Rect};
use ratatui::style::{Color, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use ratatui::Frame;

use super::ModalFrame;

/// Modal dialog with a single-line text input.
pub struct TextInputModal<'a> {
    title: &'a str,
    input: &'a str,
    hint: Option<&'a str>,
    border_color: Option<Color>,
    width: u16,
}

impl<'a> TextInputModal<'a> {
    pub fn new(title: &'a str, input: &'a str) -> Self {
        Self {
            title,
            input,
            hint: None,
            border_color: None,
            width: 50,
        }
    }

    pub fn hint(mut self, h: &'a str) -> Self {
        self.hint = Some(h);
        self
    }

    pub fn border_color(mut self, c: Color) -> Self {
        self.border_color = Some(c);
        self
    }

    pub fn width(mut self, w: u16) -> Self {
        self.width = w;
        self
    }

    pub fn render_centered(self, frame: &mut Frame, term: Rect) -> Rect {
        let colors = theme::get();
        let border_color = self.border_color.unwrap_or(colors.ui.text_primary);
        let height = if self.hint.is_some() { 6 } else { 5 };

        let inner = ModalFrame::new(self.title)
            .width(self.width)
            .height(height)
            .border_color(border_color)
            .render_centered(frame, term);

        if self.hint.is_some() {
            let rows =
                Layout::vertical([Constraint::Length(1), Constraint::Length(1)]).split(inner);

            frame.render_widget(
                Paragraph::new(Line::from(vec![
                    Span::raw("> "),
                    Span::styled(self.input, Style::new().fg(colors.input.text)),
                    Span::styled("█", Style::new().fg(colors.input.cursor)),
                ])),
                rows[0],
            );

            if let Some(hint) = self.hint {
                frame.render_widget(
                    Paragraph::new(Span::styled(hint, Style::new().fg(colors.input.hint))),
                    rows[1],
                );
            }
        } else {
            frame.render_widget(
                Paragraph::new(Line::from(vec![
                    Span::raw("> "),
                    Span::styled(self.input, Style::new().fg(colors.input.text)),
                    Span::styled("█", Style::new().fg(colors.input.cursor)),
                ])),
                inner,
            );
        }

        inner
    }
}
