"use client";

import { vendidoPorMedida } from "@/lib/adicionais";
import { useEffect, useRef, useState } from "react";
import { Check, HelpCircle, X } from "lucide-react";
import type { GrupoNaVitrine, ServicoOpcional } from "@/lib/servicos-opcionais";
import { useVisaoDaLoja } from "@/components/VisaoDaLojaContext";

/*
  Os serviços que a loja oferece junto com a peça.

  Ficam por último, logo acima do total — depois que o cliente já decidiu o
  que quer, na hora em que "quer que a gente faça a arte?" é uma pergunta
  bem-vinda e não uma distração.

  Três coisas que este arquivo faz questão de acertar:

  1. O título é o nome que o lojista deu ao grupo. "SERVIÇOS" fixo dizia menos
     do que "ACABAMENTO" ou "PRAZO DE ENTREGA".
  2. Só grupo obrigatório pede alguma coisa. Sem isso, uma frase como
     "escolha uma opção" em cima de um serviço opcional faz o cliente achar
     que precisa contratar algo para comprar — e o que está ali é oferta.
  3. O "?" só existe quando há texto para mostrar, e mostrar é a função dele.
     Ícone de ajuda que não ajuda é enfeite que ensina o cliente a ignorar.
*/

function Ajuda({ texto, corDaLoja }: { texto: string; corDaLoja: string }) {
  const [aberto, setAberto] = useState(false);
  const caixa = useRef<HTMLSpanElement | null>(null);

  useEffect(() => {
    if (!aberto) return;
    const foraDaCaixa = (evento: MouseEvent | TouchEvent) => {
      if (!caixa.current?.contains(evento.target as Node)) setAberto(false);
    };
    const comEsc = (evento: KeyboardEvent) => {
      if (evento.key === "Escape") {
        evento.stopPropagation();
        setAberto(false);
      }
    };
    document.addEventListener("mousedown", foraDaCaixa);
    document.addEventListener("touchstart", foraDaCaixa);
    document.addEventListener("keydown", comEsc);
    return () => {
      document.removeEventListener("mousedown", foraDaCaixa);
      document.removeEventListener("touchstart", foraDaCaixa);
      document.removeEventListener("keydown", comEsc);
    };
  }, [aberto]);

  return (
    <span ref={caixa} className="relative inline-flex">
      {/* Um <span> com papel de botão: o cartão inteiro já é um <button>, e
          botão dentro de botão não existe em HTML. */}
      <span
        role="button"
        tabIndex={0}
        aria-label="O que está incluso"
        aria-expanded={aberto}
        onClick={(evento) => {
          evento.preventDefault();
          evento.stopPropagation();
          setAberto((antes) => !antes);
        }}
        onKeyDown={(evento) => {
          if (evento.key !== "Enter" && evento.key !== " ") return;
          evento.preventDefault();
          evento.stopPropagation();
          setAberto((antes) => !antes);
        }}
        className="inline-flex cursor-help items-center text-zinc-400 transition-colors hover:text-zinc-600"
      >
        <HelpCircle size={13} />
      </span>

      {aberto ? (
        <span
          role="tooltip"
          onClick={(evento) => evento.stopPropagation()}
          className="absolute bottom-full left-1/2 z-30 mb-2 w-60 -translate-x-1/2 rounded-xl border border-zinc-200 bg-white p-3 text-left shadow-[0_8px_28px_rgba(0,0,0,0.12)]"
        >
          <span className="flex items-start gap-2">
            <span className="flex-1 text-[12px] leading-relaxed text-zinc-600">{texto}</span>
            <span
              role="button"
              tabIndex={0}
              aria-label="Fechar"
              onClick={(evento) => {
                evento.preventDefault();
                evento.stopPropagation();
                setAberto(false);
              }}
              onKeyDown={(evento) => {
                if (evento.key !== "Enter" && evento.key !== " ") return;
                evento.preventDefault();
                setAberto(false);
              }}
              className="mt-0.5 shrink-0 cursor-pointer text-zinc-300 hover:text-zinc-500"
            >
              <X size={12} />
            </span>
          </span>
          <span
            className="absolute left-1/2 top-full h-2.5 w-2.5 -translate-x-1/2 -translate-y-1/2 rotate-45 border-b border-r border-zinc-200 bg-white"
            style={{ borderColor: `${corDaLoja}22` }}
          />
        </span>
      ) : null}
    </span>
  );
}

function CartaoDoServico({
  servico,
  marcado,
  corDaLoja,
  formatarDinheiro,
  aoEscolher,
  porPeca,
}: {
  servico: ServicoOpcional;
  marcado: boolean;
  corDaLoja: string;
  formatarDinheiro: (valor: number) => string;
  aoEscolher: () => void;
  /* "por peça" no produto por m²; "por unidade" no resto. */
  porPeca: string;
}) {
  /* Sem preco para este visitante, o servico aparece sem valor nenhum: nem
     "Grátis" (que seria mentira) nem o preco. */
  const { mostrarPreco } = useVisaoDaLoja();
  return (
    <button
      type="button"
      onClick={aoEscolher}
      aria-pressed={marcado}
      className="group relative flex w-full items-center gap-3 rounded-2xl border bg-white p-3 text-left transition-all hover:shadow-[0_2px_10px_rgba(0,0,0,0.05)]"
      style={{
        borderColor: marcado ? corDaLoja : "#e4e4e7",
        boxShadow: marcado ? `0 0 0 1px ${corDaLoja}` : undefined,
        backgroundColor: marcado ? `${corDaLoja}08` : "#fff",
      }}
    >
      <span
        className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl transition-colors"
        style={{ backgroundColor: marcado ? `${corDaLoja}1a` : "#f4f4f5" }}
      >
        {/* A arte da casa, não um contorno genérico. */}
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img
          src={`/icones/servicos/${servico.icone}.svg`}
          alt=""
          width={26}
          height={26}
          style={{ width: 26, height: 26 }}
        />
      </span>

      <span className="min-w-0 flex-1">
        <span className="flex items-center gap-1.5">
          <span className="truncate text-[13.5px] font-semibold text-zinc-900">{servico.titulo}</span>
          {servico.detalhes ? <Ajuda texto={servico.detalhes} corDaLoja={corDaLoja} /> : null}
        </span>
        {servico.descricao ? (
          <span className="mt-0.5 block text-[11.5px] leading-snug text-zinc-500">{servico.descricao}</span>
        ) : null}
        <span className="mt-1.5 flex items-baseline gap-1.5">
          <span className="text-[14px] font-bold" style={{ color: marcado ? corDaLoja : "#18181b" }}>
            {!mostrarPreco ? "" : servico.preco > 0 ? formatarDinheiro(servico.preco) : "Grátis"}
          </span>
          {mostrarPreco && servico.preco > 0 ? (
            /* Serviço quase sempre é cobrado uma vez; quando não for, a
               vitrine precisa dizer, senão a conta surpreende no total. */
            <span className="text-[10.5px] font-medium text-zinc-500">
              {servico.porPeca ? porPeca : "no pedido"}
            </span>
          ) : null}
        </span>
      </span>

      {/* Sem caixa de marcar esperando clique: o cartão inteiro é o controle,
          e o visto só aparece depois de escolhido. Um quadradinho vazio antes
          da escolha faz parecer formulário a preencher, quando é oferta. */}
      {marcado ? (
        <span
          className="absolute right-2.5 top-2.5 flex h-4.5 w-4.5 items-center justify-center rounded-full p-0.5 text-white"
          style={{ backgroundColor: corDaLoja }}
        >
          <Check size={11} strokeWidth={3.5} />
        </span>
      ) : null}
    </button>
  );
}

export function ServicosOpcionais({
  vitrine,
  escolhidos,
  aoEscolher,
  corDaLoja,
  formatarDinheiro,
  faltando,
  unidadeDeVenda,
}: {
  vitrine: GrupoNaVitrine[];
  escolhidos: string[];
  aoEscolher: (servico: ServicoOpcional, caixa: GrupoNaVitrine) => void;
  corDaLoja: string;
  formatarDinheiro: (valor: number) => string;
  /* A unidade de venda do produto: no m², serviço por unidade é "por peça". */
  unidadeDeVenda?: string | null;
  /* O grupo obrigatório que ainda não foi respondido, para a loja dizer o que
     falta em vez de deixar um botão morto. */
  faltando?: string | null;
}) {
  if (!vitrine.length) return null;

  return (
    <div className="space-y-5">
      {vitrine.map((caixa) => {
        const escolhaUnica = caixa.grupo.modo === "uma";
        const pendente = faltando === caixa.grupo.nome;
        /* A instrução só existe quando a loja realmente exige uma resposta.
           Grupo opcional mostra apenas o nome: ele é uma oferta, não um
           campo de formulário esperando ser preenchido. */
        const instrucao = caixa.grupo.obrigatorio
          ? escolhaUnica
            ? "selecione uma opção (obrigatório)"
            : "selecione uma ou mais opções (obrigatório)"
          : null;
        return (
          <section key={caixa.grupo.id || "avulsos"} className="space-y-2.5">
            <div className="flex items-center gap-2">
              <span className="text-[11px] font-semibold uppercase tracking-[0.08em] text-zinc-500">
                {caixa.grupo.nome}
              </span>
              {instrucao ? (
                <span
                  className="text-[10.5px] font-medium"
                  style={{ color: pendente ? corDaLoja : "#a1a1aa" }}
                >
                  {instrucao}
                </span>
              ) : null}
            </div>

            <div className="grid gap-2 sm:grid-cols-2">
              {caixa.servicos.map((servico) => (
                <CartaoDoServico
                  key={servico.id}
                  servico={servico}
                  marcado={escolhidos.includes(servico.id)}
                  corDaLoja={corDaLoja}
                  formatarDinheiro={formatarDinheiro}
                  aoEscolher={() => aoEscolher(servico, caixa)}
                  porPeca={vendidoPorMedida(unidadeDeVenda) ? "por peça" : "por unidade"}
                />
              ))}
            </div>
          </section>
        );
      })}
    </div>
  );
}
