"use client";

import { useState, useMemo, useEffect, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import {
  AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip,
  ResponsiveContainer, ReferenceLine
} from "recharts";
import { Sparkles, TrendingUp, TrendingDown, Zap, RotateCcw, ChevronRight, AlertTriangle } from "lucide-react";
import { aiApi } from "@/lib/api";

// ─── Types ────────────────────────────────────────────────────────────────────
interface SimParams {
  monthlyIncome: number;
  monthlyExpenses: number;
  savingsRate: number;
  investmentReturn: number;
  loanPayment: number;
  emergencyMonths: number;
}

const DEFAULT_PARAMS: SimParams = {
  monthlyIncome: 10200,
  monthlyExpenses: 6100,
  savingsRate: 40,
  investmentReturn: 7,
  loanPayment: 450,
  emergencyMonths: 6,
};

const scenarios = [
  {
    id: "aggressive",
    label: "Aggressive Saver",
    icon: "🚀",
    color: "text-emerald-400",
    bg: "bg-emerald-500/10 border-emerald-500/20",
    params: { savingsRate: 55, monthlyExpenses: 4600, investmentReturn: 9 },
  },
  {
    id: "balanced",
    label: "Balanced Growth",
    icon: "⚖️",
    color: "text-blue-400",
    bg: "bg-blue-500/10 border-blue-500/20",
    params: { savingsRate: 40, monthlyExpenses: 6100, investmentReturn: 7 },
  },
  {
    id: "conservative",
    label: "Conservative",
    icon: "🛡️",
    color: "text-purple-400",
    bg: "bg-purple-500/10 border-purple-500/20",
    params: { savingsRate: 25, monthlyExpenses: 7600, investmentReturn: 4 },
  },
];

// ─── Local projection engine (instant feedback while API loads) ───────────────
function projectBalance(params: SimParams, startBalance: number, months = 36) {
  const monthlySavings = params.monthlyIncome * (params.savingsRate / 100);
  const monthlyReturn = params.investmentReturn / 100 / 12;
  let balance = startBalance;
  return Array.from({ length: months + 1 }, (_, i) => {
    if (i > 0) balance = balance * (1 + monthlyReturn) + monthlySavings - params.loanPayment;
    return { month: i === 0 ? "Now" : `M${i}`, balance: Math.round(balance), savings: Math.round(monthlySavings * i) };
  });
}

// ─── Custom Tooltip ───────────────────────────────────────────────────────────
interface TooltipProps {
  active?: boolean;
  payload?: Array<{ name: string; value: number; stroke?: string; fill?: string }>;
  label?: string;
}
function CustomTooltip({ active, payload, label }: TooltipProps) {
  if (!active || !payload?.length) return null;
  return (
    <div className="glass-card p-3 text-xs space-y-1">
      <p className="text-zinc-400 font-medium">{label}</p>
      {payload.map((entry) => (
        <div key={entry.name} className="flex justify-between gap-4">
          <span style={{ color: entry.stroke || entry.fill }}>{entry.name}</span>
          <span className="text-white font-semibold">${entry.value?.toLocaleString()}</span>
        </div>
      ))}
    </div>
  );
}

// ─── Slider ───────────────────────────────────────────────────────────────────
function Slider({ label, value, min, max, step, format, onChange, color = "emerald" }: {
  label: string; value: number; min: number; max: number; step: number;
  format: (v: number) => string; onChange: (v: number) => void; color?: string;
}) {
  const pct = ((value - min) / (max - min)) * 100;
  const colorMap: Record<string, string> = {
    emerald: "#10b981", blue: "#3b82f6", purple: "#8b5cf6", amber: "#f59e0b", red: "#ef4444",
  };
  const c = colorMap[color] || colorMap.emerald;

  return (
    <div className="space-y-2">
      <div className="flex items-center justify-between">
        <span className="text-xs font-medium text-zinc-400">{label}</span>
        <motion.span
          key={value}
          initial={{ scale: 1.15, color: c }}
          animate={{ scale: 1, color: "#ffffff" }}
          transition={{ duration: 0.25 }}
          className="text-sm font-bold text-white"
        >
          {format(value)}
        </motion.span>
      </div>
      <div className="relative h-2 w-full rounded-full bg-white/10">
        <div className="absolute h-full rounded-full transition-all duration-100"
          style={{ width: `${pct}%`, background: `linear-gradient(90deg, ${c}88, ${c})` }} />
        <input type="range" min={min} max={max} step={step} value={value}
          onChange={(e) => onChange(Number(e.target.value))}
          className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" style={{ zIndex: 10 }} />
        <div className="absolute top-1/2 -translate-y-1/2 h-4 w-4 rounded-full border-2 border-white shadow-lg transition-all duration-100"
          style={{ left: `calc(${pct}% - 8px)`, background: c }} />
      </div>
    </div>
  );
}

// ─── Metric Card ──────────────────────────────────────────────────────────────
function MetricCard({ label, value, sub, positive, icon }: {
  label: string; value: string; sub: string; positive: boolean; icon: React.ReactNode;
}) {
  return (
    <motion.div whileHover={{ scale: 1.02 }} className="glass-card p-4">
      <div className="flex items-start justify-between">
        <p className="text-xs text-zinc-400">{label}</p>
        <div className="text-zinc-500">{icon}</div>
      </div>
      <p className="mt-2 text-xl font-bold text-white">{value}</p>
      <p className={`text-xs mt-1 ${positive ? "text-emerald-400" : "text-red-400"}`}>{sub}</p>
    </motion.div>
  );
}

// ─── Main Page ────────────────────────────────────────────────────────────────
export default function SimulatorPage() {
  const [params, setParams] = useState<SimParams>(DEFAULT_PARAMS);
  const [activeScenario, setActiveScenario] = useState<string | null>("balanced");
  const [startBalance, setStartBalance] = useState(24563);
  const [apiScenarios, setApiScenarios] = useState<Record<string, number> | null>(null);
  const [loadingApi, setLoadingApi] = useState(false);
  const [apiError, setApiError] = useState(false);

  // Load real starting balance and API scenarios on mount
  useEffect(() => {
    const loadApiData = async () => {
      setLoadingApi(true);
      try {
        const [twinData, scenariosData] = await Promise.all([
          aiApi.twinPredict(),
          aiApi.twinScenarios(6),
        ]);
        // Extract starting balance from twin prediction
        const projections = twinData.monthly_projections;
        if (projections && projections.length > 0) {
          setStartBalance(projections[0].balance || 24563);
        }
        // Extract scenario end values
        if (scenariosData.scenarios) {
          const s = scenariosData.scenarios;
          const getEnd = (arr: number[]) => arr[arr.length - 1] || 0;
          setApiScenarios({
            conservative: getEnd(s.conservative || []),
            expected: getEnd(s.expected || []),
            optimistic: getEnd(s.optimistic || []),
          });
        }
        setApiError(false);
      } catch {
        setApiError(true);
      } finally {
        setLoadingApi(false);
      }
    };
    loadApiData();
  }, []);

  const projection = useMemo(() => projectBalance(params, startBalance), [params, startBalance]);
  const baseProjection = useMemo(() => projectBalance(DEFAULT_PARAMS, startBalance), [startBalance]);

  const finalBalance = projection[projection.length - 1].balance;
  const baseBalance = baseProjection[baseProjection.length - 1].balance;
  const delta = finalBalance - baseBalance;
  const monthlySavings = params.monthlyIncome * (params.savingsRate / 100);
  const emergencyTarget = params.monthlyExpenses * params.emergencyMonths;
  const monthsToEmergency = Math.ceil(Math.max(0, emergencyTarget - startBalance) / monthlySavings);

  const update = (key: keyof SimParams) => (v: number) => {
    setParams((p) => ({ ...p, [key]: v }));
    setActiveScenario(null);
  };

  const applyScenario = (s: typeof scenarios[0]) => {
    setParams((p) => ({ ...p, ...s.params }));
    setActiveScenario(s.id);
  };

  const reset = useCallback(() => {
    setParams(DEFAULT_PARAMS);
    setActiveScenario("balanced");
  }, []);

  const comparisonData = projection.map((p, i) => ({
    ...p,
    base: baseProjection[i]?.balance,
  }));

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.4 }}
      className="flex flex-col gap-6"
    >
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold tracking-tight text-white">What-If Simulator</h1>
          <p className="text-zinc-400 mt-1 text-sm">
            Model financial scenarios and see your future balance in real-time
            {loadingApi && <span className="ml-2 text-zinc-600">· Loading real data...</span>}
          </p>
        </div>
        <button onClick={reset} className="flex items-center gap-2 rounded-xl border border-white/10 bg-white/5 px-3 py-2 text-xs text-zinc-400 hover:text-white transition-colors">
          <RotateCcw className="h-3.5 w-3.5" />
          Reset
        </button>
      </div>

      {/* API error notice */}
      {apiError && (
        <div className="flex items-center gap-3 rounded-2xl border border-amber-500/20 bg-amber-500/5 px-5 py-3">
          <AlertTriangle className="h-4 w-4 text-amber-400 flex-shrink-0" />
          <p className="text-xs text-zinc-400">
            <span className="text-amber-400 font-medium">Using local projections</span> — backend offline. Sliders still work with estimated data.
          </p>
        </div>
      )}

      {/* API Scenario Cards (from backend) */}
      {apiScenarios && (
        <div className="glass-card p-4">
          <div className="flex items-center gap-2 mb-3">
            <Sparkles className="h-4 w-4 text-emerald-400" />
            <span className="text-xs font-semibold text-white">AI 6-Month Forecast (from your real data)</span>
          </div>
          <div className="grid grid-cols-3 gap-3">
            {[
              { label: "Conservative", value: apiScenarios.conservative, color: "text-zinc-400" },
              { label: "Expected", value: apiScenarios.expected, color: "text-blue-400" },
              { label: "Optimistic", value: apiScenarios.optimistic, color: "text-emerald-400" },
            ].map((s) => (
              <div key={s.label} className="text-center">
                <p className="text-xs text-zinc-500">{s.label}</p>
                <p className={`text-lg font-bold mt-1 ${s.color}`}>
                  ${s.value.toLocaleString()}
                </p>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Scenario Presets */}
      <div className="grid grid-cols-3 gap-3">
        {scenarios.map((s) => (
          <motion.button
            key={s.id}
            whileHover={{ scale: 1.02 }}
            whileTap={{ scale: 0.98 }}
            onClick={() => applyScenario(s)}
            className={`flex items-center gap-3 rounded-2xl border p-4 text-left transition-all ${s.bg} ${
              activeScenario === s.id ? "ring-1 ring-white/20" : ""
            }`}
          >
            <span className="text-2xl">{s.icon}</span>
            <div>
              <p className={`text-sm font-semibold ${s.color}`}>{s.label}</p>
              <p className="text-xs text-zinc-500 mt-0.5">Apply preset</p>
            </div>
            {activeScenario === s.id && <div className="ml-auto h-2 w-2 rounded-full bg-white/60" />}
          </motion.button>
        ))}
      </div>

      <div className="grid gap-6 lg:grid-cols-5">
        {/* Controls */}
        <motion.div
          initial={{ opacity: 0, x: -20 }}
          animate={{ opacity: 1, x: 0 }}
          transition={{ duration: 0.4 }}
          className="col-span-2 glass-card p-6 space-y-6"
        >
          <div className="flex items-center gap-2">
            <Zap className="h-4 w-4 text-amber-400" />
            <h2 className="text-sm font-semibold text-white">Adjust Parameters</h2>
          </div>
          <Slider label="Monthly Income" value={params.monthlyIncome} min={3000} max={25000} step={100}
            format={(v) => `$${v.toLocaleString()}`} onChange={update("monthlyIncome")} color="emerald" />
          <Slider label="Monthly Expenses" value={params.monthlyExpenses} min={1500} max={15000} step={100}
            format={(v) => `$${v.toLocaleString()}`} onChange={update("monthlyExpenses")} color="amber" />
          <Slider label="Savings Rate" value={params.savingsRate} min={5} max={80} step={1}
            format={(v) => `${v}%`} onChange={update("savingsRate")} color="blue" />
          <Slider label="Investment Return (Annual)" value={params.investmentReturn} min={1} max={20} step={0.5}
            format={(v) => `${v}%`} onChange={update("investmentReturn")} color="purple" />
          <Slider label="Loan Payment" value={params.loanPayment} min={0} max={3000} step={50}
            format={(v) => `$${v.toLocaleString()}`} onChange={update("loanPayment")} color="red" />
          <Slider label="Emergency Fund Target (months)" value={params.emergencyMonths} min={1} max={12} step={1}
            format={(v) => `${v}mo`} onChange={update("emergencyMonths")} color="emerald" />
        </motion.div>

        {/* Chart + Metrics */}
        <div className="col-span-3 flex flex-col gap-4">
          {/* Metrics */}
          <div className="grid grid-cols-3 gap-3">
            <MetricCard
              label="36-Month Balance"
              value={`$${(finalBalance / 1000).toFixed(1)}k`}
              sub={`${delta >= 0 ? "+" : ""}$${Math.abs(delta / 1000).toFixed(1)}k vs baseline`}
              positive={delta >= 0}
              icon={<TrendingUp className="h-4 w-4" />}
            />
            <MetricCard
              label="Monthly Savings"
              value={`$${monthlySavings.toFixed(0)}`}
              sub={`${params.savingsRate}% of income`}
              positive={params.savingsRate >= 20}
              icon={<Sparkles className="h-4 w-4" />}
            />
            <MetricCard
              label="Emergency Fund"
              value={monthsToEmergency === 0 ? "Funded ✓" : `${monthsToEmergency}mo`}
              sub={monthsToEmergency === 0 ? "Goal achieved" : `$${emergencyTarget.toLocaleString()} target`}
              positive={monthsToEmergency === 0}
              icon={<TrendingDown className="h-4 w-4" />}
            />
          </div>

          {/* Projection Chart */}
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.1 }}
            className="glass-card p-6 flex-1"
          >
            <div className="flex items-center justify-between mb-5">
              <div>
                <h2 className="text-base font-semibold text-white">36-Month Projection</h2>
                <p className="text-xs text-zinc-400 mt-0.5">Your scenario vs baseline</p>
              </div>
              <div className="flex gap-4 text-xs">
                <div className="flex items-center gap-1.5">
                  <div className="h-2 w-2 rounded-full bg-emerald-400" />
                  <span className="text-zinc-400">Your scenario</span>
                </div>
                <div className="flex items-center gap-1.5">
                  <div className="h-2 w-2 rounded-full bg-zinc-600" />
                  <span className="text-zinc-400">Baseline</span>
                </div>
              </div>
            </div>
            <ResponsiveContainer width="100%" height={260}>
              <AreaChart data={comparisonData} margin={{ top: 5, right: 5, left: -20, bottom: 0 }}>
                <defs>
                  <linearGradient id="simGrad" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="5%" stopColor="#10b981" stopOpacity={0.3} />
                    <stop offset="95%" stopColor="#10b981" stopOpacity={0} />
                  </linearGradient>
                  <linearGradient id="baseGrad" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="5%" stopColor="#6b7280" stopOpacity={0.2} />
                    <stop offset="95%" stopColor="#6b7280" stopOpacity={0} />
                  </linearGradient>
                </defs>
                <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.05)" />
                <XAxis dataKey="month" tick={{ fill: "#71717a", fontSize: 10 }} axisLine={false} tickLine={false} interval={5} />
                <YAxis tick={{ fill: "#71717a", fontSize: 10 }} axisLine={false} tickLine={false}
                  tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`} />
                <Tooltip content={<CustomTooltip />} />
                <ReferenceLine y={startBalance} stroke="rgba(255,255,255,0.1)" strokeDasharray="4 4" />
                <Area type="monotone" dataKey="base" name="Baseline" stroke="#6b7280" strokeWidth={1.5} fill="url(#baseGrad)" strokeDasharray="4 4" />
                <Area type="monotone" dataKey="balance" name="Scenario" stroke="#10b981" strokeWidth={2.5} fill="url(#simGrad)" />
              </AreaChart>
            </ResponsiveContainer>
          </motion.div>

          {/* Dynamic AI Insight */}
          <AnimatePresence mode="wait">
            <motion.div
              key={`${params.savingsRate}-${params.investmentReturn}`}
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -10 }}
              transition={{ duration: 0.3 }}
              className="flex items-start gap-3 rounded-2xl border border-blue-500/20 bg-blue-500/5 p-4"
            >
              <Sparkles className="h-4 w-4 text-blue-400 flex-shrink-0 mt-0.5" />
              <div className="flex-1">
                <p className="text-sm font-medium text-white">AI Insight</p>
                <p className="text-xs text-zinc-400 mt-1">
                  {params.savingsRate >= 50
                    ? `At ${params.savingsRate}% savings rate, you'll reach $100k in approximately ${Math.ceil((100000 - startBalance) / (params.monthlyIncome * params.savingsRate / 100))} months. That's an aggressive but achievable goal.`
                    : params.savingsRate >= 30
                    ? `Your ${params.savingsRate}% savings rate is above average. Increasing by just 5% more would add $${Math.round(params.monthlyIncome * 0.05 * 36).toLocaleString()} to your 3-year balance.`
                    : `At ${params.savingsRate}% savings rate, consider reducing discretionary spending. Even a 5% increase would significantly accelerate your goals.`}
                </p>
              </div>
              <button className="flex items-center gap-1 text-xs text-blue-400 hover:text-blue-300 transition-colors whitespace-nowrap">
                Ask AI <ChevronRight className="h-3 w-3" />
              </button>
            </motion.div>
          </AnimatePresence>
        </div>
      </div>
    </motion.div>
  );
}
