// FeedMemorias — feed de fotos do mês (estilo álbum), um card por aula.
// Recebe `posts` já montados e ordenados: [{ ano, mes, dia, assunto, emoji, fotos:[{id,src,legenda}] }]
// Hoje o App monta os posts com o mês em memória; um futuro /api/feed pode
// devolver o mesmo shape atravessando meses sem mudar nada aqui.
const { useState: useStateFE, useRef: useRefFE } = React;

const MESES_FE = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
                  'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];

// --- Card de compartilhamento: canvas 1080×1350 com a paleta da marca ---
// Canvas não lê variáveis CSS; valores espelham o :root do styles.css
const CARD_CORES = { fundo: '#F5EDE0', texto: '#2B2620', suave: '#6B5B48' };

// Retângulo com cantos levemente assimétricos (estética da marca)
function cantosIrregulares(ctx, x, y, w, h, raios) {
  const [r1, r2, r3, r4] = raios;
  ctx.beginPath();
  ctx.moveTo(x + r1, y);
  ctx.lineTo(x + w - r2, y);
  ctx.arcTo(x + w, y, x + w, y + r2, r2);
  ctx.lineTo(x + w, y + h - r3);
  ctx.arcTo(x + w, y + h, x + w - r3, y + h, r3);
  ctx.lineTo(x + r4, y + h);
  ctx.arcTo(x, y + h, x, y + h - r4, r4);
  ctx.lineTo(x, y + r1);
  ctx.arcTo(x, y, x + r1, y, r1);
  ctx.closePath();
}

function truncarTexto(ctx, txt, maxW) {
  if (ctx.measureText(txt).width <= maxW) return txt;
  // Trunca por code points (não code units) — slice quebraria emoji no meio (vira �)
  const pontos = Array.from(txt);
  while (pontos.length > 1 && ctx.measureText(pontos.join('') + '…').width > maxW) pontos.pop();
  return pontos.join('').trimEnd() + '…';
}

// Reusa a <img> do carrossel se já decodificada; senão carrega de novo (same-origin, sem taint)
function carregarImagem(imgEl, src) {
  if (imgEl && imgEl.complete && imgEl.naturalWidth > 0) return Promise.resolve(imgEl);
  return new Promise((res, rej) => {
    const i = new Image();
    i.onload = () => res(i);
    i.onerror = () => rej(new Error('foto não carregou'));
    i.src = src;
  });
}

async function gerarCardMemoria(post, foto, imgEl) {
  // fonts.load das faces exatas do canvas (fillText não dispara carregamento sozinho)
  if (document.fonts && document.fonts.load) {
    try {
      await Promise.all([
        document.fonts.load('600 54px Fredoka'),
        document.fonts.load('700 60px Fredoka'),
        document.fonts.load('italic 600 34px Nunito'),
        document.fonts.load('italic 400 32px Nunito'),
      ]);
    } catch (_) {}
  }
  const img = await carregarImagem(imgEl, foto.src);
  const W = 1080, H = 1350, M = 48;
  const c = document.createElement('canvas');
  c.width = W; c.height = H;
  const ctx = c.getContext('2d');

  ctx.fillStyle = CARD_CORES.fundo;
  ctx.fillRect(0, 0, W, H);

  // Foto em cover-crop com cantos arredondados
  const fw = W - M * 2, fh = 1000;
  ctx.save();
  cantosIrregulares(ctx, M, M, fw, fh, [38, 34, 36, 32]);
  ctx.clip();
  const esc = Math.max(fw / img.naturalWidth, fh / img.naturalHeight);
  const dw = img.naturalWidth * esc, dh = img.naturalHeight * esc;
  ctx.drawImage(img, M + (fw - dw) / 2, M + (fh - dh) / 2, dw, dh);
  ctx.restore();

  // Título: emoji + assunto
  ctx.fillStyle = CARD_CORES.texto;
  ctx.font = '600 54px Fredoka, sans-serif';
  const titulo = `${post.emoji || '🌿'} ${post.assunto || window.t('mem.aulaDoDia')}`;
  ctx.fillText(truncarTexto(ctx, titulo, fw), M, M + fh + 86);

  // Data
  ctx.fillStyle = CARD_CORES.suave;
  ctx.font = 'italic 600 34px Nunito, sans-serif';
  ctx.fillText(window.SoluI18n.dataLonga(post.ano, post.mes, post.dia), M, M + fh + 142);

  // Legenda da foto (se houver) — encurta pra não invadir a marca
  if (foto.legenda) {
    ctx.font = 'italic 400 32px Nunito, sans-serif';
    ctx.fillText(truncarTexto(ctx, `“${foto.legenda}”`, fw - 220), M, M + fh + 196);
  }

  // Marca solu no canto inferior direito
  ctx.fillStyle = CARD_CORES.texto;
  ctx.font = '700 60px Fredoka, sans-serif';
  ctx.fillText('solu', W - M - ctx.measureText('solu').width, H - 44);

  return new Promise((res) => c.toBlob(res, 'image/jpeg', 0.92));
}

function CardMemoria({ post, onAbrirDia, onAbrirFoto }) {
  const [ativa, setAtiva] = useStateFE(0);
  const [compartilhando, setCompartilhando] = useStateFE(false);
  const carrosselRef = useRefFE(null);
  const cardsRef = useRefFE({}); // cache de blobs gerados — retry após NotAllowedError vira share instantâneo
  const multi = post.fotos.length > 1;

  const compartilhar = async () => {
    if (compartilhando) return;
    setCompartilhando(true);
    try {
      const foto = post.fotos[ativa] || post.fotos[0];
      const chave = `${foto.id || ativa}|${foto.legenda || ''}`;
      let blob = cardsRef.current[chave];
      if (!blob) {
        const imgs = carrosselRef.current ? carrosselRef.current.querySelectorAll('img') : [];
        blob = await gerarCardMemoria(post, foto, imgs[ativa]);
        if (!blob) throw new Error('canvas vazio');
        cardsRef.current[chave] = blob;
      }
      const nome = `solu-${post.ano}-${String(post.mes + 1).padStart(2, '0')}-${String(post.dia).padStart(2, '0')}.jpg`;
      const file = new File([blob], nome, { type: 'image/jpeg' });
      if (navigator.canShare && navigator.canShare({ files: [file] })) {
        await navigator.share({ files: [file] });
      } else {
        // Sem share nativo (desktop): baixa a imagem
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url; a.download = nome;
        document.body.appendChild(a); a.click(); a.remove();
        setTimeout(() => URL.revokeObjectURL(url), 5000);
      }
    } catch (e) {
      if (e && e.name === 'NotAllowedError') {
        // iOS: a foto demorou e o gesto expirou — o card já está no cache, o retry compartilha na hora
        alert(window.t('mem.fotoLenta'));
      } else if (!e || e.name !== 'AbortError') {
        // AbortError = usuária fechou o share sheet; não é erro
        alert(window.t('mem.imagemErro'));
      }
    } finally {
      setCompartilhando(false);
    }
  };

  const onScrollCarrossel = (e) => {
    const el = e.currentTarget;
    const idx = Math.round(el.scrollLeft / el.clientWidth);
    const limitado = Math.max(0, Math.min(post.fotos.length - 1, idx));
    if (limitado !== ativa) setAtiva(limitado);
  };

  const legendaAtiva = (post.fotos[ativa] || {}).legenda;

  return (
    <article className="memoria-card">
      <button className="memoria-titulo" onClick={() => onAbrirDia(post.dia)}>
        <span className="memoria-emoji">{post.emoji || '🌿'}</span>
        <span className="memoria-assunto">{post.assunto || window.t('mem.aulaDoDia')}</span>
        <span className="memoria-data">{window.SoluI18n.dataLonga(post.ano, post.mes, post.dia)}</span>
      </button>

      <div className="memoria-carrossel" ref={carrosselRef} onScroll={multi ? onScrollCarrossel : undefined}>
        {post.fotos.map((f, i) => (
          <img key={f.id || i} {...window.blurImg()} src={f.src} alt={f.legenda || `Foto ${i + 1}`}
               loading="lazy" onClick={() => onAbrirFoto(f)} />
        ))}
      </div>

      {multi && (
        <div className="memoria-dots">
          {post.fotos.map((_, i) => (
            <span key={i} className={`memoria-dot ${i === ativa ? 'on' : ''}`} />
          ))}
        </div>
      )}

      {legendaAtiva && <div className="memoria-legenda">“{legendaAtiva}”</div>}

      <button className="btn-pequeno memoria-compartilhar" onClick={compartilhar} disabled={compartilhando}>
        <svg className="ic-aviao" viewBox="0 0 24 24" width="15" height="15" fill="none"
             stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M22 2 11 13" />
          <path d="M22 2 15 22 11 13 2 9 22 2Z" />
        </svg>
        {compartilhando ? window.t('mem.preparando') : window.t('mem.compartilhar')}
      </button>
    </article>
  );
}

function FeedMemorias({ posts, onAbrirDia }) {
  const [fotoAberta, setFotoAberta] = useStateFE(null);

  if (!posts || posts.length === 0) {
    return (
      <div className="memorias-vazio">
        <span style={{ fontSize: 40 }}>📸</span>
        {window.t('mem.vazio')}
      </div>
    );
  }

  return (
    <div className="memorias-feed">
      {posts.map((p) => (
        <CardMemoria key={`${p.ano}-${p.mes}-${p.dia}`} post={p}
                     onAbrirDia={onAbrirDia} onAbrirFoto={setFotoAberta} />
      ))}
      {fotoAberta && <FotoViewer foto={fotoAberta} onClose={() => setFotoAberta(null)} />}
    </div>
  );
}

window.FeedMemorias = FeedMemorias;
