// Utility helpers + i18n
const { useState, useEffect, useMemo, useRef, useCallback } = React;

const I18N = {
  EN: {
    title: 'Player Database',
    subtitle: 'Thailand Women — Centralised Squad Registry',
    senior: 'Senior', u23: 'U23', u20: 'U20', u17: 'U17', u15: 'U15', all: 'All Squads',
    search: 'Search players, clubs, positions…',
    name: 'Name', pos: 'Pos', age: 'Age', dob: 'DOB', foot: 'Foot', height: 'Ht', club: 'Club',
    caps: 'Caps', intGoals: 'Int.G', apps: 'Apps', goals: 'Goals', assists: 'Asst', minutes: 'Mins',
    yellows: 'Y', reds: 'R', shirt: '#', team: 'Team',
    all_positions: 'All positions', all_foot: 'Any foot', all_ages: 'Any age',
    gk: 'GK', def: 'Defender', mid: 'Midfielder', fwd: 'Forward',
    players_found: 'players found',
    import: 'Import', exportCsv: 'Export CSV', exportXml: 'Export XML', addPlayer: 'Add player',
    edit: 'Edit', save: 'Save', cancel: 'Cancel', close: 'Close',
    overview: 'Overview', club_stats: 'Club season', nt_stats: 'National team', career: 'Career history',
    attributes: 'Attribute radar',
    pace: 'Pace', shooting: 'Shooting', passing: 'Passing', dribbling: 'Dribbling', defending: 'Defending', physical: 'Physical',
    drop_csv: 'Drop CSV / XML here', or_click: 'or click to browse',
    biography: 'Biography', from: 'From', to: 'To', period: 'Period',
    profile: 'Profile', condense: 'Condense', expand: 'Expand', sort_by: 'Sort:',
    no_players: 'No players match the current filters.',
    left: 'Left', right: 'Right', both: 'Both',
    tweaks_title: 'Tweaks',
  },
  TH: {
    title: 'ฐานข้อมูลผู้เล่น',
    subtitle: 'ทีมชาติไทยหญิง — ทะเบียนนักเตะรวมศูนย์',
    senior: 'ชุดใหญ่', u23: 'U23', u20: 'U20', u17: 'U17', u15: 'U15', all: 'ทุกชุด',
    search: 'ค้นหาผู้เล่น สโมสร ตำแหน่ง…',
    name: 'ชื่อ', pos: 'ตน.', age: 'อายุ', dob: 'วันเกิด', foot: 'เท้า', height: 'สูง', club: 'สโมสร',
    caps: 'ทีมชาติ', intGoals: 'ปทศ.', apps: 'ลงสนาม', goals: 'ประตู', assists: 'แอสต์', minutes: 'นาที',
    yellows: 'เหลือง', reds: 'แดง', shirt: 'เบอร์', team: 'ชุด',
    all_positions: 'ทุกตำแหน่ง', all_foot: 'ทุกข้างเท้า', all_ages: 'ทุกอายุ',
    gk: 'ผู้รักษาประตู', def: 'กองหลัง', mid: 'กองกลาง', fwd: 'กองหน้า',
    players_found: 'คน',
    import: 'นำเข้า', exportCsv: 'ส่งออก CSV', exportXml: 'ส่งออก XML', addPlayer: 'เพิ่มผู้เล่น',
    edit: 'แก้ไข', save: 'บันทึก', cancel: 'ยกเลิก', close: 'ปิด',
    overview: 'สรุป', club_stats: 'สโมสรฤดูกาลปัจจุบัน', nt_stats: 'ทีมชาติ', career: 'ประวัติการเล่น',
    attributes: 'แผนภูมิคุณสมบัติ',
    pace: 'ความเร็ว', shooting: 'การยิง', passing: 'การจ่าย', dribbling: 'เลี้ยงบอล', defending: 'เกมรับ', physical: 'ร่างกาย',
    drop_csv: 'ลากไฟล์ CSV / XML มาวาง', or_click: 'หรือคลิกเพื่อเลือกไฟล์',
    biography: 'ข้อมูลส่วนตัว', from: 'จาก', to: 'ถึง', period: 'ช่วงเวลา',
    profile: 'โปรไฟล์', condense: 'ลด', expand: 'ขยาย', sort_by: 'เรียง:',
    no_players: 'ไม่พบผู้เล่นที่ตรงกับตัวกรองปัจจุบัน',
    left: 'ซ้าย', right: 'ขวา', both: 'ทั้งสองข้าง',
    tweaks_title: 'ปรับแต่ง',
  },
};

function useI18n(lang) {
  return useCallback((k) => (I18N[lang] && I18N[lang][k]) || I18N.EN[k] || k, [lang]);
}

function ageFromDob(dob) {
  const d = new Date(dob);
  const now = new Date('2026-05-12');
  let a = now.getFullYear() - d.getFullYear();
  const m = now.getMonth() - d.getMonth();
  if (m < 0 || (m === 0 && now.getDate() < d.getDate())) a--;
  return a;
}

function clubByCode(code) {
  return (window.TWNT_DATA.CLUBS).find(c => c.code === code) || { code, name: code, color: '#888' };
}

function posGroup(pos) {
  return window.TWNT_DATA.POSITION_GROUPS[pos] || 'Other';
}

// CSV serialization (simple, quote-escaped)
function toCsv(players) {
  const headers = ['id','name','thaiName','pos','altPos','dob','foot','height','team','club','shirt','caps','intGoals',
    'apps','goals','assists','yellows','reds','minutes',
    'intApps','intG','intA','intY','intR','intMin',
    'pace','shooting','passing','dribbling','defending','physical'];
  const esc = (v) => {
    if (v === null || v === undefined) return '';
    const s = String(v);
    if (s.includes(',') || s.includes('"') || s.includes('\n')) return '"' + s.replace(/"/g,'""') + '"';
    return s;
  };
  const rows = players.map(p => [
    p.id, p.name, p.thaiName, p.pos, (p.altPos||[]).join('|'), p.dob, p.foot, p.height,
    p.team, p.club, p.shirt, p.caps, p.intGoals,
    p.stats.apps, p.stats.goals, p.stats.assists, p.stats.yellows, p.stats.reds, p.stats.minutes,
    p.intStats.apps, p.intStats.goals, p.intStats.assists, p.intStats.yellows, p.intStats.reds, p.intStats.minutes,
    p.radar.pace, p.radar.shooting, p.radar.passing, p.radar.dribbling, p.radar.defending, p.radar.physical
  ].map(esc).join(','));
  return [headers.join(','), ...rows].join('\n');
}

function parseCsv(text) {
  const lines = text.split(/\r?\n/).filter(l => l.trim());
  if (lines.length < 2) return [];
  const parseLine = (line) => {
    const out = []; let cur = ''; let inQ = false;
    for (let i = 0; i < line.length; i++) {
      const c = line[i];
      if (inQ) {
        if (c === '"' && line[i+1] === '"') { cur += '"'; i++; }
        else if (c === '"') { inQ = false; }
        else { cur += c; }
      } else {
        if (c === ',') { out.push(cur); cur = ''; }
        else if (c === '"') { inQ = true; }
        else { cur += c; }
      }
    }
    out.push(cur);
    return out;
  };
  const headers = parseLine(lines[0]);
  return lines.slice(1).map((line, idx) => {
    const cells = parseLine(line);
    const r = {}; headers.forEach((h, i) => r[h] = cells[i] || '');
    return {
      id: r.id || ('imp_' + Date.now() + '_' + idx),
      name: r.name, thaiName: r.thaiName,
      pos: r.pos, altPos: (r.altPos || '').split('|').filter(Boolean),
      dob: r.dob, foot: r.foot || 'R', height: +r.height || 165,
      team: r.team || 'Senior', club: r.club || 'BG',
      shirt: +r.shirt || 0, caps: +r.caps || 0, intGoals: +r.intGoals || 0,
      stats: { apps:+r.apps||0, goals:+r.goals||0, assists:+r.assists||0, yellows:+r.yellows||0, reds:+r.reds||0, minutes:+r.minutes||0 },
      intStats: { apps:+r.intApps||0, goals:+r.intG||0, assists:+r.intA||0, yellows:+r.intY||0, reds:+r.intR||0, minutes:+r.intMin||0 },
      radar: { pace:+r.pace||10, shooting:+r.shooting||10, passing:+r.passing||10, dribbling:+r.dribbling||10, defending:+r.defending||10, physical:+r.physical||10 },
      career: [],
    };
  });
}

function toXml(players) {
  const esc = (s) => String(s).replace(/[<>&"']/g, c => ({'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;',"'":'&apos;'})[c]);
  const out = ['<?xml version="1.0" encoding="UTF-8"?>', '<players>'];
  for (const p of players) {
    out.push(`  <player id="${esc(p.id)}">`);
    out.push(`    <name>${esc(p.name)}</name>`);
    out.push(`    <thaiName>${esc(p.thaiName||'')}</thaiName>`);
    out.push(`    <position primary="${esc(p.pos)}" alt="${esc((p.altPos||[]).join('|'))}"/>`);
    out.push(`    <dob>${esc(p.dob)}</dob>`);
    out.push(`    <foot>${esc(p.foot)}</foot>`);
    out.push(`    <height>${p.height}</height>`);
    out.push(`    <team>${esc(p.team)}</team>`);
    out.push(`    <club>${esc(p.club)}</club>`);
    out.push(`    <shirt>${p.shirt}</shirt>`);
    out.push(`    <caps>${p.caps}</caps>`);
    out.push(`    <intGoals>${p.intGoals}</intGoals>`);
    out.push(`    <club_stats apps="${p.stats.apps}" goals="${p.stats.goals}" assists="${p.stats.assists}" yellows="${p.stats.yellows}" reds="${p.stats.reds}" minutes="${p.stats.minutes}"/>`);
    out.push(`    <nt_stats apps="${p.intStats.apps}" goals="${p.intStats.goals}" assists="${p.intStats.assists}" yellows="${p.intStats.yellows}" reds="${p.intStats.reds}" minutes="${p.intStats.minutes}"/>`);
    out.push(`    <radar pace="${p.radar.pace}" shooting="${p.radar.shooting}" passing="${p.radar.passing}" dribbling="${p.radar.dribbling}" defending="${p.radar.defending}" physical="${p.radar.physical}"/>`);
    out.push(`  </player>`);
  }
  out.push('</players>');
  return out.join('\n');
}

function parseXml(text) {
  const doc = new DOMParser().parseFromString(text, 'application/xml');
  const nodes = doc.querySelectorAll('player');
  const out = [];
  nodes.forEach((n, idx) => {
    const q = (sel) => n.querySelector(sel);
    const attr = (sel, name) => { const e = q(sel); return e ? e.getAttribute(name) : ''; };
    const txt = (sel) => { const e = q(sel); return e ? e.textContent : ''; };
    const posEl = q('position');
    out.push({
      id: n.getAttribute('id') || ('imp_' + idx),
      name: txt('name'),
      thaiName: txt('thaiName'),
      pos: posEl?.getAttribute('primary') || 'CM',
      altPos: (posEl?.getAttribute('alt') || '').split('|').filter(Boolean),
      dob: txt('dob'), foot: txt('foot') || 'R', height: +txt('height') || 165,
      team: txt('team') || 'Senior', club: txt('club') || 'BG',
      shirt: +txt('shirt') || 0, caps: +txt('caps') || 0, intGoals: +txt('intGoals') || 0,
      stats: { apps:+attr('club_stats','apps')||0, goals:+attr('club_stats','goals')||0, assists:+attr('club_stats','assists')||0, yellows:+attr('club_stats','yellows')||0, reds:+attr('club_stats','reds')||0, minutes:+attr('club_stats','minutes')||0 },
      intStats: { apps:+attr('nt_stats','apps')||0, goals:+attr('nt_stats','goals')||0, assists:+attr('nt_stats','assists')||0, yellows:+attr('nt_stats','yellows')||0, reds:+attr('nt_stats','reds')||0, minutes:+attr('nt_stats','minutes')||0 },
      radar: { pace:+attr('radar','pace')||10, shooting:+attr('radar','shooting')||10, passing:+attr('radar','passing')||10, dribbling:+attr('radar','dribbling')||10, defending:+attr('radar','defending')||10, physical:+attr('radar','physical')||10 },
      career: [],
    });
  });
  return out;
}

function downloadFile(name, content, mime) {
  const blob = new Blob([content], { type: mime });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url; a.download = name; a.click();
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

Object.assign(window, {
  useI18n, ageFromDob, clubByCode, posGroup,
  toCsv, parseCsv, toXml, parseXml, downloadFile,
});
