// shared.jsx — MinduBier × Copa 2026 — Shared utilities, constants, icons, mocks, validations

// ─── Tokens ────────────────────────────────────────────────────────────
const MB = {
  copper: '#c5762a',
  amber: '#efa31f',
  gold: '#ffd503',
  bgLight: '#fffff4',
  bgDark: '#444444',
  bgDarker: '#323231',
  bgFooter: '#2a2a29',
  white: '#ffffff',
  copaGreen: '#009739',
  copaGreenDeep: '#00622a',
  copaYellow: '#fedd00',
  copaBlue: '#002776',
  error: '#c0392b',
  success: '#1f8a5b',
  display: "'Outfit', system-ui, sans-serif",
  body: "'Nunito Sans', system-ui, sans-serif",
  ease: 'cubic-bezier(0.16, 1, 0.3, 1)',
};

// ─── Constants ─────────────────────────────────────────────────────────
const TAMANHOS = ['P', 'M', 'G', 'GG', 'XG'];
const TABELA_MEDIDAS = [
  { tamanho: 'P',  largura: 54, comprimento: 70 },
  { tamanho: 'M',  largura: 56, comprimento: 72 },
  { tamanho: 'G',  largura: 58, comprimento: 73.5 },
  { tamanho: 'GG', largura: 60, comprimento: 75.5 },
  { tamanho: 'XG', largura: 64, comprimento: 77.5 },
];
const PRECO_CAMISA_CENTAVOS = 9900;

// ─── BRL formatting ────────────────────────────────────────────────────
function brl(centavos) {
  return (centavos / 100).toLocaleString('pt-BR', {
    style: 'currency', currency: 'BRL', minimumFractionDigits: 2,
  });
}
function brlNumber(centavos) {
  // No "R$" prefix; for use after "R$" already in template
  return (centavos / 100).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

// ─── Masks (inline, no libs) ───────────────────────────────────────────
function maskCEP(v) {
  const d = (v || '').replace(/\D/g, '').slice(0, 8);
  if (d.length <= 5) return d;
  return d.slice(0, 5) + '-' + d.slice(5);
}
function unmaskCEP(v) { return (v || '').replace(/\D/g, ''); }

function maskTelefone(v) {
  const d = (v || '').replace(/\D/g, '').slice(0, 11);
  if (d.length === 0) return '';
  if (d.length < 3) return '(' + d;
  if (d.length < 7) return '(' + d.slice(0, 2) + ') ' + d.slice(2);
  if (d.length <= 10) return '(' + d.slice(0, 2) + ') ' + d.slice(2, 6) + '-' + d.slice(6);
  return '(' + d.slice(0, 2) + ') ' + d.slice(2, 7) + '-' + d.slice(7);
}
function unmaskTelefone(v) { return (v || '').replace(/\D/g, ''); }

// ─── Mocks ─────────────────────────────────────────────────────────────
async function mockConsultarCEP(cep) {
  const cepLimpo = (cep || '').replace(/\D/g, '');
  const r = await fetch(`/api/cep?cep=${cepLimpo}`);
  if (!r.ok) {
    const data = await r.json().catch(() => ({}));
    throw new Error(data.error || 'CEP não encontrado');
  }
  const data = await r.json();
  return {
    cep: data.cep,
    logradouro: data.logradouro,
    bairro: data.bairro,
    cidade: data.cidade,
    estado: data.estado,
  };
}

async function mockCalcularFrete(cepDestino, quantidade) {
  const r = await fetch('/api/frete', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      cepDestino: (cepDestino || '').replace(/\D/g, ''),
      quantidade: quantidade,
    }),
  });
  if (!r.ok) {
    const data = await r.json().catch(() => ({}));
    throw new Error(data.error || 'Não foi possível calcular o frete');
  }
  const data = await r.json();
  return { opcoes: data.opcoes };
}

async function enviarCadastro(pedido) {
  const r = await fetch('/api/cadastro', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(pedido),
  });
  const data = await r.json().catch(() => ({}));
  if (!r.ok) {
    throw new Error(data.error || 'Erro ao enviar cadastro');
  }
  return data; // { success: true, protocolo }
}

// ─── Validation (Zod-style without zod) ────────────────────────────────
function validateCadastro(data) {
  const e = {};
  if (!data.nome || data.nome.trim().length < 3) e.nome = 'Nome muito curto';
  else if (data.nome.length > 100) e.nome = 'Nome muito longo';
  if (!data.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) e.email = 'E-mail inválido';
  const tel = unmaskTelefone(data.telefone);
  if (!/^\d{10,11}$/.test(tel)) e.telefone = 'Telefone deve ter DDD + número';
  const cep = unmaskCEP(data.cep);
  if (!/^\d{8}$/.test(cep)) e.cep = 'CEP deve ter 8 dígitos';
  if (!data.logradouro || !data.logradouro.trim()) e.logradouro = 'Informe o logradouro';
  if (!data.numero || !String(data.numero).trim()) e.numero = 'Informe o número';
  if (!data.bairro || !data.bairro.trim()) e.bairro = 'Informe o bairro';
  if (!data.cidade || !data.cidade.trim()) e.cidade = 'Informe a cidade';
  if (!data.estado || data.estado.length !== 2) e.estado = 'UF inválida';
  const totalCamisas = (data.itens || []).reduce((s, i) => s + (i.quantidade || 0), 0);
  if (totalCamisas === 0) e.itens = 'Selecione pelo menos uma camisa';
  if (!data.tipoEntrega) e.tipoEntrega = 'Escolha como receber';
  return e;
}

// ─── Icons (inline SVG, lucide-style) ──────────────────────────────────
const Icon = {
  Check: (p) => (
    <svg width={p.size || 18} height={p.size || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M20 6L9 17l-5-5" />
    </svg>
  ),
  Plus: (p) => (
    <svg width={p.size || 18} height={p.size || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M12 5v14M5 12h14" />
    </svg>
  ),
  Minus: (p) => (
    <svg width={p.size || 18} height={p.size || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M5 12h14" />
    </svg>
  ),
  ArrowRight: (p) => (
    <svg width={p.size || 18} height={p.size || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M5 12h14M13 5l7 7-7 7" />
    </svg>
  ),
  ArrowDown: (p) => (
    <svg width={p.size || 18} height={p.size || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M12 5v14M5 13l7 7 7-7" />
    </svg>
  ),
  Trophy: (p) => (
    <svg width={p.size || 22} height={p.size || 22} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6" />
      <path d="M18 9h1.5a2.5 2.5 0 0 0 0-5H18" />
      <path d="M4 22h16" />
      <path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22" />
      <path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22" />
      <path d="M18 2H6v7a6 6 0 0 0 12 0V2Z" />
    </svg>
  ),
  Sparkles: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3Z" />
    </svg>
  ),
  Shirt: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M20.4 4.5 16 2a5 5 0 0 1-8 0L3.6 4.5a2 2 0 0 0-.7 2.7L6.5 12V22h11V12l3.6-4.8a2 2 0 0 0-.7-2.7" />
    </svg>
  ),
  Package: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="m7.5 4.27 9 5.15" />
      <path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" />
      <path d="M3.3 7 12 12l8.7-5" />
      <path d="M12 22V12" />
    </svg>
  ),
  MapPin: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M20 10c0 7-8 13-8 13s-8-6-8-13a8 8 0 0 1 16 0Z" />
      <circle cx="12" cy="10" r="3" />
    </svg>
  ),
  Award: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <circle cx="12" cy="8" r="6" />
      <path d="M15.477 12.89 17 22l-5-3-5 3 1.523-9.11" />
    </svg>
  ),
  Truck: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2" />
      <path d="M15 18H9" />
      <path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14" />
      <circle cx="17" cy="18" r="2" />
      <circle cx="7" cy="18" r="2" />
    </svg>
  ),
  X: (p) => (
    <svg width={p.size || 22} height={p.size || 22} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M18 6 6 18M6 6l12 12" />
    </svg>
  ),
  AlertCircle: (p) => (
    <svg width={p.size || 16} height={p.size || 16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <circle cx="12" cy="12" r="10" />
      <line x1="12" y1="8" x2="12" y2="12" />
      <line x1="12" y1="16" x2="12.01" y2="16" />
    </svg>
  ),
  Loader: (p) => (
    <svg width={p.size || 16} height={p.size || 16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ animation: 'spin 0.8s linear infinite' }} {...p}>
      <path d="M21 12a9 9 0 1 1-6.219-8.56" />
    </svg>
  ),
  ChevronLeft: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="m15 18-6-6 6-6" />
    </svg>
  ),
  ChevronRight: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="m9 18 6-6-6-6" />
    </svg>
  ),
  Whatsapp: (p) => (
    <svg width={p.size || 20} height={p.size || 20} viewBox="0 0 24 24" fill="currentColor" {...p}>
      <path d="M17.6 14.2c-.3-.1-1.7-.8-2-.9-.3-.1-.5-.1-.7.2-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.8-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.1.2-.2.3-.4.1-.2 0-.3 0-.5-.1-.1-.7-1.7-1-2.3-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.3 3.1c.2.2 2.1 3.2 5.1 4.5 2.5 1.1 3 .9 3.5.8.5-.1 1.7-.7 1.9-1.4.2-.7.2-1.2.2-1.3-.1-.2-.3-.3-.6-.4ZM12 2a10 10 0 0 0-8.5 15.3L2 22l4.9-1.3A10 10 0 1 0 12 2Z" />
    </svg>
  ),
};

// ─── Countdown helper ──────────────────────────────────────────────────
// FIFA World Cup 2026 kickoff: June 11, 2026
const COPA_KICKOFF = new Date('2026-06-11T17:00:00-04:00');

function useCountdown(target) {
  const [now, setNow] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const diff = Math.max(0, target.getTime() - now.getTime());
  const days = Math.floor(diff / 86_400_000);
  const hours = Math.floor((diff % 86_400_000) / 3_600_000);
  const minutes = Math.floor((diff % 3_600_000) / 60_000);
  const seconds = Math.floor((diff % 60_000) / 1000);
  return { days, hours, minutes, seconds, done: diff === 0 };
}

// ─── Toast system ──────────────────────────────────────────────────────
const ToastContext = React.createContext(null);

function ToastProvider({ children }) {
  const [toasts, setToasts] = React.useState([]);
  const push = React.useCallback((toast) => {
    const id = Math.random().toString(36).slice(2);
    setToasts((t) => [...t, { id, ...toast }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), toast.duration || 4500);
  }, []);
  return (
    <ToastContext.Provider value={push}>
      {children}
      <div className="toast-stack" aria-live="polite" aria-atomic="true">
        {toasts.map((t) => (
          <div key={t.id} className={`toast toast-${t.kind || 'error'}`} role="status">
            <span style={{ color: t.kind === 'success' ? MB.success : MB.error, marginTop: 2, flexShrink: 0 }}>
              {t.kind === 'success' ? <Icon.Check size={18} /> : <Icon.AlertCircle size={18} />}
            </span>
            <span style={{ flex: 1 }}>{t.message}</span>
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}
function useToast() { return React.useContext(ToastContext); }

// ─── Logo SVG (MinduBier "M" mark, fallback if avif fails) ─────────────
function MinduMark({ size = 28, color = MB.copper }) {
  return (
    <svg width={size} height={size * (3/4)} viewBox="0 0 80 60" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      {/* M shape similar to MinduBier mark */}
      <path d="M5 5 L5 55 L20 55 L20 25 L33 45 L47 25 L47 55 L62 55 L62 5 L47 5 L33 25 L20 5 Z" fill={color}/>
    </svg>
  );
}

// Standalone-bundle resource helper: returns bundled blob URL if available, otherwise the dev fallback path.
function R(id, fallback) {
  return (typeof window !== 'undefined' && window.__resources && window.__resources[id]) || fallback;
}

// Export everything to window
Object.assign(window, {
  MB, TAMANHOS, TABELA_MEDIDAS, PRECO_CAMISA_CENTAVOS,
  brl, brlNumber,
  maskCEP, unmaskCEP, maskTelefone, unmaskTelefone,
  mockConsultarCEP, mockCalcularFrete, enviarCadastro,
  validateCadastro,
  Icon, MinduMark,
  COPA_KICKOFF, useCountdown,
  ToastProvider, ToastContext, useToast,
  R,
});
