// Full data layer — JSONBin backend

const JSONBIN_KEY = "$2a$10$3yt0Qag7/dBSMpw.JxKlyuAUEJ5C9VoimIRourSn.qXYYaOcehi42";

const JSONBIN_HEADERS = {
  "Content-Type": "application/json",
  "X-Access-Key": JSONBIN_KEY,
};

// ── Known groups (hardcoded; new groups created via UI use localStorage) ─────
const GROUP_CONFIGS = {
  samawar: {
    slug:  "samawar",
    binId: "69e795b6856a682189599665",
    name:  "السماور",
    icon:  "♠",
    color: "#f5c542",
  },
};

// Resolve binId for a slug: hardcoded → ?bid= URL param → localStorage
function getGroupBinId(slug) {
  if (GROUP_CONFIGS[slug]) return GROUP_CONFIGS[slug].binId;
  const bid = new URLSearchParams(window.location.search).get("bid");
  if (bid) {
    try { localStorage.setItem(`shilletna.${slug}`, bid); } catch {}
    return bid;
  }
  try { return localStorage.getItem(`shilletna.${slug}`); } catch { return null; }
}

// Create a new group bin on JSONBin and cache binId in localStorage
async function createGroup(slug, name, icon) {
  const res = await fetch("https://api.jsonbin.io/v3/b", {
    method: "POST",
    headers: { ...JSONBIN_HEADERS, "X-Bin-Name": `shilletna-${slug}`, "X-Bin-Private": "true" },
    body: JSON.stringify({ ...DEFAULT_DB }),
  });
  if (!res.ok) throw new Error("فشل إنشاء المجموعة");
  const json = await res.json();
  const binId = json.metadata.id;
  try { localStorage.setItem(`shilletna.${slug}`, binId); } catch {}
  return binId;
}

// ── Palettes ─────────────────────────────────────────────────
const PALETTES = [
  { bg: "#22d3ee", glow: "#22d3ee" },
  { bg: "#ff4fa3", glow: "#ff4fa3" },
  { bg: "#d9f635", glow: "#d9f635" },
  { bg: "#ff8c42", glow: "#ff8c42" },
  { bg: "#a78bfa", glow: "#a78bfa" },
  { bg: "#f5c542", glow: "#f5c542" },
  { bg: "#fb7185", glow: "#fb7185" },
  { bg: "#4ade80", glow: "#4ade80" },
];

// ── Default DB structure (first run) ─────────────────────────
const DEFAULT_DB = {
  players: [
    { id: 1, name: "لاعب ١", nick: "١", paletteIndex: 0 },
    { id: 2, name: "لاعب ٢", nick: "٢", paletteIndex: 1 },
    { id: 3, name: "لاعب ٣", nick: "٣", paletteIndex: 2 },
    { id: 4, name: "لاعب ٤", nick: "٤", paletteIndex: 3 },
    { id: 5, name: "لاعب ٥", nick: "٥", paletteIndex: 4 },
    { id: 6, name: "لاعب ٦", nick: "٦", paletteIndex: 5 },
    { id: 7, name: "لاعب ٧", nick: "٧", paletteIndex: 6 },
    { id: 8, name: "لاعب ٨", nick: "٨", paletteIndex: 7 },
  ],
  matches: [],
  badges: [],
};

function migrateDB(record) {
  if (!record.players) return record;
  const fixed = record.players.map((p, i) => {
    const arabicNums = ["١","٢","٣","٤","٥","٦","٧","٨"];
    const needsFix = /لاعب \d/.test(p.name) || !p.nick || p.nick.trim() === "";
    return needsFix ? {
      ...p,
      name: `لاعب ${arabicNums[i] || (i+1)}`,
      nick: arabicNums[i] || String(i+1),
    } : p;
  });
  return { ...record, players: fixed };
}

// ── API calls (use DB.binId set by load) ──────────────────────
async function dbRead() {
  const url = `https://api.jsonbin.io/v3/b/${DB.binId}/latest`;
  const res = await fetch(url, { headers: JSONBIN_HEADERS });
  if (!res.ok) throw new Error("فشل تحميل البيانات");
  const json = await res.json();
  return json.record;
}

async function dbWrite(data) {
  const url = `https://api.jsonbin.io/v3/b/${DB.binId}`;
  const res = await fetch(url, {
    method: "PUT",
    headers: JSONBIN_HEADERS,
    body: JSON.stringify(data),
  });
  if (!res.ok) throw new Error("فشل حفظ البيانات");
  return res.json();
}

// ── Computed stats from match history ────────────────────────
function computeStats(players, matches) {
  const stats = {};
  players.forEach(p => {
    stats[p.id] = {
      overall: { wins: 0, losses: 0 },
      tarneeb: { wins: 0, losses: 0 },
      trix:    { wins: 0, losses: 0 },
      partnerships: {},
    };
    players.forEach(other => {
      if (other.id !== p.id) stats[p.id].partnerships[other.id] = { wins: 0, losses: 0 };
    });
  });

  matches.forEach(m => {
    const winners = m.winner === "A" ? m.teamA : m.teamB;
    const losers  = m.winner === "A" ? m.teamB : m.teamA;
    const gameKey = m.game === "طرنيب" ? "tarneeb" : "trix";

    winners.forEach(pid => {
      stats[pid].overall.wins++;
      stats[pid][gameKey].wins++;
      const partner = winners.find(x => x !== pid);
      if (partner) stats[pid].partnerships[partner].wins++;
    });

    losers.forEach(pid => {
      stats[pid].overall.losses++;
      stats[pid][gameKey].losses++;
      const partner = losers.find(x => x !== pid);
      if (partner) stats[pid].partnerships[partner].losses++;
    });
  });

  return stats;
}

function enrichPlayers(players, stats) {
  return players.map((p, i) => {
    const s  = stats[p.id];
    const ps = s.partnerships;
    const palette = PALETTES[p.paletteIndex ?? i] || PALETTES[i % PALETTES.length];

    const bestId  = Object.keys(ps).sort((a, b) => ps[b].wins   - ps[a].wins)[0];
    const worstId = Object.keys(ps).sort((a, b) => ps[b].losses - ps[a].losses)[0];

    return {
      ...p,
      palette,
      wins:          s.overall.wins,
      losses:        s.overall.losses,
      tarneeb:       s.tarneeb.wins,
      trix:          s.trix.wins,
      tarneebLosses: s.tarneeb.losses,
      trixLosses:    s.trix.losses,
      bestPartner:   Number(bestId),
      worstPartner:  Number(worstId),
      partnerStats:  ps,
    };
  });
}

function winRate(p) {
  const total = p.wins + p.losses;
  return total ? Math.round((p.wins / total) * 100) : 0;
}

function rankLabel(i) {
  if (i === 0) return "الأول";
  if (i === 1) return "الثاني";
  if (i === 2) return "الثالث";
  return `#${i + 1}`;
}

function arabicDateLabel(dateInput) {
  const date     = new Date(dateInput);
  const now      = new Date();
  const diffMs   = now - date;
  const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
  if (diffDays === 0) return "اليوم";
  if (diffDays === 1) return "أمس";
  if (diffDays <= 6) {
    const days = ["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"];
    return days[date.getDay()];
  }
  if (diffDays <= 13) return "منذ أسبوع";
  if (diffDays <= 20) return "منذ أسبوعين";
  return "منذ شهر";
}

// ── Global reactive store ─────────────────────────────────────
const DB = {
  binId:    null,
  raw:      null,
  players:  [],
  matches:  [],
  badges:   [],
  loading:  true,   // start true to prevent empty-data flash
  error:    null,
  listeners: [],

  notify() { this.listeners.forEach(fn => fn()); },

  subscribe(fn) {
    this.listeners.push(fn);
    return () => { this.listeners = this.listeners.filter(l => l !== fn); };
  },

  async load(slug) {
    this.loading = true;
    this.error   = null;
    this.notify();
    const binId = getGroupBinId(slug);
    if (!binId) {
      this.error   = "not-found";
      this.loading = false;
      this.notify();
      return;
    }
    this.binId = binId;
    try {
      let record = await dbRead();
      if (!record.players || record.players.length === 0) {
        record = DEFAULT_DB;
        await dbWrite(record);
      }
      record = migrateDB(record);
      this._apply(record);
    } catch (e) {
      this.error = e.message;
    }
    this.loading = false;
    this.notify();
  },

  _apply(record) {
    this.raw     = record;
    const stats  = computeStats(record.players, record.matches || []);
    this.players = enrichPlayers(record.players, stats);
    this.matches = [...(record.matches || [])].reverse();
    this.badges  = record.badges || [];
    window.PLAYERS = this.players;
    window.MATCHES = this.matches;
    window.BADGES  = this.badges;
    this.notify();
  },

  async saveMatch(game, teamA, teamB, winner) {
    const match = { id: Date.now(), game, teamA, teamB, winner, date: new Date().toISOString() };
    const record = { ...this.raw, matches: [...(this.raw.matches || []), match] };
    this._apply(record);
    await dbWrite(record);
  },

  async deleteMatch(matchId) {
    const record = { ...this.raw, matches: (this.raw.matches || []).filter(m => m.id !== matchId) };
    this._apply(record);
    await dbWrite(record);
  },

  async saveBadges(badges) {
    const record = { ...this.raw, badges };
    this._apply(record);
    await dbWrite(record);
  },

  async savePlayers(players) {
    const record = { ...this.raw, players };
    this._apply(record);
    await dbWrite(record);
  },
};

function byId(id)      { return DB.players.find(p => p.id === id); }
function badgesFor(pid) { return DB.badges.filter(b => b.playerIds.includes(pid)); }

Object.assign(window, {
  PALETTES, DB, byId, badgesFor, winRate, rankLabel, arabicDateLabel,
  GROUP_CONFIGS, getGroupBinId, createGroup,
  PLAYERS: DB.players,
  MATCHES: DB.matches,
  BADGES:  DB.badges,
});
