use adw::prelude::*;
use outlay_core::db::Database;
use std::rc::Rc;

pub struct ForecastView {
    pub container: gtk::Box,
}

impl ForecastView {
    pub fn new(db: Rc<Database>) -> Self {
        let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
        let toast_overlay = adw::ToastOverlay::new();

        let clamp = adw::Clamp::new();
        clamp.set_maximum_size(700);
        clamp.set_margin_start(16);
        clamp.set_margin_end(16);

        let inner = gtk::Box::new(gtk::Orientation::Vertical, 20);
        inner.set_margin_top(20);
        inner.set_margin_bottom(20);

        let base_currency = db.get_setting("base_currency")
            .ok().flatten()
            .unwrap_or_else(|| "USD".to_string());

        let summary_card = gtk::Box::new(gtk::Orientation::Vertical, 4);
        summary_card.add_css_class("card");
        summary_card.set_margin_start(4);
        summary_card.set_margin_end(4);

        let summary_title = gtk::Label::new(Some("CASH FLOW FORECAST"));
        summary_title.add_css_class("caption");
        summary_title.add_css_class("dim-label");
        summary_title.set_halign(gtk::Align::Start);
        summary_title.set_margin_top(12);
        summary_title.set_margin_start(12);

        let summary_detail = gtk::Label::new(Some("Based on recurring transactions and 3-month averages"));
        summary_detail.add_css_class("caption");
        summary_detail.add_css_class("dim-label");
        summary_detail.set_halign(gtk::Align::Start);
        summary_detail.set_margin_start(12);
        summary_detail.set_margin_bottom(12);

        summary_card.append(&summary_title);
        summary_card.append(&summary_detail);

        let forecast_group = adw::PreferencesGroup::builder()
            .title("MONTHLY PROJECTION")
            .build();

        let forecast_data = db.forecast_cash_flow(6).unwrap_or_default();
        for (i, (month_key, income, expenses, balance)) in forecast_data.iter().enumerate() {
            let month_name = Self::month_name(month_key);
            let is_current = i == 0;
            let label = if is_current {
                format!("{} (current)", month_name)
            } else {
                format!("{} (projected)", month_name)
            };

            let net = income - expenses;
            let balance_str = if *balance >= 0.0 {
                format!("+{:.0} {}", balance, base_currency)
            } else {
                format!("{:.0} {}", balance, base_currency)
            };

            let row = adw::ActionRow::builder()
                .title(&label)
                .subtitle(&format!(
                    "Income: {:.0} - Expenses: {:.0} = Net: {:.0}",
                    income, expenses, net,
                ))
                .build();

            let balance_label = gtk::Label::new(Some(&balance_str));
            balance_label.add_css_class("amount-display");
            if *balance >= 0.0 {
                balance_label.add_css_class("amount-income");
            } else {
                balance_label.add_css_class("amount-expense");
            }
            row.add_suffix(&balance_label);

            if !is_current {
                row.add_css_class("dim-label");
            }

            forecast_group.add(&row);
        }

        if forecast_data.is_empty() {
            let row = adw::ActionRow::builder()
                .title("No data available for forecast")
                .subtitle("Add some transactions to see projections")
                .build();
            row.add_css_class("dim-label");
            forecast_group.add(&row);
        }

        // Net cash flow summary
        if forecast_data.len() >= 2 {
            let last = &forecast_data[forecast_data.len() - 1];
            let net_summary = if last.3 >= 0.0 {
                format!("Projected cumulative balance in 6 months: +{:.0} {}", last.3, base_currency)
            } else {
                format!("Projected cumulative balance in 6 months: {:.0} {}", last.3, base_currency)
            };

            let net_label = gtk::Label::new(Some(&net_summary));
            net_label.add_css_class("heading");
            net_label.set_halign(gtk::Align::Start);
            net_label.set_margin_start(4);
            net_label.set_margin_top(8);

            inner.append(&summary_card);
            inner.append(&forecast_group);
            inner.append(&net_label);
        } else {
            inner.append(&summary_card);
            inner.append(&forecast_group);
        }

        clamp.set_child(Some(&inner));

        let scroll = gtk::ScrolledWindow::builder()
            .hscrollbar_policy(gtk::PolicyType::Never)
            .vexpand(true)
            .child(&clamp)
            .build();

        toast_overlay.set_child(Some(&scroll));
        container.append(&toast_overlay);

        ForecastView { container }
    }

    fn month_name(key: &str) -> String {
        let parts: Vec<&str> = key.split('-').collect();
        if parts.len() != 2 { return key.to_string(); }
        let month: u32 = parts[1].parse().unwrap_or(0);
        let year = parts[0];
        let name = match month {
            1 => "January", 2 => "February", 3 => "March",
            4 => "April", 5 => "May", 6 => "June",
            7 => "July", 8 => "August", 9 => "September",
            10 => "October", 11 => "November", 12 => "December",
            _ => "Unknown",
        };
        format!("{} {}", name, year)
    }
}
