"use client";

/* Os modelos de condições da empresa, dentro da aba Financeiro do orçamento.

   Uma gráfica trabalha com mais de uma condição ("à vista no Pix", "50% de
   entrada", "faturado em 30 dias") e escolhe pelo cliente. Aqui ela guarda
   cada uma com um nome, aplica no orçamento com um clique, escolhe qual é o
   padrão dos orçamentos novos — e apaga a que não usa mais, que era o que
   faltava quando só existia um padrão sem volta.

   Só o dono gerencia (é o que a rota exige); quem não é dono vê a lista e
   aplica. A regra mora em lib/modelos-de-condicoes.ts. */

import { useState } from "react";
import { Check, Loader2, Pencil, Plus, Save, Star, Trash2, X } from "lucide-react";
import type { CondicoesComerciais } from "@/lib/condicoes-comerciais";
import { LIMITE_DE_MODELOS, LIMITE_DO_NOME, type ModeloDeCondicoes } from "@/lib/modelos-de-condicoes";

type Acao =
  | { acao: "criar"; nome: string; payment_terms: CondicoesComerciais }
  | { acao: "renomear"; id: string; nome: string }
  | { acao: "substituir"; id: string; payment_terms: CondicoesComerciais }
  | { acao: "excluir"; id: string }
  | { acao: "padrao"; id: string | null };

const ICONE =
  "inline-flex h-7 w-7 items-center justify-center rounded-lg text-[var(--ks-color-text-muted)] transition-colors hover:bg-[var(--ks-color-bg-soft)] hover:text-[var(--ks-color-text-primary)] disabled:cursor-not-allowed disabled:opacity-40";

export function ModelosDeCondicoes({
  modelos,
  podeGerenciar,
  desabilitado,
  condicoesAtuais,
  aoUsar,
  aoMudarLista,
}: {
  modelos: ModeloDeCondicoes[];
  /* É o dono da empresa: só ele cria, renomeia, apaga e escolhe o padrão. */
  podeGerenciar: boolean;
  desabilitado?: boolean;
  /* O que está na tela agora, para salvar como modelo novo ou gravar por cima. */
  condicoesAtuais: CondicoesComerciais | null;
  aoUsar: (condicoes: CondicoesComerciais) => void;
  aoMudarLista: (modelos: ModeloDeCondicoes[]) => void;
}) {
  const [ocupado, setOcupado] = useState<string | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [aplicado, setAplicado] = useState<string | null>(null);
  const [nomeNovo, setNomeNovo] = useState<string | null>(null);
  const [renomeando, setRenomeando] = useState<{ id: string; nome: string } | null>(null);
  const [excluindo, setExcluindo] = useState<string | null>(null);

  const cheia = modelos.length >= LIMITE_DE_MODELOS;

  async function pedir(corpo: Acao, marca: string) {
    setOcupado(marca);
    setErro(null);
    try {
      const resposta = await fetch("/api/quotes/condicoes-padrao", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(corpo),
      });
      const json = (await resposta.json().catch(() => null)) as { error?: string; modelos?: ModeloDeCondicoes[] } | null;
      if (!resposta.ok) throw new Error(json?.error || "Não deu para salvar.");
      aoMudarLista(json?.modelos ?? []);
      return true;
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não deu para salvar.");
      return false;
    } finally {
      setOcupado(null);
    }
  }

  async function criarModelo() {
    if (!condicoesAtuais || nomeNovo === null) return;
    const deuCerto = await pedir({ acao: "criar", nome: nomeNovo, payment_terms: condicoesAtuais }, "criar");
    if (deuCerto) setNomeNovo(null);
  }

  async function salvarNome() {
    if (!renomeando) return;
    const deuCerto = await pedir({ acao: "renomear", id: renomeando.id, nome: renomeando.nome }, `renomear-${renomeando.id}`);
    if (deuCerto) setRenomeando(null);
  }

  const usar = (modelo: ModeloDeCondicoes) => {
    aoUsar(modelo.condicoes);
    setAplicado(modelo.id);
    window.setTimeout(() => setAplicado((atual) => (atual === modelo.id ? null : atual)), 2500);
  };

  const campo =
    "w-full rounded-lg border border-[var(--ks-color-border-subtle)] bg-white px-2.5 py-1.5 text-sm focus:border-[var(--ks-color-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/20";

  return (
    <div className="space-y-2 border-t border-dashed border-[var(--ks-color-border-subtle)] pt-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <span className="text-xs font-semibold text-[var(--ks-color-text-secondary)]">Modelos da empresa</span>
        {podeGerenciar && condicoesAtuais && nomeNovo === null && (
          <button
            type="button"
            disabled={desabilitado || cheia}
            onClick={() => {
              setErro(null);
              setNomeNovo("");
            }}
            title={cheia ? `A empresa já tem ${LIMITE_DE_MODELOS} modelos.` : undefined}
            className="inline-flex items-center gap-1.5 rounded-lg border border-[var(--ks-color-border-subtle)] bg-white px-2.5 py-1.5 text-xs font-semibold text-[var(--ks-color-primary)] transition-colors hover:bg-[var(--ks-color-primary-soft)] disabled:opacity-50"
          >
            <Plus size={13} />
            Salvar estas condições como modelo
          </button>
        )}
      </div>

      {modelos.length > 0 && (
        <ul className="divide-y divide-[var(--ks-color-border-subtle)]/60">
          {modelos.map((modelo) => {
            const renomeandoEste = renomeando?.id === modelo.id;
            return (
              <li key={modelo.id} className="flex flex-wrap items-center gap-2 py-1.5">
                {podeGerenciar ? (
                  <button
                    type="button"
                    disabled={desabilitado || ocupado !== null}
                    onClick={() => void pedir({ acao: "padrao", id: modelo.padrao ? null : modelo.id }, `padrao-${modelo.id}`)}
                    title={modelo.padrao ? "Deixar de ser o padrão dos orçamentos novos" : "Usar em todo orçamento novo"}
                    className={`${ICONE} ${modelo.padrao ? "text-amber-500 hover:text-amber-600" : ""}`}
                  >
                    {ocupado === `padrao-${modelo.id}` ? <Loader2 size={14} className="animate-spin" /> : <Star size={14} fill={modelo.padrao ? "currentColor" : "none"} />}
                  </button>
                ) : (
                  <span className={`${ICONE} pointer-events-none ${modelo.padrao ? "text-amber-500" : "opacity-0"}`} aria-hidden="true">
                    <Star size={14} fill="currentColor" />
                  </span>
                )}

                {renomeandoEste ? (
                  <div className="flex min-w-0 flex-1 items-center gap-1.5">
                    <input
                      autoFocus
                      value={renomeando.nome}
                      maxLength={LIMITE_DO_NOME}
                      onChange={(evento) => setRenomeando({ id: modelo.id, nome: evento.target.value })}
                      onKeyDown={(evento) => {
                        /* Enter salva e Escape desiste. Sem <form> aqui de
                           propósito: esta tela inteira já é um formulário, e
                           HTML não aceita um dentro do outro — o campo virava
                           enfeite e o Enter mandava o orçamento. */
                        if (evento.key === "Enter") {
                          evento.preventDefault();
                          void salvarNome();
                        }
                        if (evento.key === "Escape") setRenomeando(null);
                      }}
                      aria-label={`Novo nome de ${modelo.nome}`}
                      className={campo}
                    />
                    <button type="button" disabled={ocupado !== null} onClick={() => void salvarNome()} className={ICONE} title="Salvar o nome">
                      <Check size={14} />
                    </button>
                    <button type="button" onClick={() => setRenomeando(null)} className={ICONE} title="Cancelar">
                      <X size={14} />
                    </button>
                  </div>
                ) : (
                  <>
                    <span className="min-w-0 flex-1 truncate text-sm font-medium text-[var(--ks-color-text-primary)]">{modelo.nome}</span>
                    {excluindo === modelo.id ? (
                      <span className="flex items-center gap-1.5 text-xs text-[var(--ks-color-text-secondary)]">
                        Apagar este modelo?
                        <button
                          type="button"
                          disabled={ocupado !== null}
                          onClick={async () => {
                            const deuCerto = await pedir({ acao: "excluir", id: modelo.id }, `excluir-${modelo.id}`);
                            if (deuCerto) setExcluindo(null);
                          }}
                          className="rounded-lg px-2 py-1 text-xs font-bold text-[var(--ks-color-status-danger)] transition-colors hover:bg-[var(--ks-color-status-danger)]/10 disabled:opacity-50"
                        >
                          {ocupado === `excluir-${modelo.id}` ? "Apagando..." : "Apagar"}
                        </button>
                        <button type="button" onClick={() => setExcluindo(null)} className="rounded-lg px-2 py-1 text-xs font-semibold text-[var(--ks-color-text-muted)] transition-colors hover:bg-[var(--ks-color-bg-soft)]">
                          Não
                        </button>
                      </span>
                    ) : (
                      <span className="flex items-center gap-0.5">
                        <button
                          type="button"
                          disabled={desabilitado}
                          onClick={() => usar(modelo)}
                          className="rounded-lg px-2.5 py-1 text-xs font-bold text-[var(--ks-color-primary)] transition-colors hover:bg-[var(--ks-color-primary-soft)] disabled:opacity-50"
                        >
                          {aplicado === modelo.id ? "Aplicado" : "Usar"}
                        </button>
                        {podeGerenciar && (
                          <>
                            <button
                              type="button"
                              disabled={desabilitado || !condicoesAtuais || ocupado !== null}
                              onClick={() => condicoesAtuais && void pedir({ acao: "substituir", id: modelo.id, payment_terms: condicoesAtuais }, `substituir-${modelo.id}`)}
                              title="Gravar as condições desta tela neste modelo"
                              className={ICONE}
                            >
                              {ocupado === `substituir-${modelo.id}` ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
                            </button>
                            <button
                              type="button"
                              disabled={desabilitado || ocupado !== null}
                              onClick={() => {
                                setErro(null);
                                setRenomeando({ id: modelo.id, nome: modelo.nome });
                              }}
                              title="Renomear"
                              className={ICONE}
                            >
                              <Pencil size={14} />
                            </button>
                            <button
                              type="button"
                              disabled={desabilitado || ocupado !== null}
                              onClick={() => {
                                setErro(null);
                                setExcluindo(modelo.id);
                              }}
                              title="Apagar modelo"
                              className={`${ICONE} hover:text-[var(--ks-color-status-danger)]`}
                            >
                              <Trash2 size={14} />
                            </button>
                          </>
                        )}
                      </span>
                    )}
                  </>
                )}
              </li>
            );
          })}
        </ul>
      )}

      {nomeNovo !== null && condicoesAtuais && (
        <div className="flex flex-wrap items-center gap-1.5">
          <input
            autoFocus
            value={nomeNovo}
            maxLength={LIMITE_DO_NOME}
            onChange={(evento) => setNomeNovo(evento.target.value)}
            onKeyDown={(evento) => {
              if (evento.key === "Enter") {
                evento.preventDefault();
                void criarModelo();
              }
              if (evento.key === "Escape") setNomeNovo(null);
            }}
            placeholder="Nome do modelo. Ex.: Faturado em 30 dias"
            aria-label="Nome do modelo"
            className={`${campo} min-w-0 flex-1`}
          />
          <button
            type="button"
            disabled={ocupado !== null || !nomeNovo.trim()}
            onClick={() => void criarModelo()}
            className="inline-flex items-center gap-1.5 rounded-lg bg-[var(--ks-color-primary)] px-3 py-1.5 text-xs font-bold text-white transition-colors hover:bg-[var(--ks-color-primary-strong)] disabled:opacity-50"
          >
            {ocupado === "criar" ? <Loader2 size={13} className="animate-spin" /> : <Check size={13} />}
            Salvar
          </button>
          <button type="button" onClick={() => setNomeNovo(null)} className="rounded-lg px-2.5 py-1.5 text-xs font-semibold text-[var(--ks-color-text-muted)] transition-colors hover:bg-[var(--ks-color-bg-soft)]">
            Cancelar
          </button>
        </div>
      )}

      {erro && <p className="text-xs font-semibold text-[var(--ks-color-status-danger)]">{erro}</p>}

      <p className="text-xs text-[var(--ks-color-text-muted)]">
        {modelos.length === 0
          ? podeGerenciar
            ? "A empresa ainda não tem modelos. Salve estas condições com um nome para reaproveitar nos próximos orçamentos."
            : "A empresa ainda não tem modelos de condições."
          : modelos.some((modelo) => modelo.padrao)
            ? "Todo orçamento novo começa pelo modelo da estrela. Clique na estrela dele para a empresa ficar sem padrão."
            : "Nenhum modelo é o padrão: cada orçamento novo começa à vista no Pix."}
      </p>
    </div>
  );
}
