"use client";

import { useMemo, useState } from "react";
import { BarChart3, Hash, LineChart, PieChart, Table2 } from "lucide-react";

import { CustomSelect } from "@/components/ui/custom-select";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { CANAIS, ROTULO_DA_DIMENSAO, type Dimensao } from "@/lib/paineis/agregar";
import type { TipoDeWidget } from "@/lib/paineis/metricas";
import { PERIODOS, ROTULO_DO_PERIODO, type Periodo } from "@/lib/paineis/periodos";

import type { MetricaDoCatalogo, Widget } from "./comum";

const TIPOS: Array<{ id: TipoDeWidget; rotulo: string; Icone: typeof Hash }> = [
  { id: "numero", rotulo: "Número", Icone: Hash },
  { id: "barras", rotulo: "Barras", Icone: BarChart3 },
  { id: "linha", rotulo: "Linha", Icone: LineChart },
  { id: "pizza", rotulo: "Pizza", Icone: PieChart },
  { id: "tabela", rotulo: "Tabela", Icone: Table2 },
];

type Rascunho = {
  metrica: string;
  tipo: TipoDeWidget;
  periodo: Periodo;
  de: string;
  ate: string;
  agrupar_por: string;
  limite: string;
  titulo: string;
  canal: string;
};

function rascunhoDe(widget: Widget | null, metricas: MetricaDoCatalogo[]): Rascunho {
  const primeira = metricas[0];
  return {
    metrica: widget?.metrica ?? primeira?.id ?? "faturamento",
    tipo: widget?.tipo ?? primeira?.tipo_sugerido ?? "numero",
    periodo: widget?.periodo ?? "este_mes",
    de: widget?.de ?? "",
    ate: widget?.ate ?? "",
    agrupar_por: widget?.agrupar_por ?? "",
    limite: widget?.limite ? String(widget.limite) : "10",
    titulo: widget?.titulo ?? "",
    canal: widget?.filtros?.canal ?? "",
  };
}

export function FormularioDeQuadro({
  aberto,
  metricas,
  inicial,
  salvando,
  erro,
  aoSalvar,
  aoFechar,
}: {
  aberto: boolean;
  metricas: MetricaDoCatalogo[];
  inicial: Widget | null;
  salvando: boolean;
  erro: string | null;
  aoSalvar: (quadro: Partial<Widget>) => void;
  aoFechar: () => void;
}) {
  const [r, setR] = useState<Rascunho>(() => rascunhoDe(inicial, metricas));
  const metrica = useMemo(() => metricas.find((m) => m.id === r.metrica) ?? null, [metricas, r.metrica]);

  const mudar = (parte: Partial<Rascunho>) => setR((atual) => ({ ...atual, ...parte }));

  const escolherMetrica = (id: string) => {
    const m = metricas.find((x) => x.id === id);
    if (!m) return;
    mudar({ metrica: id, tipo: m.tipos.includes(r.tipo) ? r.tipo : m.tipo_sugerido, agrupar_por: "", canal: m.filtros.includes("canal") ? r.canal : "" });
  };

  const dimensoesDoTipo = (metrica?.agrupar_por ?? []).filter((d) => (r.tipo === "pizza" ? d !== "tempo" : true));
  const pedeAgrupamento = r.tipo === "barras" || r.tipo === "pizza" || r.tipo === "tabela";
  const agrupamentoEfetivo = pedeAgrupamento ? r.agrupar_por || (r.tipo === "pizza" && metrica?.agrupar_padrao === "tempo" ? dimensoesDoTipo[0] : metrica?.agrupar_padrao) || "" : "";
  const pedeLimite = pedeAgrupamento && agrupamentoEfetivo && agrupamentoEfetivo !== "tempo";

  const salvar = () => {
    const limite = Number(String(r.limite).replace(/\D/g, ""));
    aoSalvar({
      ...(inicial ? { id: inicial.id } : {}),
      metrica: r.metrica,
      tipo: r.tipo,
      periodo: r.periodo,
      de: r.periodo === "personalizado" ? r.de : null,
      ate: r.periodo === "personalizado" ? r.ate : null,
      agrupar_por: pedeAgrupamento && r.agrupar_por ? (r.agrupar_por as Dimensao) : null,
      limite: pedeLimite && limite ? limite : null,
      titulo: r.titulo.trim(),
      filtros: r.canal ? { canal: r.canal as keyof typeof CANAIS } : null,
    });
  };

  return (
    <Dialog open={aberto} onOpenChange={(abrir) => (!abrir ? aoFechar() : undefined)}>
      <DialogContent className="max-h-[88vh] w-[94vw] max-w-xl overflow-y-auto">
        <DialogHeader>
          <DialogTitle>{inicial ? "Alterar quadro" : "Novo quadro"}</DialogTitle>
          <DialogDescription>Escolha o número, como ele aparece e de qual período.</DialogDescription>
        </DialogHeader>

        <div className="space-y-5">
          <CustomSelect
            label="O que mostrar"
            searchable
            value={r.metrica}
            onChange={escolherMetrica}
            options={metricas.map((m) => ({ value: m.id, label: m.rotulo, description: m.precisa_de_permissao_do_financeiro ? "Financeiro" : undefined }))}
          />
          {metrica ? <p className="-mt-3 text-xs leading-relaxed text-slate-500">{metrica.descricao}</p> : null}

          <div>
            <p className="ks-input-label mb-2">Como aparece</p>
            <div className="flex flex-wrap gap-2">
              {TIPOS.filter((t) => metrica?.tipos.includes(t.id)).map(({ id, rotulo, Icone }) => {
                const ativo = r.tipo === id;
                return (
                  <button
                    key={id}
                    type="button"
                    onClick={() => mudar({ tipo: id, agrupar_por: id === "pizza" && r.agrupar_por === "tempo" ? "" : r.agrupar_por })}
                    className={`inline-flex items-center gap-2 rounded-full px-3.5 py-2 text-sm font-semibold transition ${
                      ativo ? "bg-[#7C3AED] text-white shadow-[0_6px_16px_rgba(124,58,237,0.3)]" : "bg-slate-100 text-slate-600 hover:bg-slate-200/70"
                    }`}
                  >
                    <Icone className="h-4 w-4" />
                    {rotulo}
                  </button>
                );
              })}
            </div>
          </div>

          {metrica?.usa_periodo ? (
            <div className="grid gap-3 sm:grid-cols-2">
              <CustomSelect
                label="Período"
                value={r.periodo}
                onChange={(valor) => mudar({ periodo: valor as Periodo })}
                options={PERIODOS.map((p) => ({ value: p, label: ROTULO_DO_PERIODO[p] }))}
              />
              {r.periodo === "personalizado" ? (
                <div className="grid grid-cols-2 gap-2">
                  <Input label="De" type="date" value={r.de} onChange={(e) => mudar({ de: e.target.value })} />
                  <Input label="Até" type="date" value={r.ate} onChange={(e) => mudar({ ate: e.target.value })} />
                </div>
              ) : null}
            </div>
          ) : (
            <p className="text-xs text-slate-500">Este número é uma foto de agora: não depende de período.</p>
          )}

          {pedeAgrupamento ? (
            <div className="grid gap-3 sm:grid-cols-2">
              <CustomSelect
                label="Dividir"
                value={r.agrupar_por || agrupamentoEfetivo}
                onChange={(valor) => mudar({ agrupar_por: valor })}
                options={dimensoesDoTipo.map((d) => ({ value: d, label: ROTULO_DA_DIMENSAO[d as Dimensao] }))}
              />
              {pedeLimite ? (
                <Input
                  label="Mostrar até"
                  inputMode="numeric"
                  value={r.limite}
                  onChange={(e) => mudar({ limite: e.target.value.replace(/\D/g, "").slice(0, 2) })}
                  suffix="itens"
                />
              ) : null}
            </div>
          ) : null}

          {metrica?.filtros.includes("canal") ? (
            <CustomSelect
              label="Só do canal"
              value={r.canal}
              onChange={(valor) => mudar({ canal: valor })}
              options={[{ value: "", label: "Todos os canais" }, ...Object.entries(CANAIS).map(([id, rotulo]) => ({ value: id, label: rotulo }))]}
            />
          ) : null}

          <Input label="Título (opcional)" placeholder={metrica?.rotulo} value={r.titulo} maxLength={80} onChange={(e) => mudar({ titulo: e.target.value })} />

          {erro ? <p className="rounded-lg bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700">{erro}</p> : null}
        </div>

        <DialogFooter className="mt-2">
          <button type="button" className="ks-button ks-button-ghost" onClick={aoFechar} disabled={salvando}>
            Cancelar
          </button>
          <button type="button" className="ks-button ks-button-primary" onClick={salvar} disabled={salvando}>
            {salvando ? "Salvando..." : inicial ? "Salvar quadro" : "Adicionar quadro"}
          </button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
