//! GUI mode — iced 0.12 desktop application.
//!
//! Two-column layout with 6 calculator panels.

use crate::calc::*;
use iced::widget::{button, column, container, row, text, text_input, scrollable};
use iced::{
    alignment, Application, Command, Element, Length, Settings, Theme,
};

// ══════════════════════════════════════════════════════════════════════
//  Per-calculator state
// ══════════════════════════════════════════════════════════════════════

struct OhmState {
    p_in: String, i_in: String, r_in: String, v_in: String,
    p_out: String, i_out: String, r_out: String, v_out: String,
}

struct MarginState {
    cost_in: String, sell_in: String,
    profit_out: String, margin_pct_out: String, markup_pct_out: String,
}

struct RoiState {
    investment_in: String, revenue_in: String,
    profit_out: String, roi_pct_out: String,
}

struct TokenState {
    model: AiModel,
    input_tok_in: String, output_tok_in: String,
    input_cost_out: String, output_cost_out: String, total_cost_out: String,
}

struct ElecState {
    power_in: String, hours_in: String, days_in: String, rate_in: String,
    daily_kwh_out: String, monthly_kwh_out: String,
    monthly_cost_out: String, yearly_cost_out: String,
}

struct BeState {
    fixed_in: String, price_in: String, variable_in: String,
    units_out: String, revenue_out: String,
}

// ══════════════════════════════════════════════════════════════════════
//  Main application state
// ══════════════════════════════════════════════════════════════════════

struct App {
    ohm:    OhmState,
    margin: MarginState,
    roi:    RoiState,
    token:  TokenState,
    elec:   ElecState,
    be:     BeState,
}

// ══════════════════════════════════════════════════════════════════════
//  Messages
// ══════════════════════════════════════════════════════════════════════

#[derive(Debug, Clone)]
enum Message {
    OhmPower(String), OhmCurrent(String), OhmResistance(String), OhmVoltage(String),
    MarginCost(String), MarginSell(String),
    RoiInvestment(String), RoiRevenue(String),
    TokenPrev, TokenNext, TokenInputTok(String), TokenOutputTok(String),
    ElecPower(String), ElecHours(String), ElecDays(String), ElecRate(String),
    BeFixed(String), BePrice(String), BeVariable(String),
}

// ══════════════════════════════════════════════════════════════════════
//  Application
// ══════════════════════════════════════════════════════════════════════

pub fn run() -> iced::Result {
    App::run(Settings::default())
}

impl Application for App {
    type Executor = iced::executor::Default;
    type Message  = Message;
    type Theme    = Theme;
    type Flags    = ();

    fn new(_: Self::Flags) -> (Self, Command<Self::Message>) {
        (
            Self {
                ohm: OhmState {
                    p_in: String::new(), i_in: String::new(),
                    r_in: String::new(), v_in: String::new(),
                    p_out: "0 Watts(W)".into(), i_out: "0 Amps(A)".into(),
                    r_out: "0 Ohms(\u{03A9})".into(), v_out: "0 Volts(V)".into(),
                },
                margin: MarginState {
                    cost_in: String::new(), sell_in: String::new(),
                    profit_out: "0".into(), margin_pct_out: "0 %".into(),
                    markup_pct_out: "0 %".into(),
                },
                roi: RoiState {
                    investment_in: String::new(), revenue_in: String::new(),
                    profit_out: "0".into(), roi_pct_out: "0 %".into(),
                },
                token: TokenState {
                    model: AiModel::Gpt4o,
                    input_tok_in: String::new(), output_tok_in: String::new(),
                    input_cost_out: "$0.00".into(), output_cost_out: "$0.00".into(),
                    total_cost_out: "$0.00".into(),
                },
                elec: ElecState {
                    power_in: String::new(), hours_in: String::new(),
                    days_in: String::new(), rate_in: String::new(),
                    daily_kwh_out: "0 kWh".into(), monthly_kwh_out: "0 kWh".into(),
                    monthly_cost_out: "$0.00".into(), yearly_cost_out: "$0.00".into(),
                },
                be: BeState {
                    fixed_in: String::new(), price_in: String::new(),
                    variable_in: String::new(),
                    units_out: "0".into(), revenue_out: "$0.00".into(),
                },
            },
            Command::none(),
        )
    }

    fn title(&self) -> String { "MCP-Relational-Data".into() }

    fn update(&mut self, msg: Self::Message) -> Command<Self::Message> {
        match msg {
            Message::OhmPower(s)      => { self.ohm.p_in = s; self.ohm.recalculate(); }
            Message::OhmCurrent(s)    => { self.ohm.i_in = s; self.ohm.recalculate(); }
            Message::OhmResistance(s) => { self.ohm.r_in = s; self.ohm.recalculate(); }
            Message::OhmVoltage(s)    => { self.ohm.v_in = s; self.ohm.recalculate(); }
            Message::MarginCost(s) => { self.margin.cost_in = s; self.margin.recalculate(); }
            Message::MarginSell(s) => { self.margin.sell_in = s; self.margin.recalculate(); }
            Message::RoiInvestment(s) => { self.roi.investment_in = s; self.roi.recalculate(); }
            Message::RoiRevenue(s)    => { self.roi.revenue_in = s; self.roi.recalculate(); }
            Message::TokenPrev         => { self.token.model = next_model(self.token.model); self.token.recalculate(); }
            Message::TokenNext         => { self.token.model = next_model(self.token.model); self.token.recalculate(); }
            Message::TokenInputTok(s)  => { self.token.input_tok_in = s; self.token.recalculate(); }
            Message::TokenOutputTok(s) => { self.token.output_tok_in = s; self.token.recalculate(); }
            Message::ElecPower(s) => { self.elec.power_in = s; self.elec.recalculate(); }
            Message::ElecHours(s) => { self.elec.hours_in = s; self.elec.recalculate(); }
            Message::ElecDays(s)  => { self.elec.days_in = s; self.elec.recalculate(); }
            Message::ElecRate(s)  => { self.elec.rate_in = s; self.elec.recalculate(); }
            Message::BeFixed(s)    => { self.be.fixed_in = s; self.be.recalculate(); }
            Message::BePrice(s)    => { self.be.price_in = s; self.be.recalculate(); }
            Message::BeVariable(s) => { self.be.variable_in = s; self.be.recalculate(); }
        }
        Command::none()
    }

    fn view(&self) -> Element<Self::Message> {
        let left = column![
            ohm_section(&self.ohm),
            elec_section(&self.elec),
        ]
        .spacing(16);

        let right = column![
            margin_section(&self.margin),
            roi_section(&self.roi),
            token_section(&self.token),
            be_section(&self.be),
        ]
        .spacing(16);

        let body = row![left, right]
            .spacing(16)
            .padding(16);

        container(scrollable(body).height(Length::Fill))
            .width(Length::Fill)
            .height(Length::Fill)
            .padding([8, 16])
            .into()
    }
}

// ══════════════════════════════════════════════════════════════════════
//  Section views
// ══════════════════════════════════════════════════════════════════════

fn ohm_section<'a>(s: &'a OhmState) -> Element<'a, Message> {
    container(
        column![
            text("Ohm's Law & Watts Law").size(15),
            text("Enter any 2 of 4 values to solve for the remaining 2. Applies to circuit design, audio impedance matching, MOSFET PSU design, and LED driver sizing.")
                .size(10),
            q_block("Power (W)",      &s.p_in, &s.p_out, Message::OhmPower),
            q_block("Current (A)",    &s.i_in, &s.i_out, Message::OhmCurrent),
            q_block("Resistance (\u{03A9})", &s.r_in, &s.r_out, Message::OhmResistance),
            q_block("Voltage (V)",    &s.v_in, &s.v_out, Message::OhmVoltage),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

fn margin_section<'a>(s: &'a MarginState) -> Element<'a, Message> {
    container(
        column![
            text("Margin & Markup").size(15),
            text("Ecommerce pricing: calculate profit, margin %, and markup % from cost and selling price.")
                .size(10),
            q_block("Cost Price ($)",  &s.cost_in, &s.profit_out,      Message::MarginCost),
            q_block("Selling Price ($)", &s.sell_in, &s.margin_pct_out, Message::MarginSell),
            io_row("Markup", &s.markup_pct_out),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

fn roi_section<'a>(s: &'a RoiState) -> Element<'a, Message> {
    container(
        column![
            text("Return on Investment (ROI)").size(15),
            text("Measure profitability of ad spend, marketing campaigns, and capital expenditures.")
                .size(10),
            q_block("Investment ($)", &s.investment_in, &s.profit_out,  Message::RoiInvestment),
            q_block("Revenue ($)",     &s.revenue_in,    &s.roi_pct_out, Message::RoiRevenue),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

fn token_section<'a>(s: &'a TokenState) -> Element<'a, Message> {
    container(
        column![
            text("AI Token Cost Estimator").size(15),
            text("Compare per-million-token pricing across 6 major LLMs (GPT-4o, Claude 3.5 Sonnet, etc.).")
                .size(10),
            row![
                button(text("\u{25C0}")).on_press(Message::TokenPrev),
                text(s.model.label()).size(12),
                button(text("\u{25B6}")).on_press(Message::TokenNext),
            ]
            .spacing(8)
            .align_items(alignment::Alignment::Center),
            q_block("Input Tokens",  &s.input_tok_in,  &s.input_cost_out,  Message::TokenInputTok),
            q_block("Output Tokens", &s.output_tok_in, &s.output_cost_out, Message::TokenOutputTok),
            io_row("Total Cost", &s.total_cost_out),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

fn elec_section<'a>(s: &'a ElecState) -> Element<'a, Message> {
    container(
        column![
            text("Electricity Cost").size(15),
            text("Project monthly and yearly power costs for GPU servers, datacenter racks, and mining rigs.")
                .size(10),
            q_block("Power (W)",    &s.power_in, &s.daily_kwh_out,    Message::ElecPower),
            q_block("Hours / Day",  &s.hours_in, &s.monthly_kwh_out,  Message::ElecHours),
            q_block("Days / Month", &s.days_in,  &s.monthly_cost_out, Message::ElecDays),
            q_block("Rate ($/kWh)", &s.rate_in,  &s.yearly_cost_out,  Message::ElecRate),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

fn be_section<'a>(s: &'a BeState) -> Element<'a, Message> {
    container(
        column![
            text("Break-Even Analysis").size(15),
            text("How many units must you sell to cover all fixed and variable costs?")
                .size(10),
            q_block("Fixed Costs ($)",      &s.fixed_in,    &s.units_out,   Message::BeFixed),
            q_block("Price per Unit ($)",   &s.price_in,    &s.revenue_out, Message::BePrice),
            q_block("Variable Cost / Unit ($)", &s.variable_in, "", Message::BeVariable),
        ]
        .spacing(5),
    )
    .padding(12)
    .width(Length::Fill)
    .into()
}

// ══════════════════════════════════════════════════════════════════════
//  Shared UI helpers
// ══════════════════════════════════════════════════════════════════════

fn q_block<'a>(
    label: &'a str,
    input_val: &'a str,
    result_val: &'a str,
    msg: fn(String) -> Message,
) -> Element<'a, Message> {
    column![
        text(label).size(11),
        row![
            text_input("", input_val)
                .on_input(msg)
                .width(Length::FillPortion(3))
                .padding(4),
            text(result_val)
                .width(Length::FillPortion(4))
                .vertical_alignment(alignment::Vertical::Center),
        ]
        .spacing(6)
        .align_items(alignment::Alignment::Center),
    ]
    .spacing(2)
    .into()
}

fn io_row<'a>(label: &'a str, value: &'a str) -> Element<'a, Message> {
    row![
        text(label).size(11).width(Length::FillPortion(3)),
        text(value)
            .size(11)
            .width(Length::FillPortion(4))
            .vertical_alignment(alignment::Vertical::Center),
    ]
    .spacing(6)
    .align_items(alignment::Alignment::Center)
    .into()
}

// ══════════════════════════════════════════════════════════════════════
//  Recalculate impls (delegate to calc.rs)
// ══════════════════════════════════════════════════════════════════════

impl OhmState {
    fn recalculate(&mut self) {
        let p: f64 = self.p_in.trim().parse().unwrap_or(0.0);
        let i: f64 = self.i_in.trim().parse().unwrap_or(0.0);
        let r: f64 = self.r_in.trim().parse().unwrap_or(0.0);
        let v: f64 = self.v_in.trim().parse().unwrap_or(0.0);

        if (self.p_in.trim().parse::<f64>().is_ok() && p < 0.0)
            || (self.r_in.trim().parse::<f64>().is_ok() && r < 0.0)
        {
            self.p_out = "0 Watts(W)".into();
            self.i_out = "0 Amps(A)".into();
            self.r_out = "0 Ohms(\u{03A9})".into();
            self.v_out = "0 Volts(V)".into();
            return;
        }

        let (p, i, r, v) = ohm_calculate(p, i, r, v);
        self.p_out = fmt_eng(p, "Watts(W)");
        self.i_out = fmt_eng(i, "Amps(A)");
        self.r_out = fmt_eng(r, "Ohms(\u{03A9})");
        self.v_out = fmt_eng(v, "Volts(V)");
    }
}

impl MarginState {
    fn recalculate(&mut self) {
        let cost = self.cost_in.trim().parse().unwrap_or(0.0);
        let sell = self.sell_in.trim().parse().unwrap_or(0.0);
        let (profit, margin, markup) = margin_calculate(cost, sell);
        self.profit_out     = fmt_num(profit);
        self.margin_pct_out = fmt_pct(margin);
        self.markup_pct_out = fmt_pct(markup);
    }
}

impl RoiState {
    fn recalculate(&mut self) {
        let inv = self.investment_in.trim().parse().unwrap_or(0.0);
        let rev = self.revenue_in.trim().parse().unwrap_or(0.0);
        let (profit, roi) = roi_calculate(inv, rev);
        self.profit_out  = fmt_num(profit);
        self.roi_pct_out = fmt_pct(roi);
    }
}

impl TokenState {
    fn recalculate(&mut self) {
        let in_tok  = self.input_tok_in.trim().parse().unwrap_or(0.0);
        let out_tok = self.output_tok_in.trim().parse().unwrap_or(0.0);
        let (in_cost, out_cost, total) = token_cost_calculate(self.model, in_tok, out_tok);
        self.input_cost_out  = fmt_dollar(in_cost);
        self.output_cost_out = fmt_dollar(out_cost);
        self.total_cost_out  = fmt_dollar(total);
    }
}

impl ElecState {
    fn recalculate(&mut self) {
        let watts = self.power_in.trim().parse().unwrap_or(0.0);
        let hours = self.hours_in.trim().parse().unwrap_or(0.0);
        let days  = self.days_in.trim().parse().unwrap_or(30.0);
        let rate  = self.rate_in.trim().parse().unwrap_or(0.0);
        let (daily, monthly_kwh, monthly_cost, yearly) =
            electricity_calculate(watts, hours, days, rate);
        self.daily_kwh_out   = fmt_eng(daily, "kWh");
        self.monthly_kwh_out = fmt_eng(monthly_kwh, "kWh");
        self.monthly_cost_out = fmt_dollar(monthly_cost);
        self.yearly_cost_out  = fmt_dollar(yearly);
    }
}

impl BeState {
    fn recalculate(&mut self) {
        let fixed    = self.fixed_in.trim().parse().unwrap_or(0.0);
        let price    = self.price_in.trim().parse().unwrap_or(0.0);
        let variable = self.variable_in.trim().parse().unwrap_or(0.0);
        let (units, revenue) = break_even_calculate(fixed, price, variable);
        self.units_out   = fmt_num(units);
        self.revenue_out = fmt_dollar(revenue);
    }
}