"use client";

import { useEffect, type ReactNode } from "react";
import { animate, motion, useMotionValue, useReducedMotion, useTransform } from "framer-motion";

/**
 * As peças da página de Assinatura. Superfície branca, borda fina, uma cor
 * de acento (o violeta da marca) e mais nada: o que se move é o anel enchendo
 * e o número chegando — o resto fica parado para a informação falar.
 *
 * O Natan recusou a versão com cartões em degradê ("muita cara de IA"): aqui
 * não entra gradiente, nem mancha desfocada, nem selo translúcido.
 */

export function Painel({ children, className = "", atraso = 0 }: { children: ReactNode; className?: string; atraso?: number }) {
  const parado = useReducedMotion();
  return (
    <motion.section
      initial={parado ? false : { opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3, ease: "easeOut", delay: atraso }}
      className={`overflow-hidden rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] shadow-[var(--ks-shadow-subtle)] ${className}`}
    >
      {children}
    </motion.section>
  );
}

export function CabecalhoDoPainel({ titulo, texto, children }: { titulo: string; texto?: string; children?: ReactNode }) {
  return (
    <header className="flex flex-col gap-3 border-b border-[var(--ks-color-border-subtle)] px-6 py-4 sm:flex-row sm:items-center sm:justify-between">
      <div>
        <h2 className="text-base font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">{titulo}</h2>
        {texto ? <p className="mt-0.5 text-sm text-[var(--ks-color-text-muted)]">{texto}</p> : null}
      </div>
      {children}
    </header>
  );
}

export function Eyebrow({ children }: { children: ReactNode }) {
  return <p className="text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">{children}</p>;
}

/** Anel de progresso: enche até a fração quando entra na tela. */
export function Anel({
  fracao,
  tamanho = 96,
  espessura = 9,
  children,
  atraso = 0.1,
}: {
  fracao: number;
  tamanho?: number;
  espessura?: number;
  children?: ReactNode;
  atraso?: number;
}) {
  const parado = useReducedMotion();
  const raio = (tamanho - espessura) / 2;
  const circunferencia = 2 * Math.PI * raio;
  const cheio = Math.min(1, Math.max(0, fracao));
  const alvo = circunferencia * (1 - cheio);
  return (
    <div className="relative shrink-0" style={{ width: tamanho, height: tamanho }}>
      <svg width={tamanho} height={tamanho} viewBox={`0 0 ${tamanho} ${tamanho}`} className="-rotate-90">
        <circle cx={tamanho / 2} cy={tamanho / 2} r={raio} fill="none" stroke="var(--ks-color-bg-soft)" strokeWidth={espessura} />
        <motion.circle
          cx={tamanho / 2}
          cy={tamanho / 2}
          r={raio}
          fill="none"
          stroke="var(--ks-brand-600)"
          strokeWidth={espessura}
          strokeLinecap="round"
          strokeDasharray={circunferencia}
          initial={parado ? { strokeDashoffset: alvo } : { strokeDashoffset: circunferencia }}
          animate={{ strokeDashoffset: alvo }}
          transition={{ duration: 1.1, ease: [0.22, 1, 0.36, 1], delay: atraso }}
        />
      </svg>
      <div className="absolute inset-0 flex flex-col items-center justify-center leading-none">{children}</div>
    </div>
  );
}

/** Número que chega ao valor em vez de aparecer pronto. */
export function NumeroAnimado({ valor, className = "" }: { valor: number; className?: string }) {
  const parado = useReducedMotion();
  const vivo = useMotionValue(parado ? valor : 0);
  const texto = useTransform(vivo, (v) => Math.round(v).toLocaleString("pt-BR"));
  useEffect(() => {
    if (parado) {
      vivo.set(valor);
      return;
    }
    const controle = animate(vivo, valor, { duration: 0.9, ease: [0.22, 1, 0.36, 1] });
    return () => controle.stop();
  }, [vivo, valor, parado]);
  return <motion.span className={`ks-num ${className}`}>{texto}</motion.span>;
}

/**
 * Uma opção para escolher (plano, pacote): cartão com rádio no canto. A
 * escolhida ganha a borda da marca; o botão de ação fica fora, um só para o
 * grupo, e diz o que vai acontecer com a opção marcada.
 */
export function Opcao({
  selecionada,
  aoEscolher,
  titulo,
  etiqueta,
  children,
  className = "",
}: {
  selecionada: boolean;
  aoEscolher: () => void;
  titulo: string;
  etiqueta?: ReactNode;
  children: ReactNode;
  className?: string;
}) {
  const parado = useReducedMotion();
  return (
    <motion.button
      type="button"
      role="radio"
      aria-checked={selecionada}
      onClick={aoEscolher}
      whileTap={parado ? undefined : { scale: 0.995 }}
      className={`flex w-full flex-col gap-3 rounded-2xl border-2 p-5 text-left transition-[border-color,box-shadow] ${
        selecionada
          ? "border-[var(--ks-brand-600)] shadow-[0_0_0_4px_var(--ks-brand-50)]"
          : "border-[var(--ks-color-border-subtle)] hover:border-[var(--ks-color-border-strong)]"
      } ${className}`}
    >
      {/* Título nunca quebra; a etiqueta desce de linha quando não cabe ao lado. */}
      <span className="flex flex-wrap items-center justify-between gap-x-3 gap-y-1">
        <span className="flex items-center gap-2.5 whitespace-nowrap">
          <span
            aria-hidden
            className={`flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-full border-2 transition-colors ${
              selecionada ? "border-[var(--ks-brand-600)] bg-[var(--ks-brand-600)]" : "border-[var(--ks-color-border-strong)]"
            }`}
          >
            {selecionada ? (
              <motion.span
                initial={parado ? false : { scale: 0 }}
                animate={{ scale: 1 }}
                transition={{ type: "spring", stiffness: 500, damping: 30 }}
                className="h-1.5 w-1.5 rounded-full bg-white"
              />
            ) : null}
          </span>
          <span className="text-sm font-bold text-[var(--ks-color-text-primary)]">{titulo}</span>
        </span>
        {etiqueta}
      </span>
      {children}
    </motion.button>
  );
}

/** Etiqueta curta e sem fundo, para não competir com o preço. */
export function Etiqueta({ children }: { children: ReactNode }) {
  return <span className="shrink-0 text-[10px] font-bold uppercase tracking-[0.1em] text-[var(--ks-brand-600)]">{children}</span>;
}

/** Preço grande com a unidade pequena ao lado. */
export function Preco({ valor, unidade, className = "" }: { valor: string; unidade: string; className?: string }) {
  return (
    <span className={`flex items-baseline gap-1.5 ${className}`}>
      <span className="ks-num text-[28px] font-extrabold leading-none tracking-tight text-[var(--ks-color-text-primary)]">{valor}</span>
      <span className="text-sm text-[var(--ks-color-text-muted)]">{unidade}</span>
    </span>
  );
}

/** A faixa de ação do painel: resumo da escolha à esquerda, botão à direita. */
export function FaixaDeAcao({ resumo, children }: { resumo: ReactNode; children: ReactNode }) {
  return (
    <div className="flex flex-col gap-3 border-t border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-inset)] px-6 py-4 sm:flex-row sm:items-center sm:justify-between">
      <div className="min-w-0 text-sm text-[var(--ks-color-text-secondary)]">{resumo}</div>
      <div className="shrink-0">{children}</div>
    </div>
  );
}
