"use client";

import { useRef, useState } from "react";
import { ArrowRight, Eye, EyeOff, FileKey2, Loader2, RefreshCw, ShieldCheck, Upload } from "lucide-react";

import { dataCurta, ErroDaTela } from "@/components/fiscal/comum";
import { Aviso } from "@/components/ui/aviso";

import { Campo, TopoDoPasso } from "./campos";
import type { PropsDoPasso } from "./cliente";

function diasAte(iso: string | null | undefined) {
  if (!iso) return null;
  const fim = new Date(iso).getTime();
  if (!Number.isFinite(fim)) return null;
  return Math.floor((fim - Date.now()) / 86400000);
}

export function PassoCertificado({ painel, recarregar, irPara }: PropsDoPasso) {
  const emissor = painel.emissor;
  const certificado = emissor?.certificado ?? null;
  const dias = diasAte(certificado?.validade);
  const valido = dias !== null && dias >= 0;
  const [trocando, setTrocando] = useState(false);
  const [arquivo, setArquivo] = useState<File | null>(null);
  const [senha, setSenha] = useState("");
  const [verSenha, setVerSenha] = useState(false);
  const [enviando, setEnviando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [arrastando, setArrastando] = useState(false);
  const entrada = useRef<HTMLInputElement>(null);

  const escolher = (lista: FileList | null | undefined) => {
    const escolhido = lista?.[0] ?? null;
    setErro(null);
    if (escolhido && !/\.(pfx|p12)$/i.test(escolhido.name)) {
      setErro("Esse arquivo não é um certificado A1. Ele termina em .pfx ou .p12.");
      return;
    }
    setArquivo(escolhido);
  };

  const enviar = async () => {
    if (!arquivo || !senha) return;
    setEnviando(true);
    setErro(null);
    try {
      const formulario = new FormData();
      formulario.append("arquivo", arquivo);
      formulario.append("senha", senha);
      const resposta = await fetch("/api/fiscal/certificado", { method: "POST", body: formulario });
      const json = (await resposta.json().catch(() => null)) as { error?: string } | null;
      if (!resposta.ok) throw new ErroDaTela(json?.error || "O certificado não foi aceito.", resposta.status);
      setArquivo(null);
      setSenha("");
      setTrocando(false);
      if (entrada.current) entrada.current.value = "";
      await recarregar();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "O certificado não foi aceito.");
    } finally {
      setEnviando(false);
    }
  };

  if (!emissor?.cadastradoNaSpedy) {
    return (
      <div className="space-y-8">
        <TopoDoPasso Icone={FileKey2} titulo="Certificado digital" texto="O certificado A1 assina cada nota em nome da empresa." />
        <Aviso
          tom="neutro"
          titulo="Primeiro, salve os dados da empresa"
          acao={
            <button type="button" onClick={() => irPara("empresa")} className="ks-button ks-button-primary ks-button-sm">
              Ir para Sua empresa
            </button>
          }
        >
          O certificado fica ligado ao CNPJ salvo no passo 1.
        </Aviso>
      </div>
    );
  }

  const mostrarEnvio = !certificado?.validade || trocando || !valido;

  return (
    <div className="space-y-8">
      <TopoDoPasso
        Icone={FileKey2}
        titulo="Certificado digital"
        texto="O certificado A1 é a assinatura digital da empresa: um arquivo com senha, comprado em uma certificadora. Ele assina cada nota."
      />

      {certificado?.validade ? (
        <div
          className={`flex flex-col gap-5 rounded-3xl p-6 sm:flex-row sm:items-center ${
            valido ? "bg-gradient-to-br from-emerald-500 to-emerald-700 text-white shadow-[0_18px_40px_rgba(16,185,129,0.28)]" : "bg-gradient-to-br from-rose-500 to-red-700 text-white shadow-[0_18px_40px_rgba(224,19,41,0.28)]"
          }`}
        >
          <span className="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-white/20">
            <ShieldCheck size={32} />
          </span>
          <div className="min-w-0 flex-1">
            <p className="text-xl font-extrabold">{valido ? "Certificado pronto" : "Certificado vencido"}</p>
            <p className="mt-1 truncate text-sm text-white/85">{certificado.titular || "Certificado da empresa"}</p>
            <p className="mt-1 text-sm text-white/85">
              {valido ? "Válido até " : "Venceu em "}
              <strong className="ks-num text-white">{dataCurta(certificado.validade)}</strong>
              {valido ? ` · faltam ${dias} ${dias === 1 ? "dia" : "dias"}` : ""}
            </p>
          </div>
          {valido ? (
            <div className="flex flex-wrap gap-2">
              {!trocando ? (
                <button type="button" onClick={() => setTrocando(true)} className="inline-flex h-11 items-center gap-2 rounded-xl bg-white/15 px-4 text-sm font-bold text-white transition hover:bg-white/25">
                  <RefreshCw size={16} />
                  Trocar
                </button>
              ) : null}
              <button type="button" onClick={() => irPara("notas")} className="inline-flex h-11 items-center gap-2 rounded-xl bg-white px-5 text-sm font-bold text-emerald-700 transition hover:bg-white/90">
                Continuar
                <ArrowRight size={16} />
              </button>
            </div>
          ) : null}
        </div>
      ) : null}

      {valido && dias !== null && dias <= 30 ? (
        <Aviso tom="atencao" titulo="O certificado vence logo">
          Renove com a certificadora antes do vencimento e envie o arquivo novo aqui, para as notas não pararem.
        </Aviso>
      ) : null}

      {erro ? (
        <Aviso tom="ruim" titulo="O certificado não foi aceito" aoFechar={() => setErro(null)}>
          {erro}
        </Aviso>
      ) : null}

      {mostrarEnvio ? (
        <div className="grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]">
          <button
            type="button"
            onClick={() => entrada.current?.click()}
            onDragOver={(e) => {
              e.preventDefault();
              setArrastando(true);
            }}
            onDragLeave={() => setArrastando(false)}
            onDrop={(e) => {
              e.preventDefault();
              setArrastando(false);
              escolher(e.dataTransfer.files);
            }}
            className={`flex min-h-[200px] flex-col items-center justify-center gap-3 rounded-3xl border-2 border-dashed px-6 py-8 text-center transition ${
              arrastando
                ? "border-[var(--ks-color-primary)] bg-violet-500/5"
                : arquivo
                  ? "border-emerald-400 bg-emerald-500/5"
                  : "border-[var(--ks-color-border-strong)] hover:border-[var(--ks-color-primary)] hover:bg-[var(--ks-color-bg-hover)]"
            }`}
          >
            <span
              className={`flex h-14 w-14 items-center justify-center rounded-2xl text-white ${
                arquivo ? "bg-gradient-to-br from-emerald-400 to-emerald-600" : "bg-gradient-to-br from-violet-500 to-purple-600"
              }`}
            >
              {arquivo ? <ShieldCheck size={26} /> : <Upload size={26} />}
            </span>
            <span className="text-base font-extrabold text-[var(--ks-color-text-primary)]">{arquivo ? arquivo.name : "Escolha o arquivo do certificado"}</span>
            <span className="text-sm text-[var(--ks-color-text-muted)]">
              {arquivo ? "Clique para trocar o arquivo." : "Arraste aqui ou clique para procurar. Ele termina em .pfx ou .p12."}
            </span>
          </button>
          <input ref={entrada} type="file" accept=".pfx,.p12,application/x-pkcs12" className="hidden" onChange={(e) => escolher(e.target.files)} />

          <div className="flex flex-col justify-between gap-5 rounded-3xl bg-[var(--ks-color-bg-inset)] p-6">
            <Campo
              rotulo="Senha do certificado"
              ajuda="É a senha que você criou ao comprar o certificado A1, não a senha do Ktalogu. Ela serve só para abrir o arquivo e não fica guardada."
              link="certificado"
              dica="A senha criada na compra do certificado. Ela não fica guardada."
            >
              <div className="relative">
                <input
                  type={verSenha ? "text" : "password"}
                  value={senha}
                  onChange={(e) => setSenha(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter" && arquivo && senha) void enviar();
                  }}
                  autoComplete="new-password"
                  className="ks-field"
                  style={{ paddingRight: "2.75rem" }}
                />
                <button
                  type="button"
                  onClick={() => setVerSenha((v) => !v)}
                  className="absolute right-2 top-1/2 -translate-y-1/2 rounded-lg p-1.5 text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-hover)]"
                  aria-label={verSenha ? "Esconder senha" : "Mostrar senha"}
                >
                  {verSenha ? <EyeOff size={16} /> : <Eye size={16} />}
                </button>
              </div>
            </Campo>
            <div className="flex flex-wrap items-center justify-end gap-2">
              {trocando ? (
                <button type="button" onClick={() => setTrocando(false)} className="ks-button ks-button-ghost">
                  Cancelar
                </button>
              ) : null}
              <button type="button" onClick={() => void enviar()} disabled={!arquivo || !senha || enviando} className="ks-button ks-button-primary">
                {enviando ? <Loader2 size={16} className="animate-spin" /> : <ShieldCheck size={16} />}
                {enviando ? "Conferindo o certificado…" : "Enviar certificado"}
              </button>
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}
