"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import {
  Award,
  Check,
  Clapperboard,
  Copy,
  ExternalLink,
  HardDrive,
  Loader2,
  Lock,
  Mail,
  MessageSquare,
  Palette,
  PlayCircle,
  ReceiptText,
  Save,
} from "lucide-react";

import ImageUpload from "@/components/image-upload";
import { AreaFechada, CarregandoArea, ErroDaArea, FalhaDaArea, pedirDigitais } from "@/components/digitais/comum";
import { Aviso } from "@/components/ui/aviso";
import { Button } from "@/components/ui/button";
import { EntradaDecimal } from "@/components/ui/campo-decimal";
import { ColorField } from "@/components/ui/color-field";
import {
  AreaDeTexto,
  ChaveDeAjuste,
  EscolhaDeAjuste,
  FolhaDeAjustes,
  LinhaDeAjuste,
  SecaoDeAjustes,
  type ItemDoIndice,
} from "@/components/ui/folha-de-ajustes";
import { Input } from "@/components/ui/input";
import { PageHeader } from "@/components/ui/page-header";
import {
  PALAVRAS_DO_EMAIL,
  VELOCIDADES_POSSIVEIS,
  secoesMexidas,
  type ConfiguracoesDigitais,
} from "@/lib/digitais/configuracoes";
import { fonteDosTitulos, FUNDOS_DA_AREA } from "@/lib/digitais/aparencia";
import { FORMATOS_NA_TELA, RECUSADOS_NA_TELA } from "@/lib/digitais/formatos";
import { faixaDoEspaco } from "@/lib/digitais/limites";
import { tamanhoLegivel } from "@/lib/digitais/nome-do-arquivo";

import { EscolhaDaCor, EscolhaDaFonte, EscolhaDasCapas, EscolhaDoFundo, FontesDaAparencia, PreviaDaArea } from "./aparencia-da-area";

type Resposta = {
  config: ConfiguracoesDigitais;
  padrao: ConfiguracoesDigitais;
  atualizadoEm: string | null;
  podeMudar: boolean;
  loja: { nome: string; cor: string | null; dominio: string | null; enderecoDaArea: string | null };
  deposito: boolean;
  /* A nota de serviço (NFS-e) já está configurada em Notas fiscais. */
  nfseConfigurada?: boolean;
  espaco: { usado: number; total: number; porArquivo: number; teste: boolean };
};

type Prazo = "sempre" | "ano" | "outro";

const prazoDe = (dias: number | null): Prazo => (dias === null ? "sempre" : dias === 365 ? "ano" : "outro");
const velocidadeNaTela = (v: number) => `${String(v).replace(".", ",")}x`;
const plural = (n: number, um: string, varios: string) => `${n} ${n === 1 ? um : varios}`;

export default function ConfiguracoesDosDigitais() {
  const [dados, setDados] = useState<Resposta | null>(null);
  const [config, setConfig] = useState<ConfiguracoesDigitais | null>(null);
  const [salvo, setSalvo] = useState<string>("");
  const [erro, setErro] = useState<Error | null>(null);
  const [salvando, setSalvando] = useState(false);
  const [mensagem, setMensagem] = useState<{ tom: "bom" | "ruim"; texto: string } | null>(null);
  const [copiado, setCopiado] = useState(false);

  const carregar = useCallback(
    () =>
      pedirDigitais<Resposta>("/api/digitais/configuracoes")
        .then((resposta) => {
          setErro(null);
          setDados(resposta);
          setConfig(resposta.config);
          setSalvo(JSON.stringify(resposta.config));
        })
        .catch((e: unknown) => setErro(e instanceof Error ? e : new Error("Não foi possível carregar."))),
    []
  );

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

  const mudou = config !== null && JSON.stringify(config) !== salvo;

  const mudar = <S extends keyof ConfiguracoesDigitais>(secao: S, parte: Partial<ConfiguracoesDigitais[S]>) => {
    setConfig((atual) => (atual ? { ...atual, [secao]: { ...atual[secao], ...parte } } : atual));
    setMensagem(null);
  };

  const salvar = async () => {
    if (!config) return;
    setSalvando(true);
    setMensagem(null);
    try {
      const resposta = await pedirDigitais<{ config: ConfiguracoesDigitais }>("/api/digitais/configuracoes", {
        method: "PUT",
        body: JSON.stringify({ config }),
      });
      setConfig(resposta.config);
      setSalvo(JSON.stringify(resposta.config));
      setMensagem({ tom: "bom", texto: "Configurações salvas." });
    } catch (e) {
      setMensagem({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível salvar." });
    } finally {
      setSalvando(false);
    }
  };

  const indice: ItemDoIndice[] = useMemo(() => {
    if (!config || !dados) return [];
    const mexidas = secoesMexidas(config);
    const prazo = prazoDe(config.acesso.prazoDias);
    return [
      {
        id: "dig-area",
        titulo: "Área de membros",
        resumo: config.area.nome ? config.area.nome : "Nome e endereço",
        Icone: Clapperboard,
      },
      {
        id: "dig-aparencia",
        titulo: "Aparência",
        resumo: `${fonteDosTitulos(config.area.fonte).nome} · ${FUNDOS_DA_AREA.find((f) => f.id === config.area.fundo)?.nome ?? "Preto profundo"}`,
        Icone: Palette,
        mexido: mexidas.has("area"),
      },
      {
        id: "dig-entrega",
        titulo: "Entrega e e-mails",
        resumo: config.entrega.reenviarEm24h ? "Com lembrete em 24 h" : "Sem lembrete",
        Icone: Mail,
        mexido: mexidas.has("entrega") || mexidas.has("lembretes"),
      },
      {
        id: "dig-acesso",
        titulo: "Acesso e segurança",
        resumo: `${prazo === "sempre" ? "Para sempre" : prazo === "ano" ? "1 ano" : plural(config.acesso.prazoDias ?? 0, "dia", "dias")} · ${plural(config.acesso.aparelhos, "aparelho", "aparelhos")}`,
        Icone: Lock,
        mexido: mexidas.has("acesso"),
      },
      {
        id: "dig-player",
        titulo: "Player de vídeo",
        resumo: `Assistida em ${config.player.percentualAssistida}%`,
        Icone: PlayCircle,
        mexido: mexidas.has("player"),
      },
      {
        id: "dig-comentarios",
        titulo: "Comentários",
        resumo: config.comentarios.quando === "na_hora" ? "Aparecem na hora" : "Você aprova antes",
        Icone: MessageSquare,
        mexido: mexidas.has("comentarios"),
      },
      {
        id: "dig-certificado",
        titulo: "Certificado",
        resumo: config.certificado.emitir ? "Ao concluir o conteúdo" : "Desligado",
        Icone: Award,
        mexido: mexidas.has("certificado"),
      },
      {
        id: "dig-nota",
        titulo: "Nota fiscal",
        resumo: config.fiscal.nfseNaLoja ? "NFS-e sozinha nas vendas" : "Você emite quando quiser",
        Icone: ReceiptText,
        mexido: mexidas.has("fiscal"),
      },
      {
        id: "dig-armazenamento",
        titulo: "Armazenamento",
        resumo: `${tamanhoLegivel(dados.espaco.usado)} de ${tamanhoLegivel(dados.espaco.total)}`,
        Icone: HardDrive,
      },
    ];
  }, [config, dados]);

  if (erro instanceof ErroDaArea && erro.status === 403) return <AreaFechada erro={erro} />;
  if (erro) return <FalhaDaArea erro={erro} aoTentarDeNovo={() => void carregar()} />;
  if (!dados || !config) return <CarregandoArea />;

  const podeMudar = dados.podeMudar;
  const prazo = prazoDe(config.acesso.prazoDias);
  const corDaLoja = dados.loja.cor || "#5F31D6";
  const usado = dados.espaco.usado;
  const fracao = dados.espaco.total > 0 ? Math.min(100, (usado / dados.espaco.total) * 100) : 0;
  const faixa = faixaDoEspaco(usado, dados.espaco.total);

  const copiarEndereco = async () => {
    if (!dados.loja.enderecoDaArea) return;
    try {
      await navigator.clipboard.writeText(dados.loja.enderecoDaArea);
      setCopiado(true);
      window.setTimeout(() => setCopiado(false), 1800);
    } catch {
      setCopiado(false);
    }
  };

  const inserirPalavra = (palavra: string) => {
    mudar("entrega", { mensagem: `${config.entrega.mensagem}${config.entrega.mensagem.endsWith(" ") ? "" : " "}{{${palavra}}}` });
  };

  return (
    <div className="space-y-6 pb-4">
      <PageHeader
        eyebrow="Produtos digitais"
        title="Configurações dos produtos digitais"
        subtitle="Valem para todos os conteúdos em vídeo e produtos digitais da loja. Cada produto pode mudar o que precisar."
      />

      {!podeMudar ? (
        <Aviso tom="neutro">Você pode ver estas configurações, mas mudar fica com quem tem a permissão de configurar os digitais.</Aviso>
      ) : null}

      <FolhaDeAjustes indice={indice}>
        <SecaoDeAjustes
          id="dig-area"
          Icone={Clapperboard}
          titulo="Área de membros"
          texto="Onde seus clientes assistem aos vídeos e baixam o que compraram. Fica no endereço da sua loja."
        >
          <LinhaDeAjuste titulo="Endereço" texto="Usa o domínio da sua loja, sem configurar nada.">
            {dados.loja.enderecoDaArea ? (
              <div className="flex flex-wrap items-center gap-2">
                <code className="min-w-0 flex-1 truncate rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2.5 font-mono text-[13px] text-[var(--ks-color-text-primary)]">
                  {dados.loja.enderecoDaArea.replace(/^https?:\/\//, "")}
                </code>
                <button type="button" onClick={() => void copiarEndereco()} className="ks-button ks-button-soft ks-button-sm">
                  {copiado ? <Check size={14} /> : <Copy size={14} />}
                  {copiado ? "Copiado" : "Copiar"}
                </button>
                <a href={dados.loja.enderecoDaArea} target="_blank" rel="noreferrer" className="ks-button ks-button-ghost ks-button-sm">
                  <ExternalLink size={14} />
                  Abrir
                </a>
              </div>
            ) : (
              <p className="pt-1.5 text-sm text-[var(--ks-color-text-muted)]">Defina o endereço da loja em Loja &gt; Personalização para a área ganhar o dela.</p>
            )}
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Nome que aparece" texto="No topo da área e nos e-mails." htmlFor="dig-nome">
            <Input
              id="dig-nome"
              placeholder={dados.loja.nome}
              value={config.area.nome ?? ""}
              maxLength={60}
              disabled={!podeMudar}
              onChange={(e) => mudar("area", { nome: e.target.value || null })}
            />
          </LinhaDeAjuste>
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-aparencia"
          Icone={Palette}
          titulo="Aparência da área de membros"
          texto="Do jeito da sua marca: o cliente vê as mudanças assim que você salva."
        >
          <FontesDaAparencia />
          <div className="py-3">
            <PreviaDaArea
              aparencia={{ fonte: config.area.fonte, fundo: config.area.fundo, capas: config.area.capas }}
              cor={config.area.cor || corDaLoja}
              foto={config.area.banner}
              nomeDaArea={config.area.nome || dados.loja.nome}
            />
          </div>
          <LinhaDeAjuste titulo="Letra dos títulos" texto="Nome do conteúdo, dos módulos e dos vídeos. O texto corrido usa sempre uma letra fácil de ler." largo>
            <EscolhaDaFonte valor={config.area.fonte} desligado={!podeMudar} aoEscolher={(fonte) => mudar("area", { fonte })} />
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Cor de destaque" texto="Botões, progresso, selos e o brilho das capas. Cores apagadas viram laranja para os botões nunca sumirem.">
            <div className="space-y-3">
              <EscolhaDaCor valor={config.area.cor} corDaLoja={corDaLoja} desligado={!podeMudar} aoEscolher={(cor) => mudar("area", { cor })} />
              <ColorField
                label="Outra cor"
                value={config.area.cor ?? ""}
                fallback={corDaLoja}
                onChange={(cor) => {
                  if (podeMudar) mudar("area", { cor: cor || null });
                }}
              />
            </div>
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Fundo" texto="Escuro destaca as fotos, como num streaming." largo>
            <EscolhaDoFundo
              valor={config.area.fundo}
              desligado={!podeMudar}
              aoEscolher={(fundo) => mudar("area", { fundo, aparencia: fundo === "claro" ? "clara" : "escura" })}
            />
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Capas dos módulos" texto="A foto de cada módulo fica no editor do conteúdo. Módulo sem foto ganha uma capa com a sua cor e o título.">
            <EscolhaDasCapas valor={config.area.capas} desligado={!podeMudar} aoEscolher={(capas) => mudar("area", { capas })} />
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Foto de destaque" texto="A foto grande do topo da área. 1920 × 1080; com pessoa, o rosto à direita fica melhor. Sem foto, usamos a capa do conteúdo." largo>
            <div className="max-w-xl">
              <ImageUpload
                bucket="products"
                folder="digitais/banners"
                value={config.area.banner ?? ""}
                onChange={(url) => mudar("area", { banner: url || null })}
                disabled={!podeMudar}
                enableCrop
                cropAspect={16 / 9}
              />
            </div>
          </LinhaDeAjuste>
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-entrega"
          Icone={Mail}
          titulo="Entrega e e-mails"
          texto="Assim que o pagamento é aprovado, o comprador recebe o acesso no e-mail, em nome da sua loja."
        >
          <LinhaDeAjuste titulo="Assunto" texto="O que aparece na caixa de entrada." htmlFor="dig-assunto">
            <Input
              id="dig-assunto"
              value={config.entrega.assunto}
              maxLength={140}
              disabled={!podeMudar}
              onChange={(e) => mudar("entrega", { assunto: e.target.value })}
            />
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Mensagem" texto="Toque numa palavra para colocá-la no texto. Ela vira o dado de cada compra." htmlFor="dig-mensagem">
            <AreaDeTexto
              id="dig-mensagem"
              value={config.entrega.mensagem}
              maxLength={2000}
              rows={4}
              disabled={!podeMudar}
              onChange={(e) => mudar("entrega", { mensagem: e.target.value })}
            />
            <div className="mt-2 flex flex-wrap gap-1.5">
              {PALAVRAS_DO_EMAIL.map((palavra) => (
                <button
                  key={palavra}
                  type="button"
                  disabled={!podeMudar}
                  onClick={() => inserirPalavra(palavra)}
                  className="rounded-full bg-[var(--ks-color-bg-inset)] px-2.5 py-1 font-mono text-[11px] text-[var(--ks-color-text-muted)] transition-colors hover:bg-[var(--ks-brand-50)] hover:text-[var(--ks-brand-600)] disabled:opacity-60"
                >
                  {`{{${palavra}}}`}
                </button>
              ))}
            </div>
          </LinhaDeAjuste>
          <ChaveDeAjuste
            titulo="Lembrar quem não abriu"
            texto="Se o comprador não entrar em 24 horas, ele recebe o acesso de novo, uma vez."
            ligado={config.entrega.reenviarEm24h}
            desabilitado={!podeMudar}
            aoMudar={(reenviarEm24h) => mudar("entrega", { reenviarEm24h })}
          />
          <ChaveDeAjuste
            titulo="Lembrar quem parou de assistir"
            texto="Um e-mail “continue de onde parou” para quem não assiste ao conteúdo há 30 dias. No máximo um por mês."
            ligado={config.lembretes.alunosParados}
            desabilitado={!podeMudar}
            aoMudar={(alunosParados) => mudar("lembretes", { alunosParados })}
          />
          <ChaveDeAjuste
            titulo="Mostrar o acesso também no WhatsApp"
            texto="Na tela de compra aprovada, um botão abre a conversa com o link de acesso."
            ligado={config.entrega.botaoWhatsapp}
            desabilitado={!podeMudar}
            aoMudar={(botaoWhatsapp) => mudar("entrega", { botaoWhatsapp })}
          />
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-acesso"
          Icone={Lock}
          titulo="Acesso e segurança"
          texto="Por quanto tempo o comprador acessa e como evitar que um login seja dividido entre muitas pessoas."
        >
          <LinhaDeAjuste titulo="Por quanto tempo" texto="Vale para as compras novas. Cada conteúdo pode ter o seu.">
            <EscolhaDeAjuste
              rotulo="Por quanto tempo"
              valor={prazo}
              aoEscolher={(escolha) => {
                if (!podeMudar) return;
                if (escolha === "sempre") mudar("acesso", { prazoDias: null });
                else if (escolha === "ano") mudar("acesso", { prazoDias: 365 });
                else mudar("acesso", { prazoDias: config.acesso.prazoDias && config.acesso.prazoDias !== 365 ? config.acesso.prazoDias : 90 });
              }}
              opcoes={[
                { valor: "sempre", titulo: "Para sempre", texto: "O jeito mais comum: quem comprou acessa quando quiser." },
                { valor: "ano", titulo: "1 ano", texto: "Depois de um ano da compra, o acesso fecha." },
                { valor: "outro", titulo: "Outro prazo", texto: "Você escolhe quantos dias." },
              ]}
            />
            {prazo === "outro" ? (
              <div className="mt-2 flex max-w-[220px] items-center gap-2">
                <EntradaDecimal
                  aria-label="Dias de acesso"
                  casas={0}
                  valor={config.acesso.prazoDias ?? 90}
                  disabled={!podeMudar}
                  aoMudar={(dias) => mudar("acesso", { prazoDias: Math.max(1, Math.min(3650, Math.round(dias || 1))) })}
                  suffix="dias"
                />
              </div>
            ) : null}
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Aparelhos ao mesmo tempo" texto="Assistindo juntos com o mesmo login. O mais antigo pausa sozinho.">
            <div className="max-w-[220px]">
              <EntradaDecimal
                aria-label="Aparelhos ao mesmo tempo"
                casas={0}
                valor={config.acesso.aparelhos}
                disabled={!podeMudar}
                aoMudar={(n) => mudar("acesso", { aparelhos: Math.max(1, Math.min(10, Math.round(n || 1))) })}
                suffix={config.acesso.aparelhos === 1 ? "aparelho" : "aparelhos"}
              />
            </div>
          </LinhaDeAjuste>
          <ChaveDeAjuste
            titulo="Freio de compartilhamento"
            texto="Muitos lugares diferentes num dia: o acesso pede para entrar de novo pelo código do e-mail e você é avisado."
            ligado={config.acesso.freioLugares !== null}
            desabilitado={!podeMudar}
            aoMudar={(ligado) => mudar("acesso", { freioLugares: ligado ? 5 : null })}
          />
          {config.acesso.freioLugares !== null ? (
            <LinhaDeAjuste titulo="Quantos lugares em 24 horas" texto="Casa, trabalho e celular na rua contam como três.">
              <div className="max-w-[220px]">
                <EntradaDecimal
                  aria-label="Lugares em 24 horas"
                  casas={0}
                  valor={config.acesso.freioLugares}
                  disabled={!podeMudar}
                  aoMudar={(n) => mudar("acesso", { freioLugares: Math.max(2, Math.min(50, Math.round(n || 2))) })}
                  suffix="lugares"
                />
              </div>
            </LinhaDeAjuste>
          ) : null}
          <ChaveDeAjuste
            titulo="Marca d’água com o e-mail do cliente"
            texto="Aparece de leve no vídeo. Desencoraja quem grava a tela para repassar."
            ligado={config.acesso.marcaDagua}
            desabilitado={!podeMudar}
            aoMudar={(marcaDagua) => mudar("acesso", { marcaDagua })}
          />
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-player"
          Icone={PlayCircle}
          titulo="Player de vídeo"
          texto="O player é seu: sem propaganda, sem vídeos de outros canais e sem botão de baixar."
        >
          <ChaveDeAjuste
            titulo="Continuar de onde parou"
            texto="Volta no segundo exato, em qualquer aparelho."
            ligado={config.player.continuar}
            desabilitado={!podeMudar}
            aoMudar={(continuar) => mudar("player", { continuar })}
          />
          <LinhaDeAjuste titulo="Marcar como assistida" texto="Quando o cliente chega perto do fim do vídeo. Ele também pode marcar na mão.">
            <div className="max-w-[220px]">
              <EntradaDecimal
                aria-label="Porcentagem para marcar como assistida"
                casas={0}
                valor={config.player.percentualAssistida}
                disabled={!podeMudar}
                aoMudar={(n) => mudar("player", { percentualAssistida: Math.max(50, Math.min(100, Math.round(n || 90))) })}
                suffix="% do vídeo"
              />
            </div>
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Velocidades" texto="O cliente escolhe no player. A normal (1x) fica sempre.">
            <div className="flex flex-wrap gap-1.5 pt-1">
              {VELOCIDADES_POSSIVEIS.map((velocidade) => {
                const ligada = config.player.velocidades.includes(velocidade);
                const fixa = velocidade === 1;
                return (
                  <button
                    key={velocidade}
                    type="button"
                    aria-pressed={ligada}
                    disabled={!podeMudar || fixa}
                    onClick={() =>
                      mudar("player", {
                        velocidades: ligada
                          ? config.player.velocidades.filter((v) => v !== velocidade)
                          : [...config.player.velocidades, velocidade].sort((a, b) => a - b),
                      })
                    }
                    className={`ks-num rounded-full border px-3 py-1 text-xs font-semibold transition-colors ${
                      ligada
                        ? "border-[var(--ks-brand-600)] bg-[var(--ks-brand-600)] text-white"
                        : "border-[var(--ks-color-border-subtle)] text-[var(--ks-color-text-muted)] hover:border-[var(--ks-brand-500)]"
                    } ${fixa ? "cursor-default" : ""}`}
                  >
                    {velocidadeNaTela(velocidade)}
                  </button>
                );
              })}
            </div>
          </LinhaDeAjuste>
          <ChaveDeAjuste
            titulo="Próximo vídeo sozinho"
            texto="No fim do vídeo, conta 5 segundos e passa para a seguinte."
            ligado={config.player.proximaSozinha}
            desabilitado={!podeMudar}
            aoMudar={(proximaSozinha) => mudar("player", { proximaSozinha })}
          />
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-comentarios"
          Icone={MessageSquare}
          titulo="Comentários"
          texto="Os clientes tiram dúvidas embaixo dos vídeos e veem as respostas uns dos outros. Entre eles, aparece só o primeiro nome."
        >
          <LinhaDeAjuste titulo="Quando aparecem" texto="Para todos os clientes daquele conteúdo.">
            <EscolhaDeAjuste
              rotulo="Quando os comentários aparecem"
              valor={config.comentarios.quando}
              aoEscolher={(quando) => {
                if (podeMudar) mudar("comentarios", { quando });
              }}
              opcoes={[
                { valor: "na_hora", titulo: "Na hora", texto: "Você pode ocultar depois." },
                { valor: "aprovacao", titulo: "Depois que você aprovar", texto: "Fica esperando na tela Comentários." },
              ]}
            />
          </LinhaDeAjuste>
          <ChaveDeAjuste
            titulo="Me avisar"
            texto="No celular e no sino do painel, a cada comentário novo."
            ligado={config.comentarios.avisar}
            desabilitado={!podeMudar}
            aoMudar={(avisar) => mudar("comentarios", { avisar })}
          />
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-certificado"
          Icone={Award}
          titulo="Certificado"
          texto="Um PDF com o nome do cliente, o conteúdo e a carga horária, com um código que qualquer pessoa confere."
        >
          <ChaveDeAjuste
            titulo="Emitir ao concluir"
            texto="Quando o cliente termina todos os vídeos do conteúdo."
            ligado={config.certificado.emitir}
            desabilitado={!podeMudar}
            aoMudar={(emitir) => mudar("certificado", { emitir })}
          />
          <LinhaDeAjuste titulo="Assinatura" texto="O nome de quem assina o certificado." htmlFor="dig-assinatura">
            <Input
              id="dig-assinatura"
              placeholder={dados.loja.nome}
              value={config.certificado.assinatura ?? ""}
              maxLength={80}
              disabled={!podeMudar}
              onChange={(e) => mudar("certificado", { assinatura: e.target.value || null })}
            />
          </LinhaDeAjuste>
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-nota"
          Icone={ReceiptText}
          titulo="Nota fiscal"
          texto="Produto digital (arquivo, conteúdo em vídeo, código) sai na nota de serviço (NFS-e), com o perfil de serviço padrão da sua empresa."
        >
          <ChaveDeAjuste
            titulo="Emitir a NFS-e nas vendas da loja virtual"
            texto="Quando o pagamento é aprovado, a nota sai sozinha para o comprador. A venda e a entrega nunca esperam pela nota."
            ligado={config.fiscal.nfseNaLoja}
            desabilitado={!podeMudar}
            aoMudar={(nfseNaLoja) => mudar("fiscal", { nfseNaLoja })}
          />
          {config.fiscal.nfseNaLoja && dados.nfseConfigurada === false ? (
            <Aviso tom="atencao">
              A nota de serviço ainda não está ligada na sua empresa.{" "}
              <Link href="/dashboard/notas-fiscais/configuracao" className="font-semibold underline underline-offset-2">
                Configurar em Notas fiscais
              </Link>
            </Aviso>
          ) : null}
        </SecaoDeAjustes>

        <SecaoDeAjustes
          id="dig-armazenamento"
          Icone={HardDrive}
          titulo="Armazenamento"
          texto="Seu espaço para vídeos, PDFs e arquivos. Download e vídeo assistido não gastam espaço."
        >
          <LinhaDeAjuste titulo="Espaço do seu plano" texto={dados.espaco.teste ? "Na conta em teste o espaço é menor." : "Soma de todos os arquivos."}>
            <div className="pt-1">
              <p className="flex items-baseline gap-1.5">
                <span className="ks-num text-xl font-extrabold text-[var(--ks-color-text-primary)]">{tamanhoLegivel(usado)}</span>
                <span className="text-sm text-[var(--ks-color-text-muted)]">de {tamanhoLegivel(dados.espaco.total)}</span>
              </p>
              <div className="mt-2 h-2 overflow-hidden rounded-full bg-[var(--ks-color-bg-inset)]">
                <div
                  className={`h-full rounded-full ${faixa === "folga" ? "bg-gradient-to-r from-violet-500 to-purple-600" : "bg-gradient-to-r from-rose-500 to-red-600"}`}
                  style={{ width: `${Math.max(usado > 0 ? 1 : 0, fracao)}%` }}
                />
              </div>
              {!dados.deposito ? (
                <p className="mt-2 text-xs text-[var(--ks-color-text-soft)]">O envio de arquivos ainda está sendo ligado neste servidor.</p>
              ) : null}
            </div>
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Tamanho máximo por arquivo" texto="Limite do seu plano. Vídeo maior que isso: divida em dois vídeos.">
            <p className="ks-num pt-1.5 text-sm font-bold text-[var(--ks-color-text-primary)]">{tamanhoLegivel(dados.espaco.porArquivo)} por arquivo</p>
          </LinhaDeAjuste>
          <LinhaDeAjuste titulo="Formatos aceitos" texto="Programas que se instalam são recusados por segurança. Para pastas compactadas, use ZIP.">
            <div className="flex flex-wrap gap-1.5 pt-1">
              {FORMATOS_NA_TELA.map((formato) => (
                <span key={formato} className="rounded-full border border-[var(--ks-color-border-subtle)] px-2.5 py-0.5 text-[11px] font-semibold text-[var(--ks-color-text-muted)]">
                  {formato}
                </span>
              ))}
              <span className="rounded-full px-2 py-0.5 text-[11px] text-[var(--ks-color-text-soft)]">e outros</span>
              {RECUSADOS_NA_TELA.map((formato) => (
                <span key={formato} className="rounded-full border border-dashed border-[var(--ks-color-border-subtle)] px-2.5 py-0.5 text-[11px] text-[var(--ks-color-text-soft)] line-through">
                  {formato}
                </span>
              ))}
            </div>
          </LinhaDeAjuste>
        </SecaoDeAjustes>
      </FolhaDeAjustes>

      {podeMudar ? (
        <div className="sticky bottom-3 z-30 flex flex-wrap items-center justify-end gap-3 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-white/95 px-4 py-3 shadow-[0_10px_30px_-18px_rgba(15,23,42,0.45)] backdrop-blur">
          {mensagem ? (
            <span className={`text-sm font-semibold ${mensagem.tom === "bom" ? "text-[var(--ks-color-status-success)]" : "text-[var(--ks-color-status-danger)]"}`}>
              {mensagem.texto}
            </span>
          ) : mudou ? (
            <span className="text-sm text-[var(--ks-color-text-muted)]">Há mudanças por salvar.</span>
          ) : null}
          <Button
            type="button"
            disabled={salvando || !mudou}
            onClick={() => void salvar()}
            icon={salvando ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
          >
            {salvando ? "Salvando..." : "Salvar alterações"}
          </Button>
        </div>
      ) : null}
    </div>
  );
}
