import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { ArrowRight, Home, Sparkles } from "lucide-react";
import { useQuery } from "@tanstack/react-query";

import {
  getInstallmentPlans,
  getMonthlyDetail,
  getPensionFundSummary,
  getRecentTransactions,
} from "@/lib/api";
import { formatAmount } from "@/lib/format";
import {
  MONTH_NAMES_ES_SHORT,
  currentBudgetCycle,
  formatShortDate,
} from "@/lib/dates";
import { cn } from "@/lib/utils";
import { PageHeader } from "@/components/page-header";
import { StatTile } from "@/components/stat-tile";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";

const CYCLE = currentBudgetCycle();

function GastoDelCicloCard() {
  const q = useQuery({
    queryKey: ["budget", "month", CYCLE.year, CYCLE.month],
    queryFn: () =>
      getMonthlyDetail(CYCLE.year, CYCLE.month).then((r) => r.data),
  });
  const spend = q.data
    ? q.data.actuals_by_source.reduce((sum, a) => sum + a.net, 0)
    : null;
  const balance = q.data?.net_balance ?? null;

  return (
    <StatTile
      label="Gasto del ciclo"
      description={`Ciclo al 18 ${MONTH_NAMES_ES_SHORT[CYCLE.month].toLowerCase()}`}
      value={q.isError || spend === null ? null : formatAmount(spend, "CRC")}
      loading={q.isPending}
      to="/budget"
      ariaLabel="Ver presupuesto"
    >
      {balance !== null && (
        <p className="text-xs text-muted-foreground">
          Balance proyectado:{" "}
          <span
            data-sensitive
            className={cn(
              "font-mono font-medium",
              balance >= 0 ? "text-primary" : "text-destructive",
            )}
          >
            {balance >= 0 ? "+" : "-"}
            {formatAmount(balance, "CRC")}
          </span>
        </p>
      )}
      {q.isError && (
        <p className="text-xs text-muted-foreground">
          No se pudo cargar el ciclo.
        </p>
      )}
    </StatTile>
  );
}

function ProximasCuotasCard() {
  const q = useQuery({
    queryKey: ["installment-plans"],
    queryFn: () => getInstallmentPlans().then((r) => r.data),
  });
  const active = (q.data?.plans ?? []).filter(
    (p) => !p.is_completed && p.next_cuota_date,
  );
  // One cuota per plan per cycle, so the sum of every active plan's next
  // cuota is the load of the upcoming billing batch (next 19th). The last
  // cuota absorbs BAC's rounding, so use it when it's the one pending.
  const nextCuotaOf = (p: (typeof active)[number]) =>
    p.cuotas_billed === p.num_installments - 1
      ? p.last_installment_amount
      : p.installment_amount;
  const nextBatchTotal = active.reduce((s, p) => s + nextCuotaOf(p), 0);
  const upcoming = [...active].sort(
    (a, b) =>
      new Date(a.next_cuota_date!).getTime() -
      new Date(b.next_cuota_date!).getTime(),
  );
  const nextDate = upcoming[0]?.next_cuota_date;
  const topThree = upcoming.slice(0, 3);

  return (
    <StatTile
      label="Próximas cuotas"
      description={
        nextDate
          ? `Tasa Cero · próximo cobro ${formatShortDate(nextDate)}`
          : "Tasa Cero"
      }
      value={q.isError ? null : formatAmount(nextBatchTotal, "CRC")}
      loading={q.isPending}
      to="/financiamientos"
      ariaLabel="Ver financiamientos"
    >
      {topThree.length > 0 && (
        <ul className="space-y-0.5 text-xs text-muted-foreground">
          {topThree.map((p) => (
            <li key={p.id} className="flex justify-between gap-2">
              <span className="truncate">{p.merchant}</span>
              <span data-sensitive className="font-mono shrink-0">
                {formatShortDate(p.next_cuota_date!)} ·{" "}
                {formatAmount(nextCuotaOf(p), p.currency)}
              </span>
            </li>
          ))}
        </ul>
      )}
      {q.data && (
        <p className="text-xs text-muted-foreground">
          Restante total:{" "}
          <span data-sensitive className="font-mono font-medium">
            {formatAmount(q.data.total_remaining, "CRC")}
          </span>
        </p>
      )}
    </StatTile>
  );
}

function PensionCard() {
  const q = useQuery({
    queryKey: ["pension-fund-summary"],
    queryFn: () => getPensionFundSummary().then((r) => r.data),
  });
  const total = q.data ? q.data.reduce((s, f) => s + f.saldo_final, 0) : null;

  return (
    <StatTile
      label="Pensión"
      description="Saldo total de fondos"
      value={q.isError || total === null ? null : formatAmount(total, "CRC")}
      loading={q.isPending}
      to="/pensions"
      ariaLabel="Ver pensiones"
    >
      {q.data && q.data.length > 0 && (
        <ul className="space-y-0.5 text-xs text-muted-foreground">
          {q.data.map((f) => (
            <li key={f.fund} className="flex justify-between gap-2">
              <span>{f.fund}</span>
              <span data-sensitive className="font-mono">
                {formatAmount(f.saldo_final, "CRC")}
              </span>
            </li>
          ))}
        </ul>
      )}
    </StatTile>
  );
}

function AskAssistantCard() {
  const [question, setQuestion] = useState("");
  const navigate = useNavigate();

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const ask = question.trim();
    navigate("/asistente", ask ? { state: { ask } } : undefined);
  };

  return (
    <Card>
      <CardContent className="pt-6">
        <form onSubmit={handleSubmit} className="flex items-center gap-3">
          <Sparkles className="w-5 h-5 text-primary shrink-0" aria-hidden />
          <Input
            value={question}
            onChange={(e) => setQuestion(e.target.value)}
            placeholder="¿Cuánto gasté este ciclo?"
            aria-label="Pregúntale al asistente"
            className="flex-1"
          />
          <Button type="submit">Preguntar</Button>
        </form>
      </CardContent>
    </Card>
  );
}

function RecentTransactionsCard() {
  const q = useQuery({
    queryKey: ["transactions", "recent"],
    queryFn: () => getRecentTransactions(5).then((r) => r.data),
  });

  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">
          Últimas transacciones
        </CardTitle>
        <Link
          to="/budget"
          className="flex items-center gap-1 text-xs text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded"
        >
          Ver todo
          <ArrowRight className="w-3 h-3" aria-hidden />
        </Link>
      </CardHeader>
      <CardContent>
        {q.isPending ? (
          <div className="space-y-2">
            {Array.from({ length: 5 }, (_, i) => (
              <Skeleton key={i} className="h-6 w-full" />
            ))}
          </div>
        ) : q.isError ? (
          <p className="text-sm text-muted-foreground">
            No se pudieron cargar las transacciones.
          </p>
        ) : (
          <ul className="divide-y divide-border">
            {(q.data ?? []).map((tx) => (
              <li
                key={tx.id}
                className="flex items-center justify-between gap-3 py-2 text-sm"
              >
                <span className="truncate">{tx.merchant}</span>
                <span className="flex items-center gap-3 shrink-0">
                  <span className="text-xs text-muted-foreground">
                    {formatShortDate(tx.date)}
                  </span>
                  <span
                    data-sensitive
                    className={cn(
                      "font-mono",
                      tx.transaction_type !== "COMPRA" && "text-primary",
                    )}
                  >
                    {tx.transaction_type === "COMPRA" ? "-" : "+"}
                    {formatAmount(tx.amount, tx.currency)}
                  </span>
                </span>
              </li>
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  );
}

export default function Inicio() {
  return (
    <div className="space-y-6">
      <PageHeader
        icon={Home}
        title="Inicio"
        subtitle="Tu panorama financiero de hoy."
      />

      <div className="grid gap-4 md:grid-cols-3">
        <GastoDelCicloCard />
        <ProximasCuotasCard />
        <PensionCard />
      </div>

      <AskAssistantCard />

      <RecentTransactionsCard />
    </div>
  );
}
