"use client";

import { useEffect, useMemo, useState } from "react";
import { BarChart3, Loader2, RefreshCw } from "lucide-react";
import Button from "@/components/ui/Button";
import { listPedidos } from "@/lib/pb/pedidos";
import { listPagos } from "@/lib/pb/pagos";
import { groupPagosByCuenta, groupPedidosByEtapa, summarizeReportes } from "@/lib/reportes/domain";
import { PIPELINE_ETAPAS, PIPELINE_LABELS } from "@/lib/pedidos/pipeline";
import { money } from "@/lib/format";
import { cn } from "@/lib/cn";
import type { Pedido } from "@/lib/types/pedido";
import type { Pago } from "@/lib/types/pago";

function getDatesOfISOWeek(weekNumber: number, year: number) {
  const simple = new Date(year, 0, 1 + (weekNumber - 1) * 7);
  const dayOfWeek = simple.getDay();
  const ISOweekStart = new Date(simple);
  if (dayOfWeek <= 4) {
    ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
  } else {
    ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
  }
  const ISOweekEnd = new Date(ISOweekStart);
  ISOweekEnd.setDate(ISOweekStart.getDate() + 6);
  
  ISOweekStart.setHours(0, 0, 0, 0);
  ISOweekEnd.setHours(23, 59, 59, 999);
  
  return { start: ISOweekStart, end: ISOweekEnd };
}

type TipoFiltro = "todos" | "mes" | "semana" | "personalizado";

const ETAPA_PROGRESS_COLORS: Record<string, string> = {
  pedido_nuevo: "bg-slate-400",
  para_medir: "bg-amber-400",
  para_cortar: "bg-orange-400",
  cortando: "bg-sky-500",
  cortado: "bg-blue-600",
  armando: "bg-white border border-line",
  terminado: "bg-teal-500",
  para_instalar: "bg-purple-500",
  entregado_con_saldo: "bg-emerald-500",
  entregado_sin_saldo: "bg-green-600",
};

export default function ReportesPage() {
  const [pedidos, setPedidos] = useState<Pedido[]>([]);
  const [pagos, setPagos] = useState<Pago[]>([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState("");

  const [tipoFiltro, setTipoFiltro] = useState<TipoFiltro>("todos");
  const [filtroMes, setFiltroMes] = useState<string>(() => {
    const today = new Date();
    return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}`;
  });
  const [filtroSemana, setFiltroSemana] = useState<number>(() => {
    // Intentar estimar la semana actual del año
    const today = new Date();
    const startOfYear = new Date(today.getFullYear(), 0, 1);
    const pastDays = (today.getTime() - startOfYear.getTime()) / 86400000;
    return Math.ceil((pastDays + startOfYear.getDay() + 1) / 7);
  });
  const [fechaDesde, setFechaDesde] = useState<string>("");
  const [fechaHasta, setFechaHasta] = useState<string>("");

  async function load() {
    setLoading(true);
    setErr("");
    try {
      const [pedidosRes, pagosRes] = await Promise.all([
        listPedidos({ perPage: 1000 }), // Cargar mas para reportes
        listPagos(),
      ]);
      setPedidos(pedidosRes.items);
      setPagos(pagosRes);
    } catch (e) {
      setErr((e as Error).message || "No se pudieron cargar reportes");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    load();
  }, []);

  const opcionesMeses = useMemo(() => {
    const list = [];
    const today = new Date();
    for (let i = 0; i < 24; i++) {
      const d = new Date(today.getFullYear(), today.getMonth() - i, 1);
      const val = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
      const label = d.toLocaleDateString("es-AR", { month: "long", year: "numeric" });
      list.push({ val, label: label.charAt(0).toUpperCase() + label.slice(1) });
    }
    return list;
  }, []);

  const opcionesSemanas = useMemo(() => {
    const list = [];
    const year = new Date().getFullYear();
    for (let i = 1; i <= 53; i++) {
      const { start, end } = getDatesOfISOWeek(i, year);
      const rango = `${start.getDate()}/${start.getMonth() + 1} al ${end.getDate()}/${end.getMonth() + 1}`;
      list.push({ semana: i, rango });
    }
    return list;
  }, []);

  const filteredData = useMemo(() => {
    let start: Date | null = null;
    let end: Date | null = null;

    if (tipoFiltro === "mes" && filtroMes) {
      const [y, m] = filtroMes.split("-").map(Number);
      start = new Date(y, m - 1, 1, 0, 0, 0, 0);
      end = new Date(y, m, 0, 23, 59, 59, 999);
    } else if (tipoFiltro === "semana" && filtroSemana) {
      const year = new Date().getFullYear();
      const res = getDatesOfISOWeek(filtroSemana, year);
      start = res.start;
      end = res.end;
    } else if (tipoFiltro === "personalizado") {
      if (fechaDesde) {
        start = new Date(fechaDesde + "T00:00:00");
      }
      if (fechaHasta) {
        end = new Date(fechaHasta + "T23:59:59.999");
      }
    }

    const filteredPedidos = pedidos.filter((p) => {
      if (!p.fecha_creacion) return false;
      const t = new Date(p.fecha_creacion).getTime();
      if (start && t < start.getTime()) return false;
      if (end && t > end.getTime()) return false;
      return true;
    });

    const filteredPagos = pagos.filter((p) => {
      if (!p.fecha) return false;
      const t = new Date(p.fecha + "T12:00:00").getTime();
      if (start && t < start.getTime()) return false;
      if (end && t > end.getTime()) return false;
      return true;
    });

    return { pedidos: filteredPedidos, pagos: filteredPagos };
  }, [pedidos, pagos, tipoFiltro, filtroMes, filtroSemana, fechaDesde, fechaHasta]);

  const resumen = useMemo(() => summarizeReportes(filteredData.pedidos, filteredData.pagos), [filteredData]);
  const porEtapa = useMemo(() => groupPedidosByEtapa(filteredData.pedidos), [filteredData.pedidos]);
  const porCuenta = useMemo(() => groupPagosByCuenta(filteredData.pagos), [filteredData.pagos]);

  const maxEtapa = useMemo(() => {
    const vals = Object.values(porEtapa);
    return vals.length > 0 ? Math.max(...vals, 1) : 1;
  }, [porEtapa]);

  const maxCuenta = useMemo(() => {
    const vals = Object.values(porCuenta);
    return vals.length > 0 ? Math.max(...vals, 1) : 1;
  }, [porCuenta]);

  return (
    <div className="max-w-6xl space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-2xl font-extrabold text-ink">
            <BarChart3 className="h-6 w-6 text-brand-dark" /> Reportes
          </h1>
          <p className="text-sm text-ink-soft">Caja, saldos y produccion sin contabilidad dura.</p>
        </div>
        <Button type="button" variant="secondary" onClick={load} loading={loading}>
          <RefreshCw size={16} /> Actualizar
        </Button>
      </div>

      {/* Bar de Filtros */}
      <div className="card p-4 grid gap-3 md:grid-cols-4 items-end">
        <div>
          <label className="text-sm font-medium text-ink-soft block mb-1.5">Filtrar por</label>
          <select
            value={tipoFiltro}
            onChange={(e) => setTipoFiltro(e.target.value as TipoFiltro)}
            className="w-full h-11 px-3 rounded-xl border border-line bg-surface text-sm text-ink outline-none focus:border-brand"
          >
            <option value="todos">Todo el historial</option>
            <option value="mes">Mes específico</option>
            <option value="semana">Semana del año</option>
            <option value="personalizado">Rango de fechas</option>
          </select>
        </div>

        {tipoFiltro === "mes" && (
          <div>
            <label className="text-sm font-medium text-ink-soft block mb-1.5">Seleccionar Mes</label>
            <select
              value={filtroMes}
              onChange={(e) => setFiltroMes(e.target.value)}
              className="w-full h-11 px-3 rounded-xl border border-line bg-surface text-sm text-ink outline-none focus:border-brand"
            >
              {opcionesMeses.map((opt) => (
                <option key={opt.val} value={opt.val}>{opt.label}</option>
              ))}
            </select>
          </div>
        )}

        {tipoFiltro === "semana" && (
          <div>
            <label className="text-sm font-medium text-ink-soft block mb-1.5">Seleccionar Semana</label>
            <select
              value={filtroSemana}
              onChange={(e) => setFiltroSemana(Number(e.target.value))}
              className="w-full h-11 px-3 rounded-xl border border-line bg-surface text-sm text-ink outline-none focus:border-brand font-mono text-xs"
            >
              {opcionesSemanas.map((opt) => (
                <option key={opt.semana} value={opt.semana}>
                  Semana {opt.semana} ({opt.rango})
                </option>
              ))}
            </select>
          </div>
        )}

        {tipoFiltro === "personalizado" && (
          <>
            <div>
              <label className="text-sm font-medium text-ink-soft block mb-1.5">Desde</label>
              <input
                type="date"
                value={fechaDesde}
                onChange={(e) => setFechaDesde(e.target.value)}
                className="w-full h-11 px-3 rounded-xl border border-line bg-surface text-sm text-ink outline-none focus:border-brand"
              />
            </div>
            <div>
              <label className="text-sm font-medium text-ink-soft block mb-1.5">Hasta</label>
              <input
                type="date"
                value={fechaHasta}
                onChange={(e) => setFechaHasta(e.target.value)}
                className="w-full h-11 px-3 rounded-xl border border-line bg-surface text-sm text-ink outline-none focus:border-brand"
              />
            </div>
          </>
        )}
      </div>

      {err && <div className="rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-bad">{err}</div>}
      {loading ? (
        <div className="grid place-items-center py-20 text-faint"><Loader2 className="h-6 w-6 animate-spin" /></div>
      ) : (
        <>
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
            <Metric label="Ventas cargadas" value={money(resumen.ventas)} />
            <Metric label="Cobrado" value={money(resumen.cobrado)} />
            <Metric label="Saldo pendiente" value={money(resumen.saldoPendiente)} tone={resumen.saldoPendiente > 0 ? "bad" : "good"} />
            <Metric label="Pedidos activos" value={String(resumen.pedidosActivos)} />
          </div>

          <div className="grid gap-4 lg:grid-cols-2">
            <section className="rounded-xl border border-line bg-surface p-4 shadow-sm">
              <h2 className="mb-4 font-extrabold text-ink text-sm uppercase tracking-wide">Producción por Etapa</h2>
              <div className="space-y-3">
                {PIPELINE_ETAPAS.map((etapa) => {
                  const qty = porEtapa[etapa] || 0;
                  const pct = Math.max(2, (qty / maxEtapa) * 100);
                  const colorClass = ETAPA_PROGRESS_COLORS[etapa] || "bg-brand";
                  return (
                    <div key={etapa} className="space-y-1.5 p-1 rounded-lg hover:bg-canvas/40 transition-colors">
                      <div className="flex items-center justify-between text-xs font-semibold">
                        <span className="text-ink-soft">{PIPELINE_LABELS[etapa]}</span>
                        <span className="text-ink font-bold">{qty}</span>
                      </div>
                      <div className="w-full bg-canvas/60 rounded-full h-2.5 overflow-hidden border border-line/40">
                        <div 
                          className={cn("h-full rounded-full transition-all duration-500", colorClass)} 
                          style={{ width: `${pct}%` }} 
                        />
                      </div>
                    </div>
                  );
                })}
              </div>
            </section>
            <section className="rounded-xl border border-line bg-surface p-4 shadow-sm">
              <h2 className="mb-4 font-extrabold text-ink text-sm uppercase tracking-wide">Ingresos por Cuenta</h2>
              <div className="space-y-3">
                {Object.entries(porCuenta).length === 0 ? (
                  <p className="text-sm text-faint p-2">Sin pagos cargados en este periodo.</p>
                ) : Object.entries(porCuenta).map(([cuenta, total]) => {
                  const pct = Math.max(2, (total / maxCuenta) * 100);
                  return (
                    <div key={cuenta} className="space-y-1.5 p-1 rounded-lg hover:bg-canvas/40 transition-colors">
                      <div className="flex items-center justify-between text-xs font-semibold">
                        <span className="text-ink-soft font-bold">{cuenta}</span>
                        <span className="text-ink font-extrabold">{money(total)}</span>
                      </div>
                      <div className="w-full bg-canvas/60 rounded-full h-2.5 overflow-hidden border border-line/40">
                        <div 
                          className="h-full rounded-full bg-emerald-500 transition-all duration-500" 
                          style={{ width: `${pct}%` }} 
                        />
                      </div>
                    </div>
                  );
                })}
              </div>
            </section>
          </div>
        </>
      )}
    </div>
  );
}

function Metric({ label, value, tone = "ink" }: { label: string; value: string; tone?: "ink" | "bad" | "good" }) {
  return (
    <div className="rounded-xl border border-line bg-surface p-4">
      <p className="text-xs font-bold uppercase tracking-wide text-faint">{label}</p>
      <p className={tone === "bad" ? "mt-1 text-2xl font-extrabold text-bad" : tone === "good" ? "mt-1 text-2xl font-extrabold text-good" : "mt-1 text-2xl font-extrabold text-ink"}>{value}</p>
    </div>
  );
}

function Row({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex items-center justify-between gap-3 rounded-lg bg-canvas px-3 py-2 text-sm">
      <span className="font-semibold text-ink-soft">{label}</span>
      <span className="font-extrabold text-ink">{value}</span>
    </div>
  );
}
