import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { LayoutDashboard, Loader2, RefreshCw } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { useAuthAccess } from "@/contexts/AuthAccessContext";
import {
  dashboardPontosPorClienteService,
  type DashboardPontosPorParceiro,
} from "@/services/fechamento/dashboardPontosPorCliente";
import { fechamentoParceirosService, type ParceiroItem } from "@/services/fechamento/parceiros";

function formatPontos(valor: number): string {
  return valor.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 4 });
}

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

function hojeIsoDate(): string {
  const d = new Date();
  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}`;
}

export default function DashboardPontos() {
  const { papel, me } = useAuthAccess();
  const [parceiros, setParceiros] = useState<ParceiroItem[]>([]);
  const [dataInicio, setDataInicio] = useState(primeiroDiaMesAtual);
  const [dataFim, setDataFim] = useState(hojeIsoDate);
  const [parceiroId, setParceiroId] = useState<string>("all");
  const [cliente, setCliente] = useState("");
  const [loading, setLoading] = useState(true);
  const [dados, setDados] = useState<DashboardPontosPorParceiro[]>([]);
  const clienteRef = useRef(cliente);
  clienteRef.current = cliente;

  const parceiroFixoSupervisor = papel === "supervisor" && me?.parceiroId;

  const loadParceiros = useCallback(async () => {
    if (parceiroFixoSupervisor && me?.parceiroId) {
      try {
        const res = await fechamentoParceirosService.listarParceiros({
          estaAtivo: "all",
          page: 1,
          perPage: 200,
        });
        const um = res.data.find((p) => p.id === me.parceiroId);
        setParceiros(um ? [um] : []);
        setParceiroId(me.parceiroId);
      } catch (e) {
        const message = e instanceof Error ? e.message : "Erro ao carregar parceiros.";
        toast.error(message);
        setParceiros([]);
        setParceiroId(me.parceiroId);
      }
      return;
    }
    try {
      const lista = await fechamentoParceirosService.listarParceirosAtivos();
      setParceiros(lista);
    } catch (e) {
      const message = e instanceof Error ? e.message : "Erro ao carregar parceiros.";
      toast.error(message);
      setParceiros([]);
    }
  }, [me?.parceiroId, parceiroFixoSupervisor]);

  const loadRelatorio = useCallback(async () => {
    try {
      setLoading(true);
      const pid =
        parceiroFixoSupervisor && me?.parceiroId
          ? me.parceiroId
          : parceiroId === "all"
            ? undefined
            : parceiroId;
      const res = await dashboardPontosPorClienteService.relatorioPontosPorCliente({
        dataInicio: dataInicio.trim() || undefined,
        dataFim: dataFim.trim() || undefined,
        parceiroId: pid,
        cliente: clienteRef.current.trim() || undefined,
      });
      setDados(res);
    } catch (e) {
      const message = e instanceof Error ? e.message : "Erro ao carregar dashboard.";
      toast.error(message);
      setDados([]);
    } finally {
      setLoading(false);
    }
  }, [dataFim, dataInicio, me?.parceiroId, parceiroFixoSupervisor, parceiroId]);

  useEffect(() => {
    void loadParceiros();
  }, [loadParceiros]);

  useEffect(() => {
    void loadRelatorio();
  }, [dataFim, dataInicio, loadRelatorio, parceiroId, me?.parceiroId, papel]);

  const totalGeral = useMemo(
    () => dados.reduce((acc, p) => acc + p.totalParceiro, 0),
    [dados],
  );

  return (
    <div className="mx-auto max-w-6xl space-y-6 p-4 pb-10 lg:p-8">
      <div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <h1 className="flex items-center gap-2 text-2xl font-semibold tracking-tight">
            <LayoutDashboard className="h-7 w-7 text-primary" />
            Dashboard
          </h1>
          <p className="text-muted-foreground">
            Pontos alocados por cliente (tarefas revisadas), por parceiro.
          </p>
        </div>
        <Button type="button" variant="outline" size="sm" className="gap-2 self-start" onClick={() => void loadRelatorio()}>
          <RefreshCw className="h-4 w-4" />
          Atualizar
        </Button>
      </div>

      <Card>
        <CardHeader className="pb-4">
          <CardTitle className="text-lg">Filtros</CardTitle>
          <CardDescription>Período por data de conclusão da tarefa, ou data de criação se ainda não concluída.</CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
          <div className="space-y-2">
            <Label htmlFor="dash-data-ini">Data início</Label>
            <Input
              id="dash-data-ini"
              type="date"
              value={dataInicio}
              onChange={(e) => setDataInicio(e.target.value)}
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="dash-data-fim">Data fim</Label>
            <Input id="dash-data-fim" type="date" value={dataFim} onChange={(e) => setDataFim(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label>Parceiro</Label>
            <Select
              value={parceiroId}
              onValueChange={setParceiroId}
              disabled={Boolean(parceiroFixoSupervisor)}
            >
              <SelectTrigger>
                <SelectValue placeholder="Todos" />
              </SelectTrigger>
              <SelectContent>
                {!parceiroFixoSupervisor ? (
                  <SelectItem value="all">Todos os parceiros</SelectItem>
                ) : null}
                {parceiroFixoSupervisor && parceiros.length === 0 && me?.parceiroId ? (
                  <SelectItem value={me.parceiroId}>Parceiro vinculado</SelectItem>
                ) : null}
                {parceiros.map((p) => (
                  <SelectItem key={p.id} value={p.id}>
                    {p.codinome?.trim() ? `${p.nome} (${p.codinome.trim()})` : p.nome}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="dash-cliente">Cliente (contém)</Label>
            <Input
              id="dash-cliente"
              placeholder="Nome do cliente"
              value={cliente}
              onChange={(e) => setCliente(e.target.value)}
            />
          </div>
        </CardContent>
        <CardContent className="pt-0">
          <Button type="button" onClick={() => void loadRelatorio()}>
            Aplicar filtros
          </Button>
        </CardContent>
      </Card>

      <Card>
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <div>
            <CardTitle className="text-lg">Resumo</CardTitle>
            <CardDescription>Soma dos pontos no período e filtros atuais.</CardDescription>
          </div>
          {loading ? (
            <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
          ) : (
            <span className="text-lg font-semibold tabular-nums">{formatPontos(totalGeral)} pts</span>
          )}
        </CardHeader>
      </Card>

      {loading && dados.length === 0 ? (
        <div className="flex justify-center py-16">
          <Loader2 className="h-10 w-10 animate-spin text-muted-foreground" />
        </div>
      ) : dados.length === 0 ? (
        <Card>
          <CardContent className="py-12 text-center text-muted-foreground">
            Nenhum dado para os filtros selecionados.
          </CardContent>
        </Card>
      ) : (
        <div className="space-y-6">
          {dados.map((bloco) => (
            <Card key={bloco.parceiroId}>
              <CardHeader className="pb-2">
                <div className="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between">
                  <CardTitle className="text-base">{bloco.parceiroNome}</CardTitle>
                  <span className="text-sm font-medium text-muted-foreground tabular-nums">
                    Total: {formatPontos(bloco.totalParceiro)} pts
                  </span>
                </div>
              </CardHeader>
              <CardContent className="pt-0">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Cliente</TableHead>
                      <TableHead className="text-right">Pontos</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {bloco.linhas.map((linha) => (
                      <TableRow key={`${bloco.parceiroId}-${linha.cliente}`}>
                        <TableCell>{linha.cliente}</TableCell>
                        <TableCell className="text-right tabular-nums">{formatPontos(linha.pontos)}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}
