"use client";

import { useEffect, useRef, useState, type ComponentType, type ReactNode } from "react";
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { AlertTriangle, ChartColumn, CircleDollarSign, FileBadge2, Home, Info, Users } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { semanticBadgeClass } from "@/lib/badge-variants";
import {
  CHART_SERIES_COLORS,
  rechartsAxisTick,
  rechartsCartesianGrid,
  rechartsLegendProps,
  rechartsTooltipProps,
  tramoRshChartColor,
} from "@/lib/chart-theme";
import type { AlertTone } from "@/lib/semantic-tokens";
import {
  badgeClassForAlert,
  badgeClassForEstadoFicha,
  surfaceClassForAlertTone,
} from "@/lib/state-variants";
import { cn } from "@/lib/utils";
import type { ReportesData } from "@/server/queries/reportes";

type MeasuredSize = {
  width: number;
  height: number;
};

export function ReportesDashboard({ data }: { data: ReportesData }) {
  const kpis = [
    { label: "Total fichas", value: data.stats.totalFichas, icon: Home },
    { label: "Total ocupantes", value: data.stats.totalOcupantes, icon: Users },
    { label: "Fichas completas", value: data.stats.fichasCompletas, icon: FileBadge2 },
    { label: "Fichas en revisión", value: data.stats.fichasEnRevision, icon: ChartColumn },
    { label: "Fichas incompletas", value: data.stats.fichasIncompletas, icon: AlertTriangle },
    { label: "Documentos pendientes", value: data.stats.documentosPendientes, icon: Info },
    { label: "Adultos mayores", value: data.stats.adultosMayores, icon: Users },
    { label: "Menores de edad", value: data.stats.menoresEdad, icon: Users },
    { label: "Vulnerabilidad promedio", value: `${Math.round(data.stats.vulnerabilityAverage)}%`, icon: CircleDollarSign },
  ];

  const vulnerabilityPercent = Math.max(0, Math.min(100, Math.round(data.stats.vulnerabilityAverage)));

  return (
    <div className="space-y-6">
      {data.filtersApplied.length > 0 ? (
        <Card className="border-border shadow-sm">
          <CardContent className="flex flex-wrap items-center gap-2 p-4">
            <span className="text-sm font-medium text-muted-foreground">Filtros activos:</span>
            {data.filtersApplied.map((item) => (
              <Badge key={item} className={semanticBadgeClass("neutral", { shape: "pill" })}>
                {item}
              </Badge>
            ))}
          </CardContent>
        </Card>
      ) : null}

      <section className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
        {kpis.map((item) => (
          <MetricCard key={item.label} label={item.label} value={item.value} icon={item.icon} />
        ))}
      </section>

      <section className="grid gap-4 xl:grid-cols-[1.15fr_0.85fr]">
        <Card className="border-border shadow-sm">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <ChartColumn className="h-5 w-5 text-muted-foreground" />
              Vulnerabilidad promedio del sector
            </CardTitle>
          </CardHeader>
          <CardContent className="grid gap-6 lg:grid-cols-[220px_1fr]">
            <div className="flex flex-col items-center justify-center rounded-2xl border border-border bg-muted p-4">
              <div className="text-4xl font-semibold text-foreground">{vulnerabilityPercent}%</div>
              <p className="mt-1 text-sm text-muted-foreground">{data.stats.vulnerabilityLevel}</p>
              <div className="mt-4 h-3 w-full overflow-hidden rounded-full bg-border">
                <div
                  className="h-full rounded-full"
                  style={{
                    width: `${vulnerabilityPercent}%`,
                    background: "linear-gradient(to right, var(--warning), var(--destructive))",
                  }}
                />
              </div>
            </div>

            <div className="space-y-4">
              {data.stats.totalFichas === 0 ? (
                <EmptyState text="No hay fichas para mostrar distribución de tramos RSH." />
              ) : (
                <>
                  <MeasuredChart className="h-[260px]">
                    {({ width, height }) => (
                      <ResponsiveContainer width={width} height={height}>
                        <PieChart>
                          <Pie
                            data={data.tramoDistribution}
                            dataKey="count"
                            nameKey="label"
                            innerRadius={70}
                            outerRadius={100}
                            paddingAngle={2}
                          >
                            {data.tramoDistribution.map((entry) => (
                              <Cell key={entry.value} fill={tramoRshChartColor(entry.value)} />
                            ))}
                          </Pie>
                          <Tooltip {...rechartsTooltipProps} />
                          <Legend {...rechartsLegendProps} />
                        </PieChart>
                      </ResponsiveContainer>
                    )}
                  </MeasuredChart>
                  <div className="grid gap-3 sm:grid-cols-2">
                    {data.tramoDistribution.map((item) => (
                      <div key={item.value} className="flex items-center justify-between rounded-xl border border-border bg-card px-3 py-2">
                        <div className="flex items-center gap-2">
                          <span className="h-3 w-3 rounded-full" style={{ backgroundColor: tramoRshChartColor(item.value) }} />
                          <span className="text-sm text-foreground">{item.label}</span>
                        </div>
                        <span className="text-sm font-medium text-foreground">{item.count}</span>
                      </div>
                    ))}
                  </div>
                </>
              )}
            </div>
          </CardContent>
        </Card>

        <Card className="border-border shadow-sm">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-muted-foreground" />
              Alertas prioritarias
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            {data.alerts.length === 0 ? (
              <EmptyState text="Sin alertas priorizadas para los filtros actuales." />
            ) : (
              data.alerts.map((alert) => (
                <div key={alert.title} className={cn(surfaceClassForAlertTone(alert.tone as AlertTone), "px-4 py-3")}>
                  <div className="flex items-start justify-between gap-3">
                    <div>
                      <p className="font-medium text-foreground">{alert.title}</p>
                      <p className="mt-1 text-sm text-muted-foreground">{alert.detail}</p>
                    </div>
                    <Badge className={badgeClassForAlert(alert.tone as AlertTone, { pill: true, ring: true })}>
                      {alert.value}
                    </Badge>
                  </div>
                </div>
              ))
            )}
          </CardContent>
        </Card>
      </section>

      <section className="grid gap-4 xl:grid-cols-2">
        <Card className="border-border shadow-sm">
          <CardHeader>
            <CardTitle>Estado de fichas</CardTitle>
          </CardHeader>
          <CardContent className="h-[320px]">
            {data.stats.totalFichas === 0 ? (
              <EmptyState text="No hay datos para graficar estados de fichas." />
            ) : (
              <MeasuredChart className="h-full">
                {({ width, height }) => (
                  <ResponsiveContainer width={width} height={height}>
                    <BarChart data={data.estadoFichaDistribution}>
                      <CartesianGrid {...rechartsCartesianGrid} />
                      <XAxis dataKey="label" tickLine={false} axisLine={false} tick={rechartsAxisTick} />
                      <YAxis allowDecimals={false} tickLine={false} axisLine={false} tick={rechartsAxisTick} />
                      <Tooltip {...rechartsTooltipProps} />
                      <Bar dataKey="count" radius={[8, 8, 0, 0]} fill="var(--chart-2)" />
                    </BarChart>
                  </ResponsiveContainer>
                )}
              </MeasuredChart>
            )}
          </CardContent>
        </Card>

        <Card className="border-border shadow-sm">
          <CardHeader>
            <CardTitle>Documentos</CardTitle>
          </CardHeader>
          <CardContent className="h-[320px]">
            {data.stats.totalFichas === 0 ? (
              <EmptyState text="No hay documentos para graficar." />
            ) : (
              <MeasuredChart className="h-full">
                {({ width, height }) => (
                  <ResponsiveContainer width={width} height={height}>
                    <BarChart data={data.documentoDistribution}>
                      <CartesianGrid {...rechartsCartesianGrid} />
                      <XAxis dataKey="label" tickLine={false} axisLine={false} tick={rechartsAxisTick} />
                      <YAxis allowDecimals={false} tickLine={false} axisLine={false} tick={rechartsAxisTick} />
                      <Tooltip {...rechartsTooltipProps} />
                      <Bar dataKey="count" radius={[8, 8, 0, 0]} fill="var(--chart-1)">
                        {data.documentoDistribution.map((entry, index) => (
                          <Cell key={entry.value} fill={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]} />
                        ))}
                      </Bar>
                    </BarChart>
                  </ResponsiveContainer>
                )}
              </MeasuredChart>
            )}
          </CardContent>
        </Card>
      </section>

      <section className="grid gap-4 xl:grid-cols-2">
        <RankingCard
          title="Manzanas con más fichas"
          rows={data.rankingFichas.slice(0, 6).map((item) => ({
            label: item.manzana,
            value: item.count,
            suffix: "fichas",
          }))}
        />
        <RankingCard
          title="Manzanas con mayor vulnerabilidad"
          rows={data.rankingVulnerabilidad.slice(0, 6).map((item) => ({
            label: item.manzana,
            value: `${Math.round(item.score)}%`,
            suffix: "promedio",
          }))}
        />
      </section>

      <Card className="border-border shadow-sm">
        <CardHeader>
          <CardTitle>Tabla territorial</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow className="bg-muted">
                  <TableHead>Manzana</TableHead>
                  <TableHead>Lote</TableHead>
                  <TableHead>Dirección</TableHead>
                  <TableHead>Ocupante</TableHead>
                  <TableHead>Teléfono</TableHead>
                  <TableHead>Estado</TableHead>
                  <TableHead>RSH</TableHead>
                  <TableHead className="text-right">Cantidad personas</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.territorialRows.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={8}>
                      <EmptyState text="No hay fichas para los filtros seleccionados." />
                    </TableCell>
                  </TableRow>
                ) : (
                  data.territorialRows.map((row) => (
                    <TableRow key={row.fichaId}>
                      <TableCell>{row.manzana}</TableCell>
                      <TableCell>{row.lote}</TableCell>
                      <TableCell className="max-w-[220px] truncate" title={row.direccion}>
                        {row.direccion}
                      </TableCell>
                      <TableCell className="max-w-[220px] truncate" title={row.ocupante}>
                        {row.ocupante}
                      </TableCell>
                      <TableCell>{row.telefono}</TableCell>
                      <TableCell>
                        <Badge className={badgeClassForEstadoFicha(row.estadoFicha)}>{row.estadoFichaLabel}</Badge>
                      </TableCell>
                      <TableCell>{row.tramoRshLabel}</TableCell>
                      <TableCell className="text-right font-medium">{row.cantidadPersonas}</TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      <section className="grid gap-4 lg:grid-cols-3">
        <SummaryCard title="Resumen del sector" value={data.generatedAt} detail="Reporte generado" icon={Info} />
        <SummaryCard title="Promedio personas por lote" value={data.stats.promedioPersonasPorLote.toFixed(1)} detail="Promedio territorial" icon={Users} />
        <SummaryCard title="Vulnerabilidad promedio" value={`${Math.round(data.stats.vulnerabilityAverage)}%`} detail={data.stats.vulnerabilityLevel} icon={CircleDollarSign} />
      </section>
    </div>
  );
}

function MeasuredChart({
  className,
  children,
}: {
  className: string;
  children: (size: MeasuredSize) => ReactNode;
}) {
  const ref = useRef<HTMLDivElement | null>(null);
  const [size, setSize] = useState<MeasuredSize | null>(null);

  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const updateSize = () => {
      const rect = element.getBoundingClientRect();
      const width = Math.floor(rect.width);
      const height = Math.floor(rect.height);

      if (width > 0 && height > 0) {
        setSize((current) => {
          if (current && current.width === width && current.height === height) {
            return current;
          }

          return { width, height };
        });
      }
    };

    updateSize();

    const observer = new ResizeObserver(updateSize);
    observer.observe(element);

    return () => observer.disconnect();
  }, []);

  return <div ref={ref} className={`w-full ${className}`}>{size ? children(size) : null}</div>;
}

function MetricCard({
  label,
  value,
  icon: Icon,
}: {
  label: string;
  value: number | string;
  icon: ComponentType<{ className?: string }>;
}) {
  return (
    <Card className="border-border shadow-sm">
      <CardContent className="flex items-center gap-4 p-5">
        <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-muted text-muted-foreground">
          <Icon className="h-5 w-5" />
        </div>
        <div>
          <p className="text-sm font-medium text-muted-foreground">{label}</p>
          <p className="text-2xl font-semibold text-foreground">{value}</p>
        </div>
      </CardContent>
    </Card>
  );
}

function RankingCard({
  title,
  rows,
}: {
  title: string;
  rows: Array<{ label: string; value: number | string; suffix: string }>;
}) {
  return (
    <Card className="border-border shadow-sm">
      <CardHeader>
        <CardTitle>{title}</CardTitle>
      </CardHeader>
      <CardContent className="space-y-3">
        {rows.length === 0 ? (
          <EmptyState text="Sin datos para el filtro actual." />
        ) : (
          rows.map((row, index) => (
            <div key={row.label} className="flex items-center justify-between rounded-2xl border border-border px-4 py-3">
              <div className="flex items-center gap-3">
                <Badge className={semanticBadgeClass("neutral", { shape: "pill" })}>#{index + 1}</Badge>
                <span className="font-medium text-foreground">{row.label}</span>
              </div>
              <div className="text-right">
                <p className="font-semibold text-foreground">{row.value}</p>
                <p className="text-xs text-muted-foreground">{row.suffix}</p>
              </div>
            </div>
          ))
        )}
      </CardContent>
    </Card>
  );
}

function SummaryCard({
  title,
  value,
  detail,
  icon: Icon,
}: {
  title: string;
  value: string;
  detail: string;
  icon: ComponentType<{ className?: string }>;
}) {
  return (
    <Card className="border-border shadow-sm">
      <CardContent className="flex items-center gap-4 p-5">
        <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-muted text-muted-foreground">
          <Icon className="h-5 w-5" />
        </div>
        <div>
          <p className="text-sm font-medium text-muted-foreground">{title}</p>
          <p className="text-base font-semibold text-foreground">{value}</p>
          <p className="text-xs text-muted-foreground">{detail}</p>
        </div>
      </CardContent>
    </Card>
  );
}

function EmptyState({ text }: { text: string }) {
  return (
    <p className="rounded-xl border border-dashed border-border px-4 py-6 text-center text-sm text-muted-foreground">
      {text}
    </p>
  );
}
