"use client";

/*
 * Painéis: telas de números que a própria empresa monta.
 *
 * A lista segue o padrão de lista da casa (busca, contadores de relance, linha
 * corrida). Criar abre um modal com nome e um modelo para não começar do zero;
 * os quadros são escolhidos dentro do painel. O assistente cria e altera os
 * mesmos painéis pelas ferramentas de lib/assistentes/ferramentas/paineis.ts.
 */

import { useCallback, useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { ChevronRight, LayoutDashboard, Loader2, Plus, Search, Sparkles, Trash2 } from "lucide-react";

import CaixaDeConfirmacao, { type Confirmacao } from "@/components/ui/caixa-de-confirmacao";
import { Aviso } from "@/components/ui/aviso";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { PageHeader } from "@/components/ui/page-header";
import { chamar, MODELOS, type MetricaDoCatalogo } from "@/components/paineis/comum";

type ItemDaLista = { id: string; nome: string; descricao: string | null; quadros: number; metricas: string[]; atualizado_em: string };

const VIVOS = [
  "bg-gradient-to-br from-violet-500 to-purple-600",
  "bg-gradient-to-br from-sky-500 to-blue-600",
  "bg-gradient-to-br from-emerald-500 to-teal-600",
  "bg-gradient-to-br from-amber-400 to-orange-500",
  "bg-gradient-to-br from-rose-500 to-pink-600",
  "bg-gradient-to-br from-indigo-500 to-violet-600",
];

function quando(iso: string) {
  const data = new Date(iso);
  if (Number.isNaN(data.getTime())) return "";
  return data.toLocaleDateString("pt-BR", { day: "2-digit", month: "short", year: "numeric" });
}

export default function PaineisPage() {
  const router = useRouter();
  const [paineis, setPaineis] = useState<ItemDaLista[]>([]);
  const [metricas, setMetricas] = useState<MetricaDoCatalogo[]>([]);
  const [podeEditar, setPodeEditar] = useState(false);
  const [carregando, setCarregando] = useState(true);
  const [erro, setErro] = useState<string | null>(null);
  const [busca, setBusca] = useState("");

  const [criando, setCriando] = useState(false);
  const [nome, setNome] = useState("");
  const [descricao, setDescricao] = useState("");
  const [modelo, setModelo] = useState("vendas");
  const [salvando, setSalvando] = useState(false);
  const [erroDoForm, setErroDoForm] = useState<string | null>(null);

  const [confirmacao, setConfirmacao] = useState<Confirmacao | null>(null);
  const [ocupado, setOcupado] = useState(false);

  const carregar = useCallback(async () => {
    setCarregando(true);
    setErro(null);
    try {
      const r = await chamar<{ paineis: ItemDaLista[]; podeEditar: boolean; metricas: MetricaDoCatalogo[] }>("/api/paineis");
      setPaineis(r.paineis);
      setPodeEditar(r.podeEditar);
      setMetricas(r.metricas);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível carregar os painéis.");
    } finally {
      setCarregando(false);
    }
  }, []);

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

  const rotuloDaMetrica = useMemo(() => new Map(metricas.map((m) => [m.id, m.rotulo])), [metricas]);

  const filtrados = useMemo(() => {
    const termo = busca.trim().toLowerCase();
    if (!termo) return paineis;
    return paineis.filter((p) => `${p.nome} ${p.descricao ?? ""}`.toLowerCase().includes(termo));
  }, [paineis, busca]);

  const totalDeQuadros = paineis.reduce((s, p) => s + p.quadros, 0);

  const abrirCriar = () => {
    setNome("");
    setDescricao("");
    setModelo("vendas");
    setErroDoForm(null);
    setCriando(true);
  };

  const criar = async () => {
    setSalvando(true);
    setErroDoForm(null);
    try {
      const escolhido = MODELOS.find((m) => m.id === modelo);
      const r = await chamar<{ painel: { id: string } }>("/api/paineis", {
        method: "POST",
        body: JSON.stringify({ nome: nome.trim() || escolhido?.nome || "Meu painel", descricao, widgets: escolhido?.widgets ?? [] }),
      });
      router.push(`/dashboard/paineis/${r.painel.id}${modelo === "vazio" ? "?editar=1" : ""}`);
    } catch (e) {
      setErroDoForm(e instanceof Error ? e.message : "Não foi possível criar.");
      setSalvando(false);
    }
  };

  const pedirExclusao = (painel: ItemDaLista) =>
    setConfirmacao({
      titulo: `Excluir o painel "${painel.nome}"?`,
      texto: "O painel some para toda a equipe. Nenhum pedido, orçamento ou lançamento é apagado.",
      confirmar: "Excluir painel",
      tom: "perigo",
      aoConfirmar: async () => {
        setOcupado(true);
        try {
          await chamar(`/api/paineis/${painel.id}`, { method: "DELETE" });
          setPaineis((lista) => lista.filter((p) => p.id !== painel.id));
          setConfirmacao(null);
        } catch (e) {
          setErro(e instanceof Error ? e.message : "Não foi possível excluir.");
          setConfirmacao(null);
        } finally {
          setOcupado(false);
        }
      },
    });

  return (
    <div className="ks-page ks-page-wide space-y-6">
      <PageHeader eyebrow="Relatórios" title="Painéis" subtitle="Monte telas com os números que importam para a sua gráfica. Também dá para pedir ao assistente." />

      {erro ? (
        <Aviso tom="ruim" aoFechar={() => setErro(null)}>
          {erro}
        </Aviso>
      ) : null}

      <div className="ks-surface overflow-hidden rounded-xl border border-[var(--ks-color-border-subtle)] shadow-sm">
        <div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-subtle)]/30 p-4">
          <div className="relative min-w-[200px] max-w-xs flex-1">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
            <Input placeholder="Buscar painel..." value={busca} onChange={(e) => setBusca(e.target.value)} className="pl-9" />
          </div>
          <div className="flex flex-wrap items-center gap-4">
            <div className="flex items-center gap-4 text-xs font-medium text-slate-500">
              <span className="flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-[var(--ks-color-primary)]" />
                <span className="ks-num">{paineis.length}</span> painéis
              </span>
              <span className="flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-sky-500" />
                <span className="ks-num">{totalDeQuadros}</span> quadros
              </span>
            </div>
            {podeEditar ? (
              <button type="button" className="ks-button ks-button-primary" onClick={abrirCriar}>
                <Plus className="h-4 w-4" />
                Novo painel
              </button>
            ) : null}
          </div>
        </div>

        {carregando ? (
          <div className="flex justify-center py-16">
            <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
          </div>
        ) : filtrados.length === 0 ? (
          <div className="flex flex-col items-center justify-center px-6 py-16 text-center">
            <span className="mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_10px_24px_rgba(124,58,237,0.32)]">
              <LayoutDashboard className="h-7 w-7" />
            </span>
            <h3 className="text-lg font-semibold text-slate-900">{busca ? "Nenhum painel com esse nome" : "Nenhum painel ainda"}</h3>
            <p className="mb-5 mt-1 max-w-md text-sm text-slate-500">
              Junte faturamento, vendedores, produção atrasada e contas num lugar só. Comece por um modelo e ajuste os quadros, ou peça ao assistente:
              &quot;monte um painel com o faturamento por vendedor deste mês&quot;.
            </p>
            {podeEditar && !busca ? (
              <button type="button" className="ks-button ks-button-primary" onClick={abrirCriar}>
                <Plus className="h-4 w-4" />
                Criar o primeiro painel
              </button>
            ) : null}
          </div>
        ) : (
          <div>
            <div className="hidden grid-cols-[minmax(0,1fr)_110px_130px_72px] gap-3 px-6 py-3 text-[10px] font-semibold uppercase tracking-[0.14em] text-slate-400 md:grid">
              <span>Painel</span>
              <span>Quadros</span>
              <span>Atualizado</span>
              <span />
            </div>
            {filtrados.map((painel, i) => (
              <div
                key={painel.id}
                onClick={() => router.push(`/dashboard/paineis/${painel.id}`)}
                className="grid cursor-pointer grid-cols-[minmax(0,1fr)_auto] items-center gap-3 border-t border-slate-100/60 px-4 py-3.5 transition-colors hover:bg-[var(--ks-color-bg-subtle)]/50 md:grid-cols-[minmax(0,1fr)_110px_130px_72px] md:px-6"
              >
                <div className="flex min-w-0 items-center gap-3">
                  <span className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl text-white shadow-sm ${VIVOS[i % VIVOS.length]}`}>
                    <LayoutDashboard className="h-5 w-5" />
                  </span>
                  <div className="min-w-0">
                    <p className="truncate font-semibold text-slate-900">{painel.nome}</p>
                    <p className="truncate text-xs text-slate-500">
                      {painel.descricao || painel.metricas.map((m) => rotuloDaMetrica.get(m) ?? m).slice(0, 4).join(" · ") || "Sem quadros ainda"}
                    </p>
                  </div>
                </div>
                <span className="hidden text-sm text-slate-600 md:block">
                  <span className="ks-num font-semibold text-slate-900">{painel.quadros}</span> {painel.quadros === 1 ? "quadro" : "quadros"}
                </span>
                <span className="hidden text-sm text-slate-500 md:block">{quando(painel.atualizado_em)}</span>
                <div className="flex items-center justify-end gap-1">
                  {podeEditar ? (
                    <button
                      type="button"
                      title="Excluir painel"
                      className="ks-button ks-button-ghost ks-button-icon ks-button-sm text-slate-400 hover:text-rose-600"
                      onClick={(e) => {
                        e.stopPropagation();
                        pedirExclusao(painel);
                      }}
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  ) : null}
                  <ChevronRight className="h-4 w-4 text-slate-300" />
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <Dialog open={criando} onOpenChange={(abrir) => (!abrir && !salvando ? setCriando(false) : undefined)}>
        <DialogContent className="max-h-[88vh] w-[94vw] max-w-xl overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Novo painel</DialogTitle>
            <DialogDescription>Dê um nome e escolha por onde começar. Os quadros podem ser trocados depois.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <Input label="Nome" placeholder={MODELOS.find((m) => m.id === modelo)?.nome ?? "Meu painel"} value={nome} maxLength={80} onChange={(e) => setNome(e.target.value)} />
            <Input label="Para que serve (opcional)" value={descricao} maxLength={400} onChange={(e) => setDescricao(e.target.value)} />
            <div>
              <p className="ks-input-label mb-2">Começar com</p>
              <div className="grid gap-2 sm:grid-cols-2">
                {MODELOS.map((m) => {
                  const ativo = modelo === m.id;
                  return (
                    <button
                      key={m.id}
                      type="button"
                      onClick={() => setModelo(m.id)}
                      className={`flex items-start gap-3 rounded-xl border px-3 py-3 text-left transition ${
                        ativo ? "border-[#7C3AED] bg-white shadow-[0_0_0_3px_rgba(124,58,237,0.14)]" : "border-slate-200 bg-white hover:border-slate-300"
                      }`}
                    >
                      <span
                        className={`mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg ${
                          ativo ? "bg-gradient-to-br from-violet-500 to-purple-600 text-white" : "bg-slate-100 text-slate-500"
                        }`}
                      >
                        {m.id === "vazio" ? <Plus className="h-4 w-4" /> : <Sparkles className="h-4 w-4" />}
                      </span>
                      <span className="min-w-0">
                        <span className="block text-sm font-semibold text-slate-900">{m.nome}</span>
                        <span className="block text-xs text-slate-500">{m.descricao}</span>
                      </span>
                    </button>
                  );
                })}
              </div>
            </div>
            {erroDoForm ? <p className="rounded-lg bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700">{erroDoForm}</p> : null}
          </div>
          <DialogFooter className="mt-2">
            <button type="button" className="ks-button ks-button-ghost" onClick={() => setCriando(false)} disabled={salvando}>
              Cancelar
            </button>
            <button type="button" className="ks-button ks-button-primary" onClick={criar} disabled={salvando}>
              {salvando ? "Criando..." : "Criar painel"}
            </button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <CaixaDeConfirmacao pedido={confirmacao} ocupado={ocupado} aoFechar={() => (!ocupado ? setConfirmacao(null) : undefined)} />
    </div>
  );
}
