// shareCard.jsx - end-of-campaign shareable image template
const { useState: useShareSt, useEffect: useShareEf } = React;

const SHARE_ROLE_SORT = { AWP:0, IGL:1, ENT:2, RIF:3, SUP:4, LRK:5 };
const SHARE_RANK_IMG = {
  GE:'/assets/ranks/global.png',
  SM:'/assets/ranks/supreme.png',
  LEM:'/assets/ranks/eagle.png',
  MG:'/assets/ranks/guardian.png',
  GN:'/assets/ranks/nova.png',
};
const SHARE_FLAG_ASSETS = new Set(['ba','br','ca','dk','ee','eu','fr','il','lt','lv','no','pl','ru','se','sk','ua','us']);

function shareRankPath(tier) {
  return SHARE_RANK_IMG[tier] || SHARE_RANK_IMG.GN;
}

function shareFlagCode(value) {
  const text = String(value || '').trim();
  const chars = [...text];
  const first = chars[0]?.codePointAt(0);
  const second = chars[1]?.codePointAt(0);

  if (first === 0x1f30d) return 'eu';
  if (first >= 0x1f1e6 && first <= 0x1f1ff && second >= 0x1f1e6 && second <= 0x1f1ff) {
    const code = String.fromCharCode(first - 0x1f1e6 + 97) + String.fromCharCode(second - 0x1f1e6 + 97);
    return SHARE_FLAG_ASSETS.has(code) ? code : 'eu';
  }

  const lower = text.toLowerCase().slice(0, 2);
  return SHARE_FLAG_ASSETS.has(lower) ? lower : 'eu';
}

function shareRoster(players) {
  return [...(players || [])]
    .sort((a,b) => (SHARE_ROLE_SORT[a.role] ?? 9) - (SHARE_ROLE_SORT[b.role] ?? 9))
    .slice(0, 5);
}

function shareLocale() {
  return window.I18N?.getLocale?.() || 'pt-BR';
}

function shareText(pt, en, ru) {
  const locale = shareLocale();
  if (locale === 'en') return en;
  if (locale === 'ru') return ru || window.I18N?.translateString?.(pt, 'ru') || en;
  return pt;
}

function shareTranslate(value) {
  return window.I18N?.translateString?.(value) || value;
}

function shareSpaced(value) {
  return String(value || '').toUpperCase().split('').join(' ');
}

function shareAppBaseUrl() {
  return `${window.location.origin}${window.location.pathname || '/'}`.replace(/\/?$/, '/');
}

function sharePublicGameUrl() {
  return 'https://16a0.xyz/';
}

function shareHashString(value) {
  const text = String(value || '');
  let hash = 2166136261;
  for (let i = 0; i < text.length; i++) {
    hash ^= text.charCodeAt(i);
    hash = Math.imul(hash, 16777619);
  }
  return (hash >>> 0).toString(36).toUpperCase();
}

function shareSeed(data) {
  const seed = data?.campaignSeed || data?.seed || data?.seriesSummary?.seed || data?.campaignSummary?.seed;
  if (seed != null && seed !== '') {
    const numeric = Number(seed);
    return Number.isFinite(numeric)
      ? numeric.toString(36).toUpperCase().padStart(6, '0')
      : String(seed).toUpperCase();
  }
  return shareHashString(JSON.stringify({
    players:(data?.players || []).map(p => p.id || p.name),
    score:data?.score || data?.seriesSummary?.score,
    teamName:data?.teamName,
    type:data?.type,
  })).padStart(6, '0');
}

function shareMinimalPlayer(player) {
  return {
    id:player.id,
    name:player.name,
    country:player.country,
    role:player.role,
    tier:player.tier,
    overall:player.overall,
    team:player.team,
    era:player.era,
  };
}

function shareMinimalData(data) {
  const seed = shareSeed(data);
  return {
    v:1,
    seed,
    type:data.type,
    players:(data.players || []).slice(0, 5).map(shareMinimalPlayer),
    overall:data.overall,
    score:data.score,
    teamName:data.teamName,
    opponentName:data.opponentName,
    isPerfect:!!data.isPerfect,
    matchFormat:data.matchFormat,
    perfectScore:data.perfectScore,
    seriesSummary:data.seriesSummary ? {
      stage:data.seriesSummary.stage,
      stageLabel:data.seriesSummary.stageLabel,
      bo:data.seriesSummary.bo,
      score:data.seriesSummary.score,
      maps:(data.seriesSummary.maps || []).map(map => ({
        mapId:map.mapId,
        name:map.name,
        score:map.score,
        won:map.won,
        overtime:!!map.overtime,
      })),
    } : null,
    campaignSummary:data.campaignSummary ? {
      outcome:data.campaignSummary.outcome,
      stageLabel:data.campaignSummary.stageLabel,
      swissRecord:data.campaignSummary.swissRecord,
      swissSeries:data.campaignSummary.swissSeries,
      playoffRecord:data.campaignSummary.playoffRecord,
      totalRecord:data.campaignSummary.totalRecord,
      path:data.campaignSummary.path || [],
    } : null,
  };
}

function encodeSharePayload(data) {
  const json = JSON.stringify(shareMinimalData(data));
  const bytes = new TextEncoder().encode(json);
  let binary = '';
  bytes.forEach(byte => { binary += String.fromCharCode(byte); });
  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
}

function decodeSharePayload(encoded) {
  try {
    const normalized = String(encoded || '').replace(/-/g, '+').replace(/_/g, '/');
    const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);
    const binary = atob(padded);
    const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
    const parsed = JSON.parse(new TextDecoder().decode(bytes));
    return parsed?.v ? parsed : null;
  } catch (_) {
    return null;
  }
}

function shareUrlForData(data) {
  return `${shareAppBaseUrl()}#share=${encodeSharePayload(data)}`;
}

function readShareRoute() {
  const hash = window.location.hash || '';
  const match = hash.match(/^#share=([^&]+)/);
  return match ? decodeSharePayload(match[1]) : null;
}

function clearShareRoute() {
  if ((window.location.hash || '').startsWith('#share=')) {
    window.history.pushState(null, '', shareAppBaseUrl());
    window.dispatchEvent(new CustomEvent('share-route-change', { detail:null }));
  }
}

function shareCaption(data) {
  const seed = shareSeed(data);
  const score = data?.seriesSummary?.score || data?.score;
  const scoreText = Array.isArray(score) ? `${score[0]}:${score[1]}` : '';
  const perfect = data?.isPerfect ? ` ${data.perfectScore || ''}`.trim() : '';
  const url = sharePublicGameUrl();
  return shareText(
    `Montei minha line no 16a0${scoreText ? ` e fiz ${scoreText}` : ''}${perfect ? ` perfeito ${perfect}` : ''}. Seed #${seed}.`,
    `I built my 16a0 lineup${scoreText ? ` and went ${scoreText}` : ''}${perfect ? ` perfect ${perfect}` : ''}. Seed #${seed}.`,
    `Ð¡Ð¾Ð±Ñ€Ð°Ð» ÑÐ²Ð¾Ð¹ ÑÐ¾ÑÑ‚Ð°Ð² Ð² 16a0${scoreText ? `: ${scoreText}` : ''}. Seed #${seed}. Ð˜Ð³Ñ€Ð°Ñ‚ÑŒ: ${url}`,
  );
}

function shareMessage(data, url = sharePublicGameUrl()) {
  return shareText(
    `${shareCaption(data)} Jogue tambem: ${url}`,
    `${shareCaption(data)} Play it: ${url}`,
    `${shareCaption(data)} Play it: ${url}`,
  );
}

function openShareRoute(data) {
  const payload = shareMinimalData(data);
  const encoded = encodeSharePayload(payload);
  window.history.pushState({ sharePayload:payload }, '', `#share=${encoded}`);
  window.dispatchEvent(new CustomEvent('share-route-change', { detail:payload }));
  return `${shareAppBaseUrl()}#share=${encoded}`;
}

function shareSocialUrl(kind, data, url) {
  const text = shareMessage(data, sharePublicGameUrl());
  if (kind === 'whatsapp') return `https://wa.me/?text=${encodeURIComponent(text)}`;
  if (kind === 'telegram') return `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(shareCaption(data))}`;
  if (kind === 'x') return `https://twitter.com/intent/tweet?text=${encodeURIComponent(shareCaption(data))}&url=${encodeURIComponent(url)}`;
  return url;
}

function ShareRankIcon({ tier, size = 22 }) {
  return (
    <img src={shareRankPath(tier)} alt={tier || 'rank'}
      style={{ width:size, height:size, objectFit:'cover', borderRadius:3,
        border:'1px solid rgba(0,0,0,0.4)', flexShrink:0 }}
      loading="lazy" />
  );
}

function ShareCard({ type, players, overall, score, opponentName, isPerfect, matchFormat, perfectScore, teamName, seriesSummary, campaignSummary, seed, campaignSeed, innerRef }) {
  const isChamp = type === 'champion';
  const format = window.getMatchFormat(matchFormat || 'MR16');
  const targetScore = perfectScore || format.perfectScore;
  const campaignSeedLabel = shareSeed({seed, campaignSeed, players, score, seriesSummary, campaignSummary, teamName, type});
  const roster = shareRoster(players);
  const seriesScore = seriesSummary?.score || score;
  const mine = seriesScore ? seriesScore[0] : null;
  const theirs = seriesScore ? seriesScore[1] : null;
  const teamLine = (teamName || shareText('Meu Time', 'My Team', 'Моя команда')).toUpperCase();
  const opponentLine = (opponentName || shareText('um adversário', 'an opponent', 'соперник')).toUpperCase();
  const seriesStageLabel = shareTranslate(seriesSummary?.stageLabel || 'Série');
  const stageLine = seriesSummary
    ? `${seriesStageLabel} - BO${seriesSummary.bo || 1}`
    : (isChamp ? shareText('Grande final', 'Grand final', 'Гранд-финал') : shareText('Última série', 'Last series', 'Последняя серия'));
  const campaignLine = campaignSummary?.totalRecord
    ? `${shareText('Campanha', 'Campaign', 'Кампания')} ${campaignSummary.totalRecord}`
    : (campaignSummary?.swissRecord ? `${shareText('Suíço', 'Swiss', 'Швейцарка')} ${campaignSummary.swissRecord}` : '');

  return (
    <div ref={innerRef} style={{
      width:480, minHeight:680, background:'#0d0f10', position:'relative',
      overflow:'hidden', fontFamily:'var(--font-ui)',
      border:'1px solid #252a2d', borderRadius:14, display:'flex', flexDirection:'column' }}>

      <div style={{ position:'absolute', inset:0,
        background:'radial-gradient(ellipse 80% 42% at 50% -6%, rgba(244,165,35,0.18), transparent 62%)',
        pointerEvents:'none' }} />
      <div style={{ position:'absolute', inset:0, opacity:0.5,
        backgroundImage:'repeating-linear-gradient(0deg, transparent, transparent 27px, rgba(255,255,255,0.02) 27px, rgba(255,255,255,0.02) 28px)',
        pointerEvents:'none' }} />

      <div style={{ position:'relative', display:'flex', alignItems:'center',
        justifyContent:'space-between', padding:'20px 26px 0' }}>
        <span style={{ fontFamily:'var(--font-cond)', fontWeight:800, fontSize:30,
          letterSpacing:'-0.01em', lineHeight:1 }}>
          <span style={{ color:'#e0e0e0' }}>16</span>
          <span style={{ color:'#4e5459', fontWeight:600 }}>x</span>
          <span style={{ color:'#f4a523' }}>0</span>
        </span>
        <span style={{ fontFamily:'var(--font-cond)', fontSize:10, fontWeight:700,
          color:'#7d8389', letterSpacing:'0.18em', textTransform:'uppercase', textAlign:'right' }}>
          seed #{campaignSeedLabel}<br/>Simulador de Major
        </span>
      </div>

      <div style={{ position:'relative', textAlign:'center', padding:'18px 26px 6px' }}>
        <div style={{ fontFamily:'var(--font-cond)', fontSize:12, fontWeight:700,
          color: isChamp ? '#f4a523' : '#96999d', letterSpacing:'0.22em',
          textTransform:'uppercase', marginBottom: isChamp ? 6 : 10 }}>
          {isChamp ? 'Campeao do Major' : 'Campanha encerrada'}
        </div>

        <div style={{ fontFamily:'var(--font-cond)', fontWeight:800,
          color:'#e0e0e0', letterSpacing:'0.02em', textTransform:'uppercase', lineHeight:1.02,
          fontSize:isChamp ? 34 : 30, marginBottom:seriesScore ? 11 : 2 }}>
          {isChamp ? 'Campeao' : 'Eliminado'}
        </div>

        {!isChamp && (
          <div style={{ marginTop:0, marginBottom:seriesScore ? 10 : 0,
            fontFamily:'var(--font-cond)', fontSize:16, fontWeight:800,
            color:'#96999d', textTransform:'uppercase',
            overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
            POR {opponentLine}
          </div>
        )}

        {seriesScore && (
          <>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'center', gap:20 }}>
              <div style={{ textAlign:'center' }}>
                <div style={{ fontFamily:'var(--font-cond)', fontSize:10, color:'#7d8389',
                  letterSpacing:'0.16em', textTransform:'uppercase', marginBottom:2,
                  maxWidth:132, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                  {teamLine}
                </div>
                <div style={{ fontFamily:'var(--font-mono)', fontSize:62, fontWeight:700, lineHeight:0.85,
                  color:'#f4a523' }}>{mine}</div>
              </div>
              <span style={{ fontFamily:'var(--font-mono)', fontSize:34, fontWeight:700,
                color:'#4e5459', transform:'translateY(-6px)' }}>:</span>
              <div style={{ textAlign:'center' }}>
                <div style={{ fontFamily:'var(--font-cond)', fontSize:10, color:'#7d8389',
                  letterSpacing:'0.16em', textTransform:'uppercase', marginBottom:2,
                  maxWidth:120, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                  {opponentName || 'Final'}
                </div>
                <div style={{ fontFamily:'var(--font-mono)', fontSize:62, fontWeight:700, lineHeight:0.85,
                  color:'#e0e0e0' }}>{theirs}</div>
              </div>
            </div>
            <div style={{ marginTop:8, display:'flex', justifyContent:'center', gap:8, flexWrap:'wrap' }}>
              <span style={{ fontFamily:'var(--font-cond)', fontSize:11, fontWeight:800,
                color:'#96999d', letterSpacing:'0.12em', textTransform:'uppercase' }}>
                {stageLine}
              </span>
              {campaignLine && (
                <span style={{ fontFamily:'var(--font-cond)', fontSize:11, fontWeight:800,
                  color:'#f4a523', letterSpacing:'0.08em', textTransform:'uppercase' }}>
                  {campaignLine}
                </span>
              )}
            </div>
            {seriesSummary?.maps?.length > 0 && (
              <div style={{ marginTop:10, display:'flex', justifyContent:'center',
                flexWrap:'wrap', gap:5 }}>
                {seriesSummary.maps.map((map, index) => (
                  <span key={`${map.mapId}-${index}`} style={{
                    padding:'4px 7px', borderRadius:4,
                    background:map.won ? 'rgba(244,165,35,0.12)' : 'rgba(160,80,80,0.12)',
                    border:`1px solid ${map.won ? 'rgba(244,165,35,0.28)' : 'rgba(160,80,80,0.28)'}`,
                    fontFamily:'var(--font-cond)', fontSize:10, fontWeight:800,
                    color:map.won ? '#f4a523' : '#d46a6a',
                    letterSpacing:'0.04em', textTransform:'uppercase' }}>
                    M{index + 1} {map.name} {map.score?.[0]}:{map.score?.[1]}{map.overtime ? ' OT' : ''}
                  </span>
                ))}
              </div>
            )}
            {isPerfect && (
              <div style={{ display:'inline-flex', alignItems:'center', gap:7, marginTop:14,
                padding:'5px 16px', background:'rgba(244,165,35,0.12)',
                border:'1px solid rgba(244,165,35,0.4)', borderRadius:5 }}>
                <span style={{ fontFamily:'var(--font-cond)', fontWeight:800, fontSize:12,
                  color:'#f4a523', letterSpacing:'0.14em' }}>VITORIA PERFEITA {targetScore}</span>
              </div>
            )}
          </>
        )}
      </div>

      <div style={{ position:'relative', padding:'12px 22px 0', flex:1 }}>
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:9 }}>
          <span style={{ fontFamily:'var(--font-cond)', fontWeight:700, fontSize:10,
            color:'#7d8389', letterSpacing:'0.16em', textTransform:'uppercase', whiteSpace:'nowrap' }}>
            Meu elenco
          </span>
          <div style={{ flex:1, height:1, background:'#1c1f21' }} />
          <span style={{ display:'inline-flex', alignItems:'center', gap:5 }}>
            <span style={{ fontFamily:'var(--font-cond)', fontSize:9, color:'#7d8389',
              letterSpacing:'0.12em', textTransform:'uppercase' }}>OVR</span>
            <span style={{ fontFamily:'var(--font-mono)', fontSize:18, fontWeight:700,
              color:'#f4a523', lineHeight:1 }}>{overall}</span>
          </span>
        </div>

        <div style={{ display:'flex', flexDirection:'column', gap:5 }}>
          {roster.map(p => (
            <div key={p.id} style={{ display:'flex', alignItems:'center', gap:10,
              padding:'7px 11px', background:'#16191a', border:'1px solid #222728',
              borderRadius:6 }}>
              <ShareRankIcon tier={p.tier} size={22} />
              <window.Flag value={p.country} size={20} />
              <span style={{ flex:1, fontFamily:'var(--font-cond)', fontWeight:800, fontSize:15,
                color:'#e0e0e0', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
                {p.name}
              </span>
              <window.RoleBadge role={p.role} />
              <span style={{ fontFamily:'var(--font-mono)', fontSize:17, fontWeight:700,
                color:'#f4a523', width:26, textAlign:'right' }}>{p.overall}</span>
            </div>
          ))}
        </div>
      </div>

      <div style={{ position:'relative', margin:'16px 22px 20px', padding:'13px 18px',
        background:'linear-gradient(90deg, rgba(244,165,35,0.1), rgba(244,165,35,0.03))',
        border:'1px solid rgba(244,165,35,0.25)', borderRadius:8,
        display:'flex', alignItems:'center', justifyContent:'space-between', gap:12 }}>
        <div style={{ textAlign:'left', minWidth:0 }}>
          <div style={{ fontFamily:'var(--font-cond)', fontWeight:800, fontSize:14,
            color:'#e0e0e0', letterSpacing:'0.02em', lineHeight:1.2, whiteSpace:'nowrap' }}>
            Monte o time dos sonhos
          </div>
          <div style={{ fontFamily:'var(--font-cond)', fontSize:11, color:'#96999d',
            letterSpacing:'0.03em', whiteSpace:'nowrap', marginTop:2 }}>
            Lendas do CS - 1.6 -> CS2 - busque o {targetScore}
          </div>
        </div>
        <div style={{ fontFamily:'var(--font-cond)', fontWeight:800, fontSize:15,
          color:'#f4a523', letterSpacing:'0.04em', whiteSpace:'nowrap', flexShrink:0 }}>
          jogue 16x0
        </div>
      </div>
    </div>
  );
}

function loadShareImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = reject;
    img.src = src;
  });
}

function rrect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + r, y, r);
  ctx.closePath();
}

function trimCanvasText(ctx, text, maxWidth) {
  let out = String(text || '');
  while (ctx.measureText(out).width > maxWidth && out.length > 2) out = out.slice(0, -1);
  return out.length < String(text || '').length ? out + '...' : out;
}

function drawShareRoleBadge(ctx, role, x, y) {
  const rm = window.ROLE_META[role] || { color:'#7d8389', label:role || 'PLY' };
  ctx.font = '800 10px Barlow Condensed, sans-serif';
  const label = rm.label || role || 'PLY';
  const w = ctx.measureText(label).width + 12;
  ctx.fillStyle = 'rgba(255,255,255,0.05)';
  rrect(ctx, x - w, y, w, 16, 3);
  ctx.fill();
  ctx.strokeStyle = `${rm.color}55`;
  rrect(ctx, x - w, y, w, 16, 3);
  ctx.stroke();
  ctx.fillStyle = rm.color;
  ctx.textAlign = 'center';
  ctx.fillText(label, x - w / 2, y + 11.5);
  return w;
}

async function renderShareCanvas(data) {
  const { type, players, overall, score, opponentName, isPerfect, teamName, seriesSummary, campaignSummary } = data;
  const isChamp = type === 'champion';
  const format = window.getMatchFormat(data.matchFormat || 'MR16');
  const targetScore = data.perfectScore || format.perfectScore;
  const campaignSeedLabel = shareSeed(data);
  const roster = shareRoster(players);
  const teamLine = String(teamName || shareText('Meu Time', 'My Team', 'Моя команда')).toUpperCase();
  const seriesScore = seriesSummary?.score || score;
  const seriesStageLabel = shareTranslate(seriesSummary?.stageLabel || 'Série');
  const stageLine = seriesSummary
    ? `${seriesStageLabel} - BO${seriesSummary.bo || 1}`
    : (isChamp ? shareText('Grande final', 'Grand final', 'Гранд-финал') : shareText('Última série', 'Last series', 'Последняя серия'));
  const campaignLine = campaignSummary?.totalRecord
    ? `${shareText('Campanha', 'Campaign', 'Кампания')} ${campaignSummary.totalRecord}`
    : (campaignSummary?.swissRecord ? `${shareText('Suíço', 'Swiss', 'Швейцарка')} ${campaignSummary.swissRecord}` : '');

  const W = 480, H = 680, S = 2;
  const canvas = document.createElement('canvas');
  canvas.width = W * S;
  canvas.height = H * S;
  const ctx = canvas.getContext('2d');
  ctx.scale(S, S);
  ctx.textBaseline = 'alphabetic';

  try { if (document.fonts && document.fonts.ready) await document.fonts.ready; } catch (e) {}

  const COND = 'Barlow Condensed, sans-serif';
  const MONO = 'JetBrains Mono, monospace';

  ctx.fillStyle = '#0d0f10';
  ctx.fillRect(0, 0, W, H);
  const glow = ctx.createRadialGradient(W/2, -20, 20, W/2, -20, 340);
  glow.addColorStop(0, 'rgba(244,165,35,0.16)');
  glow.addColorStop(1, 'rgba(244,165,35,0)');
  ctx.fillStyle = glow;
  ctx.fillRect(0, 0, W, 280);
  ctx.strokeStyle = '#252a2d';
  ctx.lineWidth = 1;
  rrect(ctx, 0.5, 0.5, W - 1, H - 1, 13);
  ctx.stroke();

  ctx.textAlign = 'left';
  ctx.font = '800 30px ' + COND;
  let hx = 24;
  ctx.fillStyle = '#e0e0e0'; ctx.fillText('16', hx, 46); hx += ctx.measureText('16').width;
  ctx.fillStyle = '#4e5459'; ctx.font = '600 30px ' + COND; ctx.fillText('x', hx, 46); hx += ctx.measureText('x').width;
  ctx.fillStyle = '#f4a523'; ctx.font = '800 30px ' + COND; ctx.fillText('0', hx, 46);

  ctx.textAlign = 'right';
  ctx.fillStyle = '#7d8389';
  ctx.font = '700 10px ' + COND;
  ctx.fillText(shareText('SIMULADOR DE MAJOR', 'MAJOR SIMULATOR', 'СИМУЛЯТОР MAJOR'), W - 24, 34);
  ctx.fillText(`SEED #${campaignSeedLabel}`, W - 24, 47);

  ctx.textAlign = 'center';
  ctx.fillStyle = isChamp ? '#f4a523' : '#96999d';
  ctx.font = '700 12px ' + COND;
  ctx.fillText(shareSpaced(isChamp ? shareText('CAMPEÃO DO MAJOR', 'MAJOR CHAMPION', 'ЧЕМПИОН MAJOR') : shareText('CAMPANHA ENCERRADA', 'CAMPAIGN ENDED', 'КАМПАНИЯ ЗАВЕРШЕНА')), W / 2, 82);
  ctx.fillStyle = '#e0e0e0';
  ctx.font = '800 34px ' + COND;
  ctx.fillText(isChamp ? shareText('CAMPEÃO', 'CHAMPION', 'ЧЕМПИОН') : shareText('ELIMINADO', 'ELIMINATED', 'ВЫЛЕТЕЛ'), W / 2, 122);

  if (!isChamp) {
    ctx.fillStyle = '#96999d';
    ctx.font = '800 16px ' + COND;
    ctx.fillText(`${shareText('POR', 'BY', 'ОТ')} ` + trimCanvasText(ctx, String(opponentName || shareText('UM ADVERSÁRIO', 'AN OPPONENT', 'СОПЕРНИК')).toUpperCase(), 290), W / 2, 148);
  }

  if (seriesScore) {
    const lx = 150, rx = 330, cx = 240;
    const labelY = isChamp ? 152 : 176;
    const scoreY = isChamp ? 214 : 238;
    ctx.fillStyle = '#7d8389';
    ctx.font = '700 10px ' + COND;
    ctx.fillText(trimCanvasText(ctx, teamLine, 150), lx, labelY);
    ctx.fillText(trimCanvasText(ctx, String(opponentName || 'FINAL').toUpperCase(), 150), rx, labelY);

    ctx.font = '700 62px ' + MONO;
    ctx.fillStyle = '#f4a523';
    ctx.fillText(String(seriesScore[0]), lx, scoreY);
    ctx.fillStyle = '#4e5459';
    ctx.font = '700 34px ' + MONO;
    ctx.fillText(':', cx, scoreY - 8);
    ctx.fillStyle = '#e0e0e0';
    ctx.font = '700 62px ' + MONO;
    ctx.fillText(String(seriesScore[1]), rx, scoreY);

    ctx.fillStyle = '#96999d';
    ctx.font = '800 11px ' + COND;
    ctx.fillText(String(stageLine).toUpperCase(), W / 2, scoreY + 22);
    if (campaignLine) {
      ctx.fillStyle = '#f4a523';
      ctx.fillText(String(campaignLine).toUpperCase(), W / 2, scoreY + 38);
    }

    if (seriesSummary?.maps?.length) {
      const y = scoreY + 58;
      const maps = seriesSummary.maps.slice(0, 3);
      const totalW = maps.reduce((sum, map, index) => {
        ctx.font = '800 10px ' + COND;
        const text = `M${index + 1} ${map.name} ${map.score?.[0]}:${map.score?.[1]}${map.overtime ? ' OT' : ''}`;
        return sum + Math.min(138, ctx.measureText(text).width + 18) + (index ? 6 : 0);
      }, 0);
      let x = W / 2 - totalW / 2;
      maps.forEach((map, index) => {
        const text = `M${index + 1} ${map.name} ${map.score?.[0]}:${map.score?.[1]}${map.overtime ? ' OT' : ''}`;
        ctx.font = '800 10px ' + COND;
        const tw = Math.min(138, ctx.measureText(text).width + 18);
        ctx.fillStyle = map.won ? 'rgba(244,165,35,0.12)' : 'rgba(160,80,80,0.12)';
        rrect(ctx, x, y - 14, tw, 22, 4);
        ctx.fill();
        ctx.strokeStyle = map.won ? 'rgba(244,165,35,0.28)' : 'rgba(160,80,80,0.28)';
        rrect(ctx, x, y - 14, tw, 22, 4);
        ctx.stroke();
        ctx.fillStyle = map.won ? '#f4a523' : '#d46a6a';
        ctx.fillText(trimCanvasText(ctx, text.toUpperCase(), tw - 10), x + tw / 2, y + 1);
        x += tw + 6;
      });
    }

    if (isPerfect) {
      ctx.font = '800 12px ' + COND;
      const text = `${shareText('VITÓRIA PERFEITA', 'PERFECT VICTORY', 'ИДЕАЛЬНАЯ ПОБЕДА')} ${targetScore}`;
      const tw = ctx.measureText(text).width + 28;
      ctx.fillStyle = 'rgba(244,165,35,0.12)';
      rrect(ctx, W / 2 - tw / 2, 310, tw, 24, 5);
      ctx.fill();
      ctx.strokeStyle = 'rgba(244,165,35,0.4)';
      rrect(ctx, W / 2 - tw / 2, 310, tw, 24, 5);
      ctx.stroke();
      ctx.fillStyle = '#f4a523';
      ctx.fillText(text, W / 2, 326);
    }
  }

  const padX = 22, rosterTop = seriesScore ? 350 : 232;
  ctx.textAlign = 'left';
  ctx.fillStyle = '#7d8389';
  ctx.font = '700 10px ' + COND;
  ctx.fillText(shareSpaced(shareText('MEU ELENCO', 'MY ROSTER', 'МОЙ СОСТАВ')), padX, rosterTop);
  ctx.textAlign = 'right';
  ctx.fillStyle = '#7d8389';
  ctx.font = '700 9px ' + COND;
  ctx.fillText('OVR', W - padX - 34, rosterTop);
  ctx.fillStyle = '#f4a523';
  ctx.font = '700 18px ' + MONO;
  ctx.fillText(String(overall), W - padX, rosterTop + 1);
  ctx.strokeStyle = '#1c1f21';
  ctx.beginPath();
  ctx.moveTo(padX + 80, rosterTop - 4);
  ctx.lineTo(W - padX - 56, rosterTop - 4);
  ctx.stroke();

  const rowH = 40, gap = 6, rx0 = padX, rw = W - padX * 2;
  for (let i = 0; i < roster.length; i++) {
    const p = roster[i];
    const ry = rosterTop + 12 + i * (rowH + gap);
    ctx.fillStyle = '#16191a';
    rrect(ctx, rx0, ry, rw, rowH, 6);
    ctx.fill();
    ctx.strokeStyle = '#222728';
    rrect(ctx, rx0, ry, rw, rowH, 6);
    ctx.stroke();

    const rankImg = await loadShareImage(shareRankPath(p.tier)).catch(() => null);
    if (rankImg) ctx.drawImage(rankImg, rx0 + 10, ry + 9, 22, 22);

    const flagImg = await loadShareImage(`/assets/flags/${shareFlagCode(p.country)}.svg`).catch(() => null);
    if (flagImg) ctx.drawImage(flagImg, rx0 + 40, ry + 12, 20, 14);

    const ovr = String(p.overall);
    ctx.textAlign = 'right';
    ctx.font = '700 17px ' + MONO;
    ctx.fillStyle = '#f4a523';
    ctx.fillText(ovr, rx0 + rw - 12, ry + 25);
    const ovrW = ctx.measureText(ovr).width;

    const badgeRight = rx0 + rw - 12 - ovrW - 12;
    const badgeW = drawShareRoleBadge(ctx, p.role, badgeRight, ry + 12);

    ctx.textAlign = 'left';
    ctx.font = '800 16px ' + COND;
    ctx.fillStyle = '#e0e0e0';
    ctx.fillText(trimCanvasText(ctx, p.name, badgeRight - badgeW - (rx0 + 70) - 8), rx0 + 70, ry + 25);
  }

  const fy = H - 88, fx = padX, fw = W - padX * 2, fh2 = 64;
  ctx.fillStyle = '#1a160d';
  rrect(ctx, fx, fy, fw, fh2, 8);
  ctx.fill();
  ctx.strokeStyle = 'rgba(244,165,35,0.3)';
  rrect(ctx, fx, fy, fw, fh2, 8);
  ctx.stroke();
  ctx.textAlign = 'left';
  ctx.fillStyle = '#e0e0e0';
  ctx.font = '800 15px ' + COND;
  ctx.fillText(shareText('Monte o time dos sonhos', 'Build your dream team', 'Соберите команду мечты'), fx + 18, fy + 28);
  ctx.fillStyle = '#96999d';
  ctx.font = '600 11px ' + COND;
  ctx.fillText(shareText(`Lendas do CS - 1.6 -> CS2 - busque o ${targetScore}`, `CS legends - 1.6 -> CS2 - chase ${targetScore}`, `Легенды CS - 1.6 -> CS2 - цель ${targetScore}`), fx + 18, fy + 46);
  ctx.textAlign = 'right';
  ctx.fillStyle = '#f4a523';
  ctx.font = '800 16px ' + COND;
  ctx.fillText(shareText('jogue 16x0', 'play 16x0', 'играть 16x0'), fx + fw - 16, fy + 39);

  return canvas;
}

async function renderShareFile(data) {
  const canvas = await renderShareCanvas(data);
  const blob = await new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
  if (!blob) throw new Error('share image blob failed');
  return new File([blob], '16a0-campanha.png', { type:'image/png' });
}

function downloadShareFile(file) {
  const url = URL.createObjectURL(file);
  const a = document.createElement('a');
  a.download = file.name || '16a0-campanha.png';
  a.href = url;
  a.click();
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

function ShareOverlay({ data, onClose, standalone = false }) {
  const [busy, setBusy] = useShareSt(false);
  const [note, setNote] = useShareSt('');
  const isMobile = window.useIsMobileView?.(760) || false;
  const previewScale = isMobile
    ? Math.max(0.62, Math.min(1, (window.innerWidth - 28) / 480, (window.innerHeight - 248) / 680))
    : 1;
  const previewWidth = 480 * previewScale;
  const previewHeight = 680 * previewScale;
  const seed = shareSeed(data);
  const publicLink = sharePublicGameUrl();
  const displayLink = publicLink;

  useShareEf(() => {
    if ((window.location.hash || '').startsWith('#share=')) {
      return;
    }
    openShareRoute(data);
  }, [data?.seed, data?.campaignSeed, data?.type, data?.overall]);

  async function download() {
    setBusy(true);
    setNote('');
    try {
      const file = await renderShareFile(data);
      downloadShareFile(file);
      setNote(shareText('Imagem salva.', 'Image saved.', 'Изображение сохранено.'));
    } catch (e) {
      setNote(shareText('Não consegui gerar o PNG. Use um print desta tela.', 'Could not generate the PNG. Use a screenshot of this screen.', 'Не удалось создать PNG. Сделайте скриншот этой страницы.'));
    } finally {
      setBusy(false);
    }
  }

  async function copyLink() {
    try {
      await navigator.clipboard.writeText(publicLink);
      setNote(shareText('Link copiado.', 'Link copied.', 'Link copied.'));
    } catch (_) {
      const input = document.createElement('input');
      input.value = publicLink;
      document.body.appendChild(input);
      input.select();
      document.execCommand('copy');
      input.remove();
      setNote(shareText('Link copiado.', 'Link copied.', 'Link copied.'));
    }
  }

  async function nativeShare(fallbackKind = null) {
    const text = shareMessage(data, publicLink);
    if (!navigator.share) {
      await copyLink();
      return;
    }
    setBusy(true);
    setNote('');
    try {
      const file = await renderShareFile(data);
      if (navigator.canShare?.({ files:[file] })) {
        await navigator.share({ title:'16a0', text, files:[file] });
      } else if (fallbackKind) {
        downloadShareFile(file);
        window.open(shareSocialUrl(fallbackKind, data, publicLink), '_blank', 'noopener,noreferrer');
      } else {
        await navigator.share({ title:'16a0', text });
      }
      setNote(shareText('Compartilhamento aberto.', 'Share sheet opened.', 'Share sheet opened.'));
    } catch (_) {
      // User cancellations should not become an error state.
    } finally {
      setBusy(false);
    }
  }

  async function shareWhatsApp() {
    if (navigator.share) {
      await nativeShare('whatsapp');
      return;
    }
    await download();
    window.open(shareSocialUrl('whatsapp', data, publicLink), '_blank', 'noopener,noreferrer');
  }

  function openSocial(kind) {
    window.open(shareSocialUrl(kind, data, publicLink), '_blank', 'noopener,noreferrer');
  }

  function close() {
    clearShareRoute();
    onClose?.();
  }

  const actionButton = (label, onClick, variant = 'dark', icon = null) => (
    <button onClick={onClick} style={{
      padding:isMobile ? '10px 12px' : '11px 16px',
      minHeight:42,
      background:variant === 'accent' ? 'var(--accent)' : 'var(--bg-3)',
      border:variant === 'accent' ? 'none' : '1px solid var(--border-2)',
      borderRadius:'var(--r-md)',
      color:variant === 'accent' ? '#15110a' : 'var(--text-1)',
      fontFamily:'var(--font-cond)', fontSize:12, fontWeight:800,
      letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer',
      display:'inline-flex', alignItems:'center', justifyContent:'center', gap:8,
      whiteSpace:'nowrap', minWidth:0, flex:isMobile ? '1 1 calc(50% - 6px)' : '0 0 auto',
    }}>
      {icon}
      {label}
    </button>
  );

  return (
    <div onClick={standalone ? undefined : close} style={{ position:'fixed', inset:0, zIndex:400,
      background:'radial-gradient(ellipse 90% 55% at 50% -10%, rgba(244,165,35,0.13), transparent 62%), var(--bg-1)',
      display:'flex', flexDirection:'column', alignItems:'center',
      justifyContent:'flex-start',
      padding:isMobile ? '14px 14px 18px' : '28px 24px 32px', overflowY:'auto', overflowX:'hidden' }}>
      <div onClick={e => e.stopPropagation()} style={{ display:'flex', flexDirection:'column',
        alignItems:'center', gap:isMobile ? 10 : 14, width:isMobile ? '100%' : 'min(1120px, 100%)' }}>
        <div style={{ width:'100%', maxWidth:920, display:'flex', alignItems:isMobile ? 'flex-start' : 'center',
          justifyContent:'space-between', gap:14, flexDirection:isMobile ? 'column' : 'row' }}>
          <div>
            <div style={{ fontFamily:'var(--font-cond)', fontWeight:800,
              fontSize:isMobile ? 24 : 38, lineHeight:0.95, color:'var(--text-1)',
              letterSpacing:'0.02em', textTransform:'uppercase', maxWidth:'100%',
              overflowWrap:'break-word' }}>
              {shareText('Compartilhar campanha', 'Share campaign', 'Share campaign')}
            </div>
            <div style={{ marginTop:8, display:'flex', flexWrap:'wrap', gap:8, alignItems:'center' }}>
              <span style={{ fontFamily:'var(--font-mono)', fontSize:12, fontWeight:800,
                color:'var(--accent)', letterSpacing:'0.08em', textTransform:'uppercase',
                padding:'5px 9px', border:'1px solid rgba(244,165,35,0.32)',
                borderRadius:'var(--r-sm)', background:'rgba(244,165,35,0.08)' }}>
                seed #{seed}
              </span>
              <span style={{ fontFamily:'var(--font-cond)', fontSize:12, fontWeight:700,
                color:'var(--text-3)', letterSpacing:'0.08em', textTransform:'uppercase' }}>
                {shareText('Imagem + link prontos', 'Image + link ready', 'Image + link ready')}
              </span>
            </div>
          </div>
          <button onClick={close} style={{ padding:'9px 14px',
            background:'transparent', border:'1px solid var(--border-2)', borderRadius:'var(--r-md)',
            color:'var(--text-2)', fontFamily:'var(--font-cond)', fontSize:12, fontWeight:800,
            letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer' }}>
            {shareText('Fechar', 'Close', 'Close')}
          </button>
        </div>

        <div style={{ width:previewWidth, height:previewHeight,
          maxWidth:'100%', flexShrink:0, position:'relative' }}>
          <div style={{ width:480, height:680, transform:`scale(${previewScale})`,
            transformOrigin:isMobile ? 'top left' : 'top center',
            position:'absolute', left:isMobile ? 0 : '50%', top:0,
            marginLeft:isMobile ? 0 : -240 }}>
            <ShareCard {...data} />
          </div>
        </div>

        <div style={{ display:'flex', gap:8, alignItems:'center', flexWrap:'wrap',
          width:isMobile ? '100%' : 'auto', maxWidth:isMobile ? 520 : 'none',
          justifyContent:'center' }}>
          {actionButton(
            busy ? 'Gerando...' : shareText('Baixar imagem', 'Download image', 'Download image'),
            download,
            'accent',
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor"
              strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 3v12M7 10l5 5 5-5M5 21h14" />
            </svg>
          )}
          {navigator.share && actionButton(shareText('Compartilhar', 'Share', 'Share'), nativeShare)}
          {actionButton('WhatsApp', shareWhatsApp)}
          {actionButton('Telegram', () => openSocial('telegram'))}
          {actionButton('X', () => openSocial('x'))}
          {actionButton(shareText('Copiar link', 'Copy link', 'Copy link'), copyLink)}
        </div>
        <div style={{ width:'100%', maxWidth:isMobile ? '100%' : 760,
          padding:'10px 12px', background:'rgba(255,255,255,0.035)',
          border:'1px solid var(--border-1)', borderRadius:'var(--r-md)',
          color:'var(--text-2)', fontFamily:'var(--font-mono)', fontSize:11,
          lineHeight:1.5, wordBreak:'break-word', textAlign:'center' }}>
          {shareMessage(data, displayLink)}
        </div>
        {note && (
          <span style={{ fontFamily:'var(--font-cond)', fontSize:11, color:'var(--text-3)',
            letterSpacing:'0.04em' }}>{note}</span>
        )}
      </div>
    </div>
  );
}

Object.assign(window, {
  ShareCard,
  ShareOverlay,
  renderShareCanvas,
  encodeSharePayload,
  decodeSharePayload,
  readShareRoute,
  openShareRoute,
  clearShareRoute,
  shareUrlForData,
  shareMessage,
  shareSeed,
});
