"use client";

import type { CSSProperties, ReactNode } from "react";
import { CalendarClock, Monitor, Smartphone } from "lucide-react";
import { useNoEditor } from "@/components/editor-da-loja/contexto";
import { configDaSecao } from "@/lib/pagina-inicial";
import {
  ESPACO_ABAIXO,
  ESPACO_ACIMA,
  classesDoDispositivo,
  fundoEmCss,
  lerExibicao,
  momentoDoAgendamento,
  textoDoAgendamento,
} from "@/lib/exibicao-da-secao";

/*
  A caixa em volta de uma seção da página (a mesma para os três modelos):
  mostrar só no celular ou só no computador, o fundo da seção (cor, degradê
  ou imagem com camada escura) e o espaço acima e abaixo. Também marca a
  seção para a contagem de cliques da loja publicada (ContadorDeCliques).

  Seção sem nenhum desses ajustes, e sem contagem, sai sem caixa nenhuma:
  exatamente o desenho de sempre.

  No editor nada some: a seção agendada fora da janela e a seção do outro
  aparelho aparecem apagadas, com o selo dizendo por quê. O "ver como se
  estivesse no ar" do painel (previa_no_ar) acende a agendada.
*/

export type Familia = "padrao" | "vitrine" | "vendor" | "boutique";

const LARGURA_DA_CAIXA: Record<Familia, string> = {
  padrao: "max-w-7xl px-4 sm:px-6 lg:px-8",
  vitrine: "max-w-[1400px] px-4",
  vendor: "max-w-6xl px-4",
  /* O container da Boutique (o mesmo dos blocos dela, CONTEUDO em
     templates/boutique/BoutiqueWidgetsDaHome.tsx): até 1240 px. */
  boutique: "max-w-[1240px] px-4 md:px-6",
};

/* A caixa contida tem o canto da família: a Boutique é reta (raio 0 em
   cards, fotos e blocos, REFERENCIA.md 2.5); as outras seguem com 22 px. */
const CANTO_DA_CAIXA: Record<Familia, string> = {
  padrao: "rounded-[22px]",
  vitrine: "rounded-[22px]",
  vendor: "rounded-[22px]",
  boutique: "",
};

type SecaoDaCaixa = { id: string; config?: unknown; previa_no_ar?: boolean };

/**
 * A seção com fundo próprio não pinta o fundo de sempre por cima (os temas
 * Padrão e Vitrine pintam background_color). Vazio, e não "transparent": o
 * React nem escreve o estilo, e a regra do texto claro não confunde a seção
 * com um cartão de fundo próprio.
 */
export function semFundoDeSempre<S extends { config?: unknown; background_color?: string }>(secao: S): S {
  const fundo = lerExibicao(configDaSecao(secao.config)).fundo;
  return fundo && fundo.tipo !== "nenhum" ? { ...secao, background_color: "" } : secao;
}

function Selo({ children, className = "" }: { children: ReactNode; className?: string }) {
  return (
    <span
      data-ks-editor-ui
      className={`pointer-events-none items-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-bold leading-none text-white shadow-md ${className}`}
    >
      {children}
    </span>
  );
}

export function CaixaDaSecao({
  secao,
  familia,
  contarCliques = false,
  children,
}: {
  secao: SecaoDaCaixa;
  familia: Familia;
  contarCliques?: boolean;
  children: ReactNode;
}) {
  const editor = useNoEditor();
  const exibicao = lerExibicao(configDaSecao(secao.config));
  const { agendamento, dispositivo, fundo } = exibicao;
  const noEditor = Boolean(editor);
  const agendadaNoEditor = noEditor && agendamento !== null;

  if (dispositivo === "todos" && !fundo && !agendadaNoEditor && !(contarCliques && !noEditor)) return <>{children}</>;

  const pontoDeTroca = familia === "vendor" || familia === "boutique" ? familia : "padrao";
  /* Na loja publicada, a seção do outro aparelho some só pelo CSS. No editor ela fica, apagada. */
  const classesDoAparelho = noEditor ? "" : classesDoDispositivo(dispositivo, pontoDeTroca);
  const lg = pontoDeTroca !== "padrao";
  const apagadaNoOutroAparelho =
    noEditor && dispositivo === "celular" ? (lg ? "lg:opacity-35" : "md:opacity-35") : noEditor && dispositivo === "computador" ? (lg ? "max-lg:opacity-35" : "max-md:opacity-35") : "";
  const momento = momentoDoAgendamento(agendamento, Date.now());
  const foraDoAr = agendadaNoEditor && (momento === "antes" || momento === "depois") && !secao.previa_no_ar;

  const espacos = fundo ? `${fundo.acima ? ESPACO_ACIMA[fundo.acima] : ""} ${fundo.abaixo ? ESPACO_ABAIXO[fundo.abaixo] : ""}`.trim() : "";
  const estiloDoFundo = (fundo ? fundoEmCss(fundo) : {}) as CSSProperties;

  /* O fundo é uma camada à parte (não fica no estilo de quem contém os
     textos): a regra do texto claro (app/globals.css) não pinta de branco o
     que está dentro de cartões e botões, que têm fundo próprio. */
  let conteudo: ReactNode = children;
  if (fundo) {
    const camada = fundo.tipo !== "nenhum" ? <div aria-hidden className="absolute inset-0" style={estiloDoFundo} /> : null;
    const marcaDoTexto = fundo.textoClaro ? { "data-ks-texto-claro": "" } : {};
    conteudo =
      fundo.largura === "contida" && fundo.tipo !== "nenhum" ? (
        <div className={`mx-auto w-full ${LARGURA_DA_CAIXA[familia]} py-3`}>
          <div className={`relative isolate overflow-hidden ${CANTO_DA_CAIXA[familia] ? `${CANTO_DA_CAIXA[familia]} ` : ""}${espacos}`} {...marcaDoTexto}>
            {camada}
            <div className="relative">{children}</div>
          </div>
        </div>
      ) : (
        <div className={`relative isolate ${espacos}`} {...marcaDoTexto}>
          {camada}
          <div className="relative">{children}</div>
        </div>
      );
  }

  return (
    <div
      data-ks-cliques={contarCliques && !noEditor ? secao.id : undefined}
      data-ks-dispositivo={dispositivo !== "todos" ? dispositivo : undefined}
      className={`${classesDoAparelho} ${noEditor ? "relative" : ""}`.trim() || undefined}
    >
      {apagadaNoOutroAparelho || foraDoAr ? <div className={`${apagadaNoOutroAparelho} ${foraDoAr ? "opacity-35" : ""}`.trim()}>{conteudo}</div> : conteudo}
      {noEditor && (agendamento || dispositivo !== "todos") ? (
        <div
          className="pointer-events-none absolute left-2 z-[34] flex max-w-[90%] flex-col items-start gap-1.5"
          style={{ top: 8 + 34 * (editor?.zoom ?? 1), transform: `scale(${editor?.zoom ?? 1})`, transformOrigin: "top left" }}
        >
          {agendamento ? (
            <Selo className={`flex ${foraDoAr ? "bg-[#b45309]" : "bg-[#0f766e]"}`}>
              <CalendarClock className="h-3.5 w-3.5" />
              {textoDoAgendamento(agendamento)}
              {foraDoAr ? " · fora do ar agora" : momento === "no_ar" ? " · no ar agora" : " · vendo como no ar"}
            </Selo>
          ) : null}
          {dispositivo === "celular" ? (
            <Selo className={`hidden bg-[#1d4ed8] ${lg ? "lg:flex" : "md:flex"}`}>
              <Smartphone className="h-3.5 w-3.5" /> Só aparece no celular
            </Selo>
          ) : dispositivo === "computador" ? (
            <Selo className={`flex bg-[#1d4ed8] ${lg ? "lg:hidden" : "md:hidden"}`}>
              <Monitor className="h-3.5 w-3.5" /> Só aparece no computador
            </Selo>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}
