import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { ArrowRight, 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 { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";

const CYCLE = currentBudgetCycle();

function StatCardShell({
  to,
  ariaLabel,
  children,
}: {
  to: string;
  ariaLabel: string;
  children: React.ReactNode;
}) {
  return (
    <Link
      to={to}
      aria-label={ariaLabel}
      className="block rounded-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
    >
      <Card className="h-full transition-colors hover:border-primary/40 cursor-pointer">
        {children}
      </Card>
    </Link>
  );
}

function StatValue({
  value,
  loading,
  className,
}: {
  value: string | null;
  loading: boolean;
  className?: string;
}) {
  if (loading) return <Skeleton className="h-8 w-36" />;
  return (
    <span
      data-sensitive
      className={cn("text-2xl font-bold font-mono", className)}
    >
      {value ?? "—"}
    </span>
  );
}

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 (
    <StatCardShell to="/budget" ariaLabel="Ver presupuesto">
      <CardHeader className="pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">
          Gasto del ciclo
        </CardTitle>
        <CardDescription>
          Ciclo al 18 {MONTH_NAMES_ES_SHORT[CYCLE.month].toLowerCase()}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-1">
        <StatValue
          loading={q.isPending}
          value={
            q.isError ? null : spend !== null ? formatAmount(spend, "CRC") : null
          }
        />
        {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>
        )}
      </CardContent>
    </StatCardShell>
  );
}

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,
  );
  const inCycle = active.filter((p) => {
    const d = new Date(p.next_cuota_date!);
    return d >= CYCLE.start && d < CYCLE.end;
  });
  const cycleTotal = inCycle.reduce((s, p) => s + p.installment_amount, 0);
  const upcoming = [...active]
    .sort(
      (a, b) =>
        new Date(a.next_cuota_date!).getTime() -
        new Date(b.next_cuota_date!).getTime(),
    )
    .slice(0, 3);

  return (
    <StatCardShell to="/financiamientos" ariaLabel="Ver financiamientos">
      <CardHeader className="pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">
          Próximas cuotas
        </CardTitle>
        <CardDescription>Tasa Cero en este ciclo</CardDescription>
      </CardHeader>
      <CardContent className="space-y-2">
        <StatValue
          loading={q.isPending}
          value={q.isError ? null : formatAmount(cycleTotal, "CRC")}
        />
        {upcoming.length > 0 && (
          <ul className="space-y-0.5 text-xs text-muted-foreground">
            {upcoming.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(p.installment_amount, 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>
        )}
      </CardContent>
    </StatCardShell>
  );
}

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 (
    <StatCardShell to="/pensions" ariaLabel="Ver pensiones">
      <CardHeader className="pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">
          Pensión
        </CardTitle>
        <CardDescription>Saldo total de fondos</CardDescription>
      </CardHeader>
      <CardContent className="space-y-2">
        <StatValue
          loading={q.isPending}
          value={
            q.isError ? null : total !== null ? formatAmount(total, "CRC") : null
          }
        />
        {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>
        )}
      </CardContent>
    </StatCardShell>
  );
}

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">
      <div>
        <h1
          className="text-2xl font-bold tracking-tight"
          style={{ fontFamily: "var(--font-heading)" }}
        >
          Inicio
        </h1>
        <p className="text-sm text-muted-foreground">
          Tu panorama financiero de hoy.
        </p>
      </div>

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

      <AskAssistantCard />

      <RecentTransactionsCard />
    </div>
  );
}
