"use client";

import { useMemo, useState, type CSSProperties, type ReactNode } from "react";
import Link from "next/link";
import { ChevronLeft, ChevronRight, ImagePlus } from "lucide-react";
import {
  FORMATOS_DE_BANNER,
  PROPORCOES_DA_IMAGEM,
  configDaSecao,
  destinoDaSecao,
  fotosDasCategorias,
  lerBanner,
  lerCarrossel,
  lerGrade,
  modoDaSecao,
  quantidadeDeProdutos,
  type EspacoVertical,
  type ImagemDaSecao,
  type LinkDaSecao,
} from "@/lib/pagina-inicial";
import { useCarrossel } from "@/lib/use-carrossel";
import { miniatura } from "@/lib/foto";
import { useNoEditor } from "@/components/editor-da-loja/contexto";
import { VendorCardDoProduto, type VendorProduto } from "./VendorCardDoProduto";
import { VendorCirculosDeItens, VendorSecaoDeProdutos } from "./VendorBlocosDaHome";
import type { VendorCategoria } from "./VendorShell";
import { ehWidget } from "@/lib/widgets-da-home";
import { VendorWidgetDaHome } from "./VendorWidgetsDaHome";
import { CaixaDaSecao } from "@/components/home/CaixaDaSecao";

/*
  A home do Vendor montada pelo editor do painel.

  Vale só para a loja Vendor que publicou a página inicial pelo editor (há
  publicação em catalog_home_publicacoes). As outras seguem com a home
  automática do VendorHome. O desenho é o do Vendor: as cores e o tamanho de
  título das seções (que os temas Padrão e Vitrine usam) não entram aqui; o
  Vendor tem a própria linguagem.

  Banner principal, tarja e stories continuam no topo, fixos, como na home
  automática: o editor monta o que vem depois deles.
*/

export type VendorSecaoDaHome = {
  id: string;
  title?: string | null;
  layout_width?: string | null;
  section_type?: string | null;
  config?: unknown;
  /* Produtos escolhidos à mão, já montados pela página. */
  products?: VendorProduto[];
  /* Só no editor: a agendada fora da janela aparece como se estivesse no ar. */
  previa_no_ar?: boolean;
};

type Contexto = {
  slug: string;
  produtos: VendorProduto[];
  categorias: VendorCategoria[];
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
};

const MARGEM: Record<EspacoVertical, string> = { nenhum: "py-0", pequeno: "pt-3", normal: "py-6" };
const LOTE = 40;

function LinkDaSecaoVendor({
  link,
  ctx,
  className,
  style,
  children,
  rotulo,
}: {
  link: LinkDaSecao;
  ctx: Contexto;
  className?: string;
  style?: CSSProperties;
  children: ReactNode;
  rotulo?: string;
}) {
  const destino = destinoDaSecao(link, ctx.slug, ctx.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} {...alvo}>
        {children}
      </a>
    );
  }
  return (
    <Link href={destino.href} className={className} style={style} aria-label={rotulo} {...alvo}>
      {children}
    </Link>
  );
}

function Vazio({ texto, style }: { texto: string; style?: CSSProperties }) {
  return (
    <div
      className="flex flex-col items-center justify-center gap-2 border-2 border-dashed text-[var(--vd-muted-fg)]"
      style={{ borderRadius: "var(--vd-radius-2xl)", borderColor: "var(--vd-border)", backgroundColor: "var(--vd-muted-bg)", ...style }}
    >
      <ImagePlus className="h-6 w-6" />
      <span className="px-3 text-center text-xs font-semibold">{texto}</span>
    </div>
  );
}

function Foto({ item, alt }: { item: { imagem: string; imagem_celular?: string }; alt: string }) {
  if (item.imagem_celular) {
    return (
      <picture>
        <source media="(max-width: 639px)" srcSet={miniatura(item.imagem_celular, 900)} />
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img src={miniatura(item.imagem, 1600)} alt={alt} loading="lazy" className="absolute inset-0 h-full w-full object-cover" draggable={false} />
      </picture>
    );
  }
  // eslint-disable-next-line @next/next/no-img-element
  return <img src={miniatura(item.imagem, 1600)} alt={alt} loading="lazy" className="absolute inset-0 h-full w-full object-cover" draggable={false} />;
}

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

const COLUNAS: Record<string, string> = {
  "2": "sm:grid-cols-2",
  "3": "sm:grid-cols-3",
  "4": "sm:grid-cols-2 lg:grid-cols-4",
  "1+2": "sm:grid-cols-2 sm:grid-rows-2",
  "2+1": "sm:grid-cols-2 sm:grid-rows-2",
};
const LUGAR: Record<string, string[]> = {
  "1+2": ["sm:col-start-1 sm:row-start-1 sm:row-span-2", "sm:col-start-2 sm:row-start-1", "sm:col-start-2 sm:row-start-2"],
  "2+1": ["sm:col-start-1 sm:row-start-1", "sm:col-start-1 sm:row-start-2", "sm:col-start-2 sm:row-start-1 sm:row-span-2"],
};
const ESPACO: Record<string, string> = { nenhum: "gap-0", pequeno: "gap-2", medio: "gap-3" };
const RAIO: Record<string, string> = { retos: "0px", suaves: "var(--vd-radius-xl)", redondos: "var(--vd-radius-2xl)" };

function VendorImagensLadoALado({ secao, ctx }: { secao: VendorSecaoDaHome; ctx: Contexto }) {
  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 visiveis = editor ? itens : itens.filter((item) => item?.imagem);
  if (!visiveis.length) return null;

  const mosaico = grade.layout === "1+2" || grade.layout === "2+1";
  const proporcao = PROPORCOES_DA_IMAGEM[grade.proporcao].proporcao;
  /* No celular: em trilho (um por vez, como o banner duplo), dois por linha
     ou um embaixo do outro. */
  const noCelular =
    grade.celular === "deslizar"
      ? "vd-sem-barra flex snap-x overflow-x-auto sm:grid sm:overflow-visible"
      : grade.celular === "lado_a_lado"
        ? "grid grid-cols-2"
        : "grid grid-cols-1";
  /* Duas imagens: uma por vez, como o banner duplo. Mais que isso: a próxima
     aparece pela metade, para contar que tem mais. */
  const larguraDoItem =
    grade.celular === "deslizar" ? `${quantas === 2 ? "w-full" : "w-[84%]"} shrink-0 snap-start sm:w-auto` : "";

  return (
    <div className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[grade.margem]}`}>
      {grade.mostrarTitulo && secao.title ? (
        <div className="mb-6 flex items-center justify-center gap-4">
          <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
          <h2 className="text-center text-base font-bold sm:text-xl">{secao.title}</h2>
          <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
        </div>
      ) : null}
      <div className={`${noCelular} ${COLUNAS[grade.layout]} ${ESPACO[grade.espaco]}`}>
        {visiveis.map((item, indice) => {
          const lugar = mosaico ? LUGAR[grade.layout][indice] || "" : "";
          const grande = lugar.includes("row-span-2");
          const medida = grande ? "aspect-[var(--proporcao)] sm:aspect-auto sm:h-full" : "aspect-[var(--proporcao)]";
          const estilo = { ["--proporcao" as string]: String(proporcao), borderRadius: RAIO[grade.cantos] } as CSSProperties;
          if (!item?.imagem) {
            return (
              <div key={`vazio-${indice}`} className={`${larguraDoItem} ${lugar} ${medida}`} style={estilo}>
                <Vazio texto={`Imagem ${indice + 1}`} style={{ height: "100%", borderRadius: RAIO[grade.cantos] }} />
              </div>
            );
          }
          return (
            <LinkDaSecaoVendor
              key={`${item.imagem}-${indice}`}
              link={item.link}
              ctx={ctx}
              rotulo={item.legenda || undefined}
              className={`group relative block overflow-hidden bg-[var(--vd-muted-bg)] ${larguraDoItem} ${lugar} ${medida}`}
              style={estilo}
            >
              <Foto item={item} alt={item.legenda || ""} />
              {item.legenda ? (
                <span className="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-8 text-[13px] font-semibold text-white sm:text-sm">
                  {item.legenda}
                </span>
              ) : null}
            </LinkDaSecaoVendor>
          );
        })}
      </div>
    </div>
  );
}

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

function VendorCarrossel({ secao, ctx }: { secao: VendorSecaoDaHome; ctx: Contexto }) {
  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 = String(FORMATOS_DE_BANNER[carrossel.formato].proporcao);

  if (!itens.length) {
    if (!editor) return null;
    return (
      <div className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[carrossel.margem]}`}>
        <Vazio texto="Carrossel de banners: adicione as imagens no painel" style={{ aspectRatio: proporcao }} />
      </div>
    );
  }

  return (
    <div className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[carrossel.margem]}`}>
      <div
        className="relative w-full overflow-hidden bg-[var(--vd-muted-bg)]"
        style={{ borderRadius: "var(--vd-radius-2xl)", aspectRatio: proporcao }}
        {...eventos}
      >
        <div className="flex h-full will-change-transform" style={{ transform: `translateX(-${atual * 100}%)`, transition: "transform 500ms ease-in-out" }}>
          {itens.map((item, indice) => (
            <LinkDaSecaoVendor key={`${item.imagem}-${indice}`} link={item.link} ctx={ctx} rotulo={`Banner ${indice + 1}`} className="relative h-full min-w-full shrink-0">
              <Foto item={item} alt={item.legenda || ""} />
            </LinkDaSecaoVendor>
          ))}
        </div>
        {itens.length > 1 ? (
          <>
            <button
              type="button"
              aria-label="Banner anterior"
              onClick={anterior}
              className="absolute left-3 top-1/2 hidden h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full border bg-[var(--vd-surface)] shadow sm:flex"
              style={{ borderColor: "var(--vd-border)" }}
            >
              <ChevronLeft className="h-4 w-4" />
            </button>
            <button
              type="button"
              aria-label="Próximo banner"
              onClick={seguinte}
              className="absolute right-3 top-1/2 hidden h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full border bg-[var(--vd-surface)] shadow sm:flex"
              style={{ borderColor: "var(--vd-border)" }}
            >
              <ChevronRight className="h-4 w-4" />
            </button>
            <div className="absolute bottom-3 left-1/2 flex -translate-x-1/2 gap-1.5">
              {itens.map((_, i) => (
                <button
                  key={i}
                  type="button"
                  aria-label={`Banner ${i + 1}`}
                  onClick={() => ir(i)}
                  className="h-1.5 rounded-full transition-all"
                  style={{ width: i === atual ? 20 : 6, backgroundColor: i === atual ? "#ffffff" : "rgba(255,255,255,0.55)" }}
                />
              ))}
            </div>
          </>
        ) : null}
      </div>
    </div>
  );
}

/* --------------------------------------------------------- banner */

function VendorBannerDaSecao({ secao, ctx }: { secao: VendorSecaoDaHome; ctx: Contexto }) {
  const editor = useNoEditor();
  const banner = lerBanner(configDaSecao(secao.config));
  const proporcao = String(FORMATOS_DE_BANNER[banner.formato || "faixa"].proporcao);
  if (!banner.imagem) {
    if (!editor) return null;
    return (
      <div className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[banner.margem]}`}>
        <Vazio texto="Banner: escolha a imagem no painel" style={{ aspectRatio: proporcao }} />
      </div>
    );
  }
  const temTexto = Boolean(banner.titulo || banner.subtitulo || banner.botao) && banner.formato !== "faixa" && Boolean(banner.formato);
  const claro = banner.tom === "claro";
  const centro = banner.alinhamento === "centro";
  return (
    <div className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[banner.margem]}`}>
      <LinkDaSecaoVendor
        link={banner.link}
        ctx={ctx}
        rotulo={banner.titulo || secao.title || "Banner"}
        className="group relative block w-full overflow-hidden bg-[var(--vd-muted-bg)]"
        style={{ borderRadius: "var(--vd-radius-2xl)", aspectRatio: proporcao }}
      >
        <Foto item={{ imagem: banner.imagem, imagem_celular: banner.imagemCelular }} alt={banner.titulo || secao.title || ""} />
        {temTexto ? (
          <>
            <span
              className={`pointer-events-none absolute inset-0 ${
                claro
                  ? centro
                    ? "bg-black/35"
                    : "bg-gradient-to-r from-black/60 via-black/25 to-transparent"
                  : centro
                    ? "bg-white/45"
                    : "bg-gradient-to-r from-white/85 via-white/40 to-transparent"
              }`}
            />
            <span
              className={`absolute inset-0 flex flex-col justify-center gap-1.5 px-5 sm:gap-2.5 sm:px-12 ${centro ? "items-center text-center" : "items-start text-left"}`}
              style={{ color: claro ? "#ffffff" : "var(--vd-foreground)" }}
            >
              {banner.titulo ? <span className="max-w-xl text-lg font-bold leading-tight sm:text-3xl">{banner.titulo}</span> : null}
              {banner.subtitulo ? <span className="hidden max-w-lg text-sm opacity-90 sm:block">{banner.subtitulo}</span> : null}
              {banner.botao ? (
                <span
                  className="mt-1 inline-flex h-9 items-center px-4 text-[13px] font-semibold text-white"
                  style={{ borderRadius: "var(--vd-radius-lg)", backgroundColor: ctx.corDaMarca || "var(--vd-primary)" }}
                >
                  {banner.botao}
                </span>
              ) : null}
            </span>
          </>
        ) : null}
      </LinkDaSecaoVendor>
    </div>
  );
}

/* ------------------------------------------------ todos os produtos */

function VendorTodosOsProdutos({ secao, ctx }: { secao: VendorSecaoDaHome; ctx: Contexto }) {
  const [quantos, setQuantos] = useState(LOTE);
  if (!ctx.produtos.length) return null;
  return (
    <section id="produtos" className="mx-auto w-full max-w-6xl scroll-mt-28 px-4 py-6">
      <div className="mb-8 flex items-center justify-center gap-4">
        <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
        <h2 className="text-center text-base font-bold sm:text-xl">{secao.title || "Todos os produtos"}</h2>
        <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
      </div>
      <div className="grid grid-cols-2 gap-x-3 gap-y-8 sm:gap-x-4 lg:grid-cols-4">
        {ctx.produtos.slice(0, quantos).map((produto) => (
          <VendorCardDoProduto
            key={produto.id}
            produto={produto}
            slug={ctx.slug}
            clienteId={ctx.clienteId}
            favoritos={ctx.favoritos}
            corDaMarca={ctx.corDaMarca}
          />
        ))}
      </div>
      {ctx.produtos.length > quantos ? (
        <div className="mt-8 flex justify-center">
          <button
            type="button"
            onClick={() => setQuantos((n) => n + LOTE)}
            className="border px-6 py-2.5 text-[13px] font-semibold transition-colors hover:bg-[var(--vd-muted-bg)]"
            style={{ borderRadius: "var(--vd-radius-lg)", borderColor: "var(--vd-border)" }}
          >
            Ver mais produtos ({ctx.produtos.length - quantos} restantes)
          </button>
        </div>
      ) : null}
    </section>
  );
}

/* ------------------------------------------------------- a seção */

function descendentes(id: string, categorias: VendorCategoria[]) {
  const achadas = new Set<string>([id]);
  const pilha = [id];
  while (pilha.length) {
    const atual = pilha.pop() as string;
    for (const c of categorias) {
      if (c.parent_id === atual && !achadas.has(c.id)) {
        achadas.add(c.id);
        pilha.push(c.id);
      }
    }
  }
  return achadas;
}

function VendorSecao({ secao, ctx, fotos }: { secao: VendorSecaoDaHome; ctx: Contexto; fotos: Map<string, string> }) {
  const editor = useNoEditor();
  const modo = modoDaSecao(secao);
  const config = configDaSecao(secao.config);
  const titulo = String(secao.title || "").trim();

  /* Os blocos novos (oferta, cupom, vídeo, perguntas...): VendorWidgetsDaHome. */
  if (ehWidget(modo)) return <VendorWidgetDaHome secao={secao} ctx={ctx} />;
  if (modo === "image_grid") return <VendorImagensLadoALado secao={secao} ctx={ctx} />;
  if (modo === "banner_carousel") return <VendorCarrossel secao={secao} ctx={ctx} />;
  if (modo === "image_banner") return <VendorBannerDaSecao secao={secao} ctx={ctx} />;
  if (modo === "all_products") return <VendorTodosOsProdutos secao={secao} ctx={ctx} />;

  if (modo === "category_circles") {
    const raizes = ctx.categorias.filter((c) => !c.parent_id);
    const limite = Number(config.limite) > 0 ? Math.min(12, Math.trunc(Number(config.limite))) : null;
    return (
      <VendorCirculosDeItens
        itens={raizes.map((categoria) => ({
          chave: categoria.id,
          href: `/${ctx.slug}/c/${categoria.slug || categoria.id}`,
          nome: categoria.name,
          foto: fotos.get(categoria.id) || null,
        }))}
        noComputador={limite ?? 6}
        noCelular={limite ?? 10}
      />
    );
  }

  if (modo === "category_navigator") {
    const itens = (Array.isArray(config.items) ? config.items : [])
      .map((bruto) => {
        const item = (bruto || {}) as Record<string, unknown>;
        const id = String(item.target_category_id || "");
        const categoria = ctx.categorias.find((c) => c.id === id || (item.target_category_slug && c.slug === item.target_category_slug));
        const caminho = String(item.target_category_slug || categoria?.slug || "");
        if (!caminho) return null;
        return {
          chave: `${id || caminho}`,
          href: `/${ctx.slug}/c/${caminho}`,
          nome: String(item.label || "").trim() || categoria?.name || "Categoria",
          foto: String(item.image_url || "") || (categoria ? fotos.get(categoria.id) : null) || null,
        };
      })
      .filter((item): item is NonNullable<typeof item> => Boolean(item))
      .slice(0, 12);
    if (!itens.length) {
      return editor ? (
        <div className="mx-auto w-full max-w-6xl px-4 py-6">
          <Vazio texto="Atalhos de categorias: escolha as categorias no painel" style={{ minHeight: 120 }} />
        </div>
      ) : null;
    }
    return <VendorCirculosDeItens itens={itens} noComputador={12} noCelular={12} />;
  }

  /* As seções de produtos. */
  let produtos: VendorProduto[] = [];
  let verTudo: string | null = null;
  let limite = 4;
  if (modo === "manual_products") {
    produtos = secao.products || [];
    limite = 48;
  } else if (modo === "featured_products") {
    limite = quantidadeDeProdutos(config, 4);
    produtos = ctx.produtos.slice(0, limite);
  } else if (modo === "category_products" || modo === "subcategory_products") {
    const alvo = String(config.target_category_id || "");
    const categoria = ctx.categorias.find((c) => c.id === alvo);
    if (categoria) {
      const ids = modo === "subcategory_products" || config.so_da_categoria === true ? new Set([alvo]) : descendentes(alvo, ctx.categorias);
      produtos = ctx.produtos.filter((p) => ids.has(String((p as VendorProduto & { category_id?: string }).category_id || "")));
      if (config.show_view_more !== false) verTudo = `/${ctx.slug}/c/${categoria.slug || categoria.id}`;
    }
    limite = quantidadeDeProdutos(config, 4);
  }

  if (!produtos.length) {
    return editor ? (
      <div className="mx-auto w-full max-w-6xl px-4 py-6">
        <Vazio texto={`${titulo || "Seção"}: nenhum produto para mostrar ainda`} style={{ minHeight: 140 }} />
      </div>
    ) : null;
  }

  return (
    <VendorSecaoDeProdutos
      titulo={titulo || "Produtos"}
      produtos={produtos}
      slug={ctx.slug}
      verTudoHref={verTudo}
      clienteId={ctx.clienteId}
      favoritos={ctx.favoritos}
      corDaMarca={ctx.corDaMarca}
      limite={limite}
    />
  );
}

export function VendorSecoesDaHome({
  secoes,
  envolver,
  contarCliques = false,
  ...ctx
}: Contexto & {
  secoes: VendorSecaoDaHome[];
  /* Só o editor passa: a moldura de cada seção. */
  envolver?: (secao: VendorSecaoDaHome, indice: number, conteudo: ReactNode) => ReactNode;
  /* A loja montada pelo editor conta os cliques de cada seção (migration 199). */
  contarCliques?: boolean;
}) {
  const fotos = useMemo(() => fotosDasCategorias(ctx.produtos as never), [ctx.produtos]);
  return (
    <>
      {secoes.map((secao, indice) => {
        /* A caixa comum de toda seção (aparelho, fundo, espaço): sem ajuste, a seção sai sozinha. */
        const conteudo = (
          <CaixaDaSecao key={secao.id} secao={secao} familia="vendor" contarCliques={contarCliques}>
            <VendorSecao secao={secao} ctx={ctx} fotos={fotos} />
          </CaixaDaSecao>
        );
        return envolver ? envolver(secao, indice, conteudo) : conteudo;
      })}
    </>
  );
}
