import { Link, useNavigate } from "@tanstack/react-router";
import { subDays } from "date-fns";
import { ArrowLeft } from "lucide-react";
import { useMemo, useState } from "react";
import {
  CartesianGrid,
  Line,
  LineChart,
  ReferenceLine,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { DatePicker } from "@/components/ui/date-picker";
import { useDailyQuotes, useHistoricalMinMax, useQuotes } from "@/lib/queries";

const CURRENCIES = ["BELO", "BLUE", "BNA"] as const;

const CURRENCY_LABELS: Record<string, string> = {
  BELO: "BELO",
  BLUE: "Dólar Blue",
  BNA: "Dólar Oficial",
};

const priceFormatter = new Intl.NumberFormat("es-AR", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
});

function formatDate(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

const dateFormatter = new Intl.DateTimeFormat("es-AR", {
  day: "numeric",
  month: "long",
  year: "numeric",
});

function formatShortDate(iso: string): string {
  const datePart = iso.split(" ")[0];
  const [y, m, d] = datePart.split("-").map(Number);
  return dateFormatter.format(new Date(y, m - 1, d));
}

export function AnalysisPage({ currency }: { currency: string }) {
  const navigate = useNavigate();
  const today = new Date();
  const defaultStart = subDays(today, 30);

  const [startDate, setStartDate] = useState<Date>(defaultStart);
  const [endDate, setEndDate] = useState<Date>(today);

  const startDateStr = formatDate(startDate);
  const endDateStr = formatDate(endDate);

  const { data: historical, isLoading: historicalLoading } =
    useHistoricalMinMax(currency);
  const { data: quotes } = useQuotes();
  const { data: daily, isLoading: dailyLoading } = useDailyQuotes(
    currency,
    startDateStr,
    endDateStr,
  );

  const yesterday = subDays(today, 1);
  const yesterdayStr = formatDate(yesterday);
  const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
  const firstOfMonthStr = formatDate(firstOfMonth);

  const { data: yesterdayQuote } = useDailyQuotes(
    currency,
    yesterdayStr,
    yesterdayStr,
  );
  const { data: firstDayQuote } = useDailyQuotes(
    currency,
    firstOfMonthStr,
    firstOfMonthStr,
  );

  const chartData = useMemo(() => {
    if (!daily) return [];
    return daily.map((d) => ({
      date: formatShortDate(d.date),
      buy: d.buy,
    }));
  }, [daily]);

  const { yDomain, minBuyValue, maxBuyValue, avgBuyValue } = useMemo(() => {
    if (chartData.length === 0)
      return {
        yDomain: [0, 0] as [number, number],
        minBuyValue: 0,
        maxBuyValue: 0,
        avgBuyValue: 0,
      };
    let min = Infinity;
    let max = -Infinity;
    let sum = 0;
    for (const d of chartData) {
      if (d.buy < min) min = d.buy;
      if (d.buy > max) max = d.buy;
      sum += d.buy;
    }
    const range = max - min || 1;
    return {
      yDomain: [min - range * 0.1, max + range * 0.1] as [number, number],
      minBuyValue: min,
      maxBuyValue: max,
      avgBuyValue: sum / chartData.length,
    };
  }, [chartData]);

  const currentQuote = quotes?.find((q) => q.type === currency);
  const currentBuy = currentQuote ? Number(currentQuote.buy) : 0;

  const yesterdayBuy = yesterdayQuote?.[0]?.buy ?? null;
  const prevDayDiff = yesterdayBuy !== null ? currentBuy - yesterdayBuy : null;
  const prevDayPct =
    prevDayDiff !== null && yesterdayBuy !== null && yesterdayBuy !== 0
      ? (prevDayDiff / yesterdayBuy) * 100
      : null;

  const firstMonthBuy = firstDayQuote?.[0]?.buy ?? null;
  const monthDiff = firstMonthBuy !== null ? currentBuy - firstMonthBuy : null;
  const monthPct =
    monthDiff !== null && firstMonthBuy !== null && firstMonthBuy !== 0
      ? (monthDiff / firstMonthBuy) * 100
      : null;

  const backTo = currency === "BELO" ? "/quotes/belo" : "/quotes";
  const backLabel = currency === "BELO" ? "BELO" : "Cotizaciones";

  function VariationValue({
    value,
    pct,
  }: {
    value: number | null;
    pct: number | null;
  }) {
    if (value === null || pct === null)
      return <p className="text-sm text-muted-foreground">Sin datos</p>;
    const isPositive = value >= 0;
    const color = isPositive ? "text-emerald-500" : "text-red-500";
    const sign = isPositive ? "+" : "";
    return (
      <p className={`text-lg font-bold tabular-nums ${color}`}>
        {sign}${priceFormatter.format(Math.abs(value))}{" "}
        <span className="text-sm font-normal">
          ({sign}
          {pct.toFixed(2)}%)
        </span>
      </p>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Link
            to={backTo}
            className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors"
          >
            <ArrowLeft className="size-4" />
            {backLabel}
          </Link>
          <h1 className="text-2xl font-semibold">Análisis</h1>
        </div>
        <div className="flex items-center gap-1 rounded-lg border p-0.5">
          {CURRENCIES.map((c) => (
            <button
              key={c}
              type="button"
              onClick={() =>
                navigate({ to: "/quotes/analysis/$currency", params: { currency: c } })
              }
              className={`px-3 py-1 text-xs rounded-md transition-colors cursor-pointer ${
                currency === c
                  ? "bg-primary text-primary-foreground"
                  : "text-muted-foreground hover:text-foreground"
              }`}
            >
              {CURRENCY_LABELS[c]}
            </button>
          ))}
        </div>
      </div>

      <div className="grid gap-4 md:grid-cols-5">
        <div className="rounded-lg border p-4">
          <p className="text-sm text-muted-foreground mb-2">
            Cotización actual (compra)
          </p>
          <p className="text-2xl font-bold">
            ${priceFormatter.format(currentBuy)}
          </p>
        </div>
        <div className="rounded-lg border p-4">
          <p className="text-sm text-muted-foreground mb-2">
            Mínimo histórico (compra)
          </p>
          {historicalLoading ? (
            <p className="text-sm text-muted-foreground">Cargando...</p>
          ) : (
            <>
              <p className="text-2xl font-bold">
                ${priceFormatter.format(historical?.minBuy ?? 0)}
              </p>
              {historical?.minBuyDate && (
                <p className="text-xs text-muted-foreground mt-0.5">
                  el {formatShortDate(historical.minBuyDate)}
                </p>
              )}
            </>
          )}
        </div>
        <div className="rounded-lg border p-4">
          <p className="text-sm text-muted-foreground mb-2">
            Máximo histórico (compra)
          </p>
          {historicalLoading ? (
            <p className="text-sm text-muted-foreground">Cargando...</p>
          ) : (
            <>
              <p className="text-2xl font-bold">
                ${priceFormatter.format(historical?.maxBuy ?? 0)}
              </p>
              {historical?.maxBuyDate && (
                <p className="text-xs text-muted-foreground mt-0.5">
                  el {formatShortDate(historical.maxBuyDate)}
                </p>
              )}
            </>
          )}
        </div>
        <div className="rounded-lg border p-4">
          <p className="text-sm text-muted-foreground mb-2">Vs. día anterior</p>
          <VariationValue value={prevDayDiff} pct={prevDayPct} />
        </div>
        <div className="rounded-lg border p-4">
          <p className="text-sm text-muted-foreground mb-2">
            Vs. primer día del mes
          </p>
          <VariationValue value={monthDiff} pct={monthPct} />
        </div>
      </div>

      <div className="rounded-lg border p-4">
        <h2 className="text-sm font-medium mb-4">
          Evolución del precio de compra
        </h2>

        <div className="flex items-center gap-4 mb-4">
          <div className="flex flex-col gap-1">
            <span className="text-xs text-muted-foreground">Desde</span>
            <DatePicker
              value={startDate}
              onChange={(d) => d && setStartDate(d)}
              placeholder="Fecha inicio"
            />
          </div>
          <div className="flex flex-col gap-1">
            <span className="text-xs text-muted-foreground">Hasta</span>
            <DatePicker
              value={endDate}
              onChange={(d) => d && setEndDate(d)}
              placeholder="Fecha fin"
            />
          </div>
        </div>

        {dailyLoading ? (
          <div className="flex items-center justify-center h-64 text-muted-foreground">
            Cargando...
          </div>
        ) : chartData.length === 0 ? (
          <div className="flex items-center justify-center h-64 text-muted-foreground">
            Sin datos para este período
          </div>
        ) : (
          <>
            <div className="h-64">
              <ResponsiveContainer width="100%" height="100%">
                <LineChart data={chartData}>
                  <CartesianGrid
                    strokeDasharray="3 3"
                    className="stroke-border"
                  />
                  <XAxis
                    dataKey="date"
                    tick={{ fontSize: 11 }}
                    className="text-muted-foreground"
                    interval="preserveStartEnd"
                  />
                  <YAxis
                    tick={{ fontSize: 11 }}
                    className="text-muted-foreground"
                    tickFormatter={(v: number) =>
                      `$${priceFormatter.format(v)}`
                    }
                    width={80}
                    domain={yDomain}
                  />
                  <Tooltip
                    formatter={(value: unknown) => [
                      `$${priceFormatter.format(Number(value))}`,
                      "Compra",
                    ]}
                    labelFormatter={(label: unknown) => `Fecha: ${label}`}
                    contentStyle={{
                      backgroundColor: "var(--card)",
                      border: "1px solid var(--border)",
                      borderRadius: "var(--radius)",
                      fontSize: 13,
                    }}
                  />
                  <ReferenceLine
                    y={maxBuyValue}
                    stroke="var(--chart-1)"
                    strokeDasharray="4 4"
                    strokeWidth={1.5}
                    label={{
                      value: `Máx: $${priceFormatter.format(maxBuyValue)}`,
                      position: "right",
                      fontSize: 11,
                      fill: "var(--chart-1)",
                    }}
                  />
                  <ReferenceLine
                    y={minBuyValue}
                    stroke="var(--chart-2)"
                    strokeDasharray="4 4"
                    strokeWidth={1.5}
                    label={{
                      value: `Mín: $${priceFormatter.format(minBuyValue)}`,
                      position: "right",
                      fontSize: 11,
                      fill: "var(--chart-2)",
                    }}
                  />
                  <ReferenceLine
                    y={avgBuyValue}
                    stroke="var(--chart-3)"
                    strokeDasharray="4 4"
                    strokeWidth={1.5}
                    label={{
                      value: `Prom: $${priceFormatter.format(avgBuyValue)}`,
                      position: "right",
                      fontSize: 11,
                      fill: "var(--chart-3)",
                    }}
                  />
                  <Line
                    type="linear"
                    dataKey="buy"
                    name="Compra"
                    stroke="var(--chart-1)"
                    strokeWidth={2}
                    dot={false}
                    activeDot={{ r: 4 }}
                    isAnimationActive={false}
                  />
                </LineChart>
              </ResponsiveContainer>
            </div>
            <div className="flex items-center justify-center gap-4 mt-3">
              <div className="flex items-center gap-1.5">
                <span
                  className="size-2.5 rounded-full"
                  style={{ backgroundColor: "var(--chart-1)" }}
                />
                <span className="text-xs text-muted-foreground">Compra</span>
              </div>
              <div className="flex items-center gap-1.5">
                <div
                  className="size-2.5 border-t-2 border-dashed"
                  style={{ borderColor: "var(--chart-1)" }}
                />
                <span className="text-xs text-muted-foreground">Máx</span>
              </div>
              <div className="flex items-center gap-1.5">
                <div
                  className="size-2.5 border-t-2 border-dashed"
                  style={{ borderColor: "var(--chart-2)" }}
                />
                <span className="text-xs text-muted-foreground">Mín</span>
              </div>
              <div className="flex items-center gap-1.5">
                <div
                  className="size-2.5 border-t-2 border-dashed"
                  style={{ borderColor: "var(--chart-3)" }}
                />
                <span className="text-xs text-muted-foreground">Prom</span>
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
