"use client";

import Link from "next/link";
import type { CSSProperties, ReactNode } from "react";
import { ChevronLeft, ChevronRight, ImagePlus } from "lucide-react";
import {
  FORMATOS_DE_BANNER,
  PROPORCOES_DA_IMAGEM,
  configDaSecao,
  destinoDaSecao,
  lerBanner,
  lerCarrossel,
  lerGrade,
  modoDaSecao,
  type EspacoVertical,
  type ImagemDaSecao,
  type LinkDaSecao,
} from "@/lib/pagina-inicial";
import { miniatura } from "@/lib/foto";
import { useCarrossel } from "@/lib/use-carrossel";
import { useNoEditor } from "@/components/editor-da-loja/contexto";
import { ehWidget } from "@/lib/widgets-da-home";
import { WidgetDaHome } from "./WidgetsDaHome";

/*
  As seções novas da página inicial nos temas Padrão e Vitrine: imagens lado
  a lado, carrossel de banners e o banner com formato. Os tipos antigos
  continuam desenhados no StoreContent, como sempre; este arquivo só entra
  quando a loja põe um tipo novo pelo editor.

  O Vendor tem os seus em templates/vendor (desenho isolado).
*/

export type SecaoNova = {
  id: string;
  title?: string | null;
  text_color?: string | null;
  layout_width?: string | null;
  title_align?: string | null;
  title_size?: string | null;
  section_type?: string | null;
  config?: unknown;
};

type Variante = "padrao" | "vitrine";

/** Se a seção é desenhada aqui (e não pelo caminho antigo do StoreContent). */
export function ehSecaoNovaDaHome(secao: SecaoNova) {
  const modo = modoDaSecao(secao);
  if (modo === "image_grid" || modo === "banner_carousel") return true;
  /* Os blocos novos (lib/widgets-da-home.ts), desenhados em WidgetsDaHome. */
  if (ehWidget(modo)) return true;
  return modo === "image_banner" && Boolean(lerBanner(configDaSecao(secao.config)).formato);
}

const MARGEM: Record<EspacoVertical, string> = {
  nenhum: "py-0",
  pequeno: "py-3 md:py-5",
  normal: "py-6 md:py-10",
};

function caixa(variante: Variante) {
  return variante === "vitrine" ? "mx-auto w-full max-w-[1400px] px-4 md:px-8" : "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8";
}

function raioDaCaixa(variante: Variante) {
  return variante === "vitrine" ? "rounded-[18px]" : "rounded-2xl md:rounded-3xl";
}

function TituloDaSecao({ secao, variante }: { secao: SecaoNova; variante: Variante }) {
  if (!secao.title) return null;
  const alinhamento = secao.title_align === "left" ? "text-left" : secao.title_align === "right" ? "text-right" : "text-center";
  const tamanho =
    variante === "vitrine"
      ? "text-3xl font-semibold tracking-tight"
      : secao.title_size === "sm"
        ? "text-xl md:text-2xl font-bold"
        : secao.title_size === "md"
          ? "text-2xl md:text-3xl font-bold"
          : secao.title_size === "xl"
            ? "text-4xl md:text-5xl font-bold"
            : "text-3xl md:text-4xl font-bold";
  return (
    <h2 className={`catalog-section-title mb-4 md:mb-6 ${alinhamento} ${tamanho}`} style={{ color: secao.text_color || undefined }}>
      {secao.title}
    </h2>
  );
}

function ComLink({
  link,
  slug,
  categorias,
  className,
  style,
  children,
  rotulo,
}: {
  link: LinkDaSecao;
  slug: string;
  categorias: Array<{ id: string; slug?: string | null }>;
  className?: string;
  style?: CSSProperties;
  children: ReactNode;
  rotulo?: string;
}) {
  const destino = destinoDaSecao(link, slug, categorias);
  if (!destino) {
    return (
      <div className={className} style={style}>
        {children}
      </div>
    );
  }
  const alvo = destino.novaAba ? { target: "_blank", rel: "noopener noreferrer" } : {};
  if (destino.externo) {
    return (
      <a href={destino.href} className={className} style={style} aria-label={rotulo || undefined} {...alvo}>
        {children}
      </a>
    );
  }
  return (
    <Link href={destino.href} className={className} style={style} aria-label={rotulo || undefined} {...alvo}>
      {children}
    </Link>
  );
}

/* A foto, com a versão do celular quando a loja mandou uma. */
function Foto({ imagem, celular, largura, alt, className, prioridade }: { imagem: string; celular?: string; largura: number; alt: string; className: string; prioridade?: boolean }) {
  const principal = miniatura(imagem, largura);
  if (celular) {
    return (
      <picture>
        <source media="(max-width: 767px)" srcSet={miniatura(celular, 900)} />
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img src={principal} alt={alt} className={className} loading={prioridade ? "eager" : "lazy"} decoding="async" draggable={false} />
      </picture>
    );
  }
  // eslint-disable-next-line @next/next/no-img-element
  return <img src={principal} alt={alt} className={className} loading={prioridade ? "eager" : "lazy"} decoding="async" draggable={false} />;
}

function LugarVazio({ texto, className, style }: { texto: string; className?: string; style?: CSSProperties }) {
  return (
    <div
      className={`flex flex-col items-center justify-center gap-2 border-2 border-dashed border-violet-300 bg-violet-50/70 text-violet-700 ${className || ""}`}
      style={style}
    >
      <ImagePlus className="h-7 w-7" strokeWidth={1.8} />
      <span className="px-3 text-center text-xs font-semibold">{texto}</span>
    </div>
  );
}

/* ------------------------------------------------ imagens lado a lado */

const COLUNAS: Record<string, string> = {
  "2": "md:grid-cols-2",
  "3": "md:grid-cols-3",
  "4": "md:grid-cols-4",
  "1+2": "md:grid-cols-2 md:grid-rows-2",
  "2+1": "md:grid-cols-2 md:grid-rows-2",
};

const LUGAR_NO_MOSAICO: Record<string, string[]> = {
  "1+2": ["md:col-start-1 md:row-start-1 md:row-span-2", "md:col-start-2 md:row-start-1", "md:col-start-2 md:row-start-2"],
  "2+1": ["md:col-start-1 md:row-start-1", "md:col-start-1 md:row-start-2", "md:col-start-2 md:row-start-1 md:row-span-2"],
};

const ESPACO: Record<string, string> = { nenhum: "gap-0", pequeno: "gap-2 md:gap-3", medio: "gap-3 md:gap-5" };
const CANTOS: Record<string, string> = { retos: "rounded-none", suaves: "rounded-xl", redondos: "rounded-3xl" };

function GradeDeImagens({ secao, variante, slug, categorias }: { secao: SecaoNova; variante: Variante; slug: string; categorias: Array<{ id: string; slug?: string | null }> }) {
  const editor = useNoEditor();
  const grade = lerGrade(configDaSecao(secao.config));
  const quantas = grade.layout === "1+2" || grade.layout === "2+1" ? 3 : Number(grade.layout);
  const itens: Array<ImagemDaSecao | null> = Array.from({ length: quantas }, (_, i) => grade.itens[i] ?? null);
  const comImagem = itens.filter((item) => item?.imagem);
  if (!comImagem.length && !editor) return null;

  const mosaico = grade.layout === "1+2" || grade.layout === "2+1";
  const proporcao = PROPORCOES_DA_IMAGEM[grade.proporcao].proporcao;
  const celular =
    grade.celular === "deslizar"
      ? "flex snap-x snap-mandatory overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden md:grid md:overflow-visible"
      : grade.celular === "lado_a_lado"
        ? "grid grid-cols-2"
        : "grid grid-cols-1";
  const larguraNoCelular = grade.celular === "deslizar" ? "w-[84%] shrink-0 snap-start md:w-auto" : "";
  const inteira = secao.layout_width === "full";
  const visiveis = editor ? itens : itens.filter((item) => item?.imagem);

  return (
    <section className={`catalog-section catalog-section-image_grid ${MARGEM[grade.margem]}`}>
      <div className={inteira ? (grade.espaco === "nenhum" ? "w-full" : "w-full px-3 md:px-5") : caixa(variante)}>
        {grade.mostrarTitulo ? <TituloDaSecao secao={secao} variante={variante} /> : null}
        <div className={`${celular} ${COLUNAS[grade.layout]} ${ESPACO[grade.espaco]}`}>
          {visiveis.map((item, indice) => {
            const lugar = mosaico ? LUGAR_NO_MOSAICO[grade.layout][indice] || "" : "";
            const grande = mosaico && lugar.includes("row-span-2");
            const moldura = `relative block overflow-hidden ${CANTOS[grade.cantos]} ${larguraNoCelular} ${lugar}`;
            /* A proporção vai numa variável: a imagem grande do mosaico troca
               a proporção pela altura das duas pequenas a partir do md. */
            const estilo = { ["--proporcao" as string]: String(proporcao) } as CSSProperties;
            const medida = grande ? "aspect-[var(--proporcao)] md:aspect-auto md:h-full" : "aspect-[var(--proporcao)]";
            if (!item?.imagem) {
              return (
                <LugarVazio
                  key={`vazio-${indice}`}
                  texto={`Imagem ${indice + 1}`}
                  className={`${CANTOS[grade.cantos]} ${larguraNoCelular} ${lugar} ${medida}`}
                  style={estilo}
                />
              );
            }
            return (
              <ComLink
                key={`${item.imagem}-${indice}`}
                link={item.link}
                slug={slug}
                categorias={categorias}
                rotulo={item.legenda || undefined}
                className={`group ${moldura} ${medida} bg-gray-100`}
                style={estilo}
              >
                <Foto
                  imagem={item.imagem}
                  largura={grande || quantas <= 2 ? 1400 : 900}
                  alt={item.legenda || ""}
                  className="absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-[1.03]"
                />
                {item.legenda ? (
                  <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/65 via-black/25 to-transparent px-4 pb-3 pt-10 text-sm font-bold text-white md:text-base">
                    {item.legenda}
                  </span>
                ) : null}
              </ComLink>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* --------------------------------------------- carrossel de banners */

function CarrosselDeBanners({ secao, variante, slug, categorias }: { secao: SecaoNova; variante: Variante; slug: string; categorias: Array<{ id: string; slug?: string | null }> }) {
  const editor = useNoEditor();
  const carrossel = lerCarrossel(configDaSecao(secao.config));
  const itens = carrossel.itens.filter((item) => item.imagem);
  const { atual, ir, anterior, seguinte, eventos } = useCarrossel(itens.length, carrossel.automatico, carrossel.intervalo);
  const proporcao = FORMATOS_DE_BANNER[carrossel.formato].proporcao;
  const inteira = secao.layout_width === "full";
  const raio = inteira ? "" : raioDaCaixa(variante);

  if (!itens.length) {
    if (!editor) return null;
    return (
      <section className={`catalog-section ${MARGEM[carrossel.margem]}`}>
        <div className={inteira ? "w-full" : caixa(variante)}>
          <LugarVazio texto="Carrossel de banners: adicione as imagens no painel" className={raio} style={{ aspectRatio: String(proporcao) }} />
        </div>
      </section>
    );
  }

  return (
    <section className={`catalog-section catalog-section-banner_carousel ${MARGEM[carrossel.margem]}`}>
      <div className={inteira ? "w-full" : caixa(variante)}>
        {carrossel.mostrarTitulo ? <TituloDaSecao secao={secao} variante={variante} /> : null}
        <div className={`relative w-full overflow-hidden bg-gray-100 ${raio}`} style={{ aspectRatio: String(proporcao) }} {...eventos}>
          <div className="flex h-full will-change-transform" style={{ transform: `translateX(-${atual * 100}%)`, transition: "transform 550ms cubic-bezier(.22,.61,.36,1)" }}>
            {itens.map((item, indice) => (
              <ComLink
                key={`${item.imagem}-${indice}`}
                link={item.link}
                slug={slug}
                categorias={categorias}
                rotulo={item.legenda || `Banner ${indice + 1}`}
                className="relative block h-full min-w-full shrink-0"
              >
                <Foto
                  imagem={item.imagem}
                  celular={item.imagem_celular || undefined}
                  largura={1920}
                  alt={item.legenda || ""}
                  prioridade={indice === 0}
                  className="absolute inset-0 h-full w-full object-cover"
                />
              </ComLink>
            ))}
          </div>
          {itens.length > 1 ? (
            <>
              <button
                type="button"
                onClick={anterior}
                aria-label="Banner anterior"
                className="absolute left-3 top-1/2 hidden h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-white/85 text-gray-900 shadow-md backdrop-blur transition hover:bg-white md:flex"
              >
                <ChevronLeft size={20} />
              </button>
              <button
                type="button"
                onClick={seguinte}
                aria-label="Próximo banner"
                className="absolute right-3 top-1/2 hidden h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-white/85 text-gray-900 shadow-md backdrop-blur transition hover:bg-white md:flex"
              >
                <ChevronRight size={20} />
              </button>
              <div className="absolute inset-x-0 bottom-3 flex justify-center gap-1.5">
                {itens.map((_, indice) => (
                  <button
                    key={indice}
                    type="button"
                    onClick={() => ir(indice)}
                    aria-label={`Ir para o banner ${indice + 1}`}
                    className={`h-2 rounded-full shadow transition-all ${indice === atual ? "w-7 bg-white" : "w-2 bg-white/60 hover:bg-white/85"}`}
                  />
                ))}
              </div>
            </>
          ) : null}
        </div>
      </div>
    </section>
  );
}

/* -------------------------------------------------- banner com formato */

function BannerComFormato({ secao, variante, slug, categorias, corDaLoja }: { secao: SecaoNova; variante: Variante; slug: string; categorias: Array<{ id: string; slug?: string | null }>; corDaLoja: string }) {
  const editor = useNoEditor();
  const banner = lerBanner(configDaSecao(secao.config));
  const formato = banner.formato || "faixa";
  const proporcao = FORMATOS_DE_BANNER[formato].proporcao;
  const inteira = secao.layout_width === "full";
  const raio = inteira ? "" : raioDaCaixa(variante);
  const temTexto = Boolean(banner.titulo || banner.subtitulo || banner.botao);
  /* Faixa fina não tem altura para texto por cima. */
  const mostraTexto = temTexto && formato !== "faixa";

  if (!banner.imagem) {
    if (!editor) return null;
    return (
      <section className={`catalog-section ${MARGEM[banner.margem]}`}>
        <div className={inteira ? "w-full" : caixa(variante)}>
          <LugarVazio texto="Banner: escolha a imagem no painel" className={raio} style={{ aspectRatio: String(proporcao) }} />
        </div>
      </section>
    );
  }

  const claro = banner.tom === "claro";
  const centro = banner.alinhamento === "centro";
  const veu = claro
    ? centro
      ? "bg-black/35"
      : "bg-gradient-to-r from-black/65 via-black/30 to-transparent"
    : centro
      ? "bg-white/45"
      : "bg-gradient-to-r from-white/85 via-white/45 to-transparent";

  return (
    <section className={`catalog-section catalog-section-image_banner ${MARGEM[banner.margem]}`}>
      <div className={inteira ? "w-full" : caixa(variante)}>
        <ComLink
          link={banner.link}
          slug={slug}
          categorias={categorias}
          rotulo={banner.titulo || secao.title || "Banner"}
          className={`group relative block w-full overflow-hidden bg-gray-100 ${raio}`}
          style={{ aspectRatio: String(proporcao) }}
        >
          <Foto
            imagem={banner.imagem}
            celular={banner.imagemCelular || undefined}
            largura={1920}
            alt={banner.titulo || secao.title || ""}
            className="absolute inset-0 h-full w-full object-cover"
          />
          {mostraTexto ? (
            <>
              <span className={`pointer-events-none absolute inset-0 ${veu}`} />
              <span
                className={`absolute inset-0 flex flex-col justify-center gap-2 px-5 sm:px-10 md:gap-3 md:px-16 ${centro ? "items-center text-center" : "items-start text-left"}`}
                style={{ color: claro ? "#ffffff" : "#111827" }}
              >
                {banner.titulo ? (
                  <span className="max-w-2xl text-xl font-extrabold leading-tight tracking-tight sm:text-3xl md:text-5xl">{banner.titulo}</span>
                ) : null}
                {banner.subtitulo ? (
                  <span className="hidden max-w-xl text-sm font-medium opacity-90 sm:block md:text-lg">{banner.subtitulo}</span>
                ) : null}
                {banner.botao ? (
                  <span
                    className="mt-1 inline-flex items-center rounded-full px-4 py-2 text-xs font-bold shadow-lg transition group-hover:brightness-110 sm:px-6 sm:py-3 sm:text-sm"
                    style={{ backgroundColor: corDaLoja, color: "#ffffff" }}
                  >
                    {banner.botao}
                  </span>
                ) : null}
              </span>
            </>
          ) : null}
        </ComLink>
      </div>
    </section>
  );
}

/** Desenha uma seção nova (ver ehSecaoNovaDaHome). */
export function SecaoNovaDaHome({
  secao,
  variante,
  slug,
  categorias,
  corDaLoja,
  produtos,
}: {
  secao: SecaoNova;
  variante: Variante;
  slug: string;
  categorias: Array<{ id: string; slug?: string | null }>;
  corDaLoja: string;
  /* Os produtos da loja (os blocos de oferta, kits, vistos e pontos escolhem daqui). */
  produtos?: Array<{ id: string; name: string } & Record<string, unknown>>;
}) {
  const modo = modoDaSecao(secao);
  if (ehWidget(modo)) {
    return <WidgetDaHome secao={secao} variante={variante} slug={slug} categorias={categorias} corDaLoja={corDaLoja} produtos={produtos ?? []} />;
  }
  if (modo === "image_grid") return <GradeDeImagens secao={secao} variante={variante} slug={slug} categorias={categorias} />;
  if (modo === "banner_carousel") return <CarrosselDeBanners secao={secao} variante={variante} slug={slug} categorias={categorias} />;
  return <BannerComFormato secao={secao} variante={variante} slug={slug} categorias={categorias} corDaLoja={corDaLoja} />;
}
