// ============================================================
// DATA — seed trades, confluences, user + stats helpers.
// Self-contained; exported to window for the other scripts.
// ============================================================

const CONFLUENCES = [
  { id: 'fvg',  name: 'FVG' },
  { id: 'ob',   name: 'Order Block' },
  { id: 'htf',  name: 'HTF Bias' },
  { id: 'sweep',name: 'Liquidity Sweep' },
  { id: 'mss',  name: 'MSS' },
  { id: 'bos',  name: 'BOS' },
  { id: 'vwap', name: 'VWAP' },
  { id: 'poi',  name: 'POI' },
  { id: 'pdh',  name: 'Prev High/Low' },
  { id: 'sess', name: 'Session H/L' },
];

const SESSIONS = [
  { id: 'pre', label: 'Pre-market', time: '06:00–09:30' },
  { id: 'open', label: 'NY Open', time: '09:30–11:00' },
  { id: 'mid', label: 'Midday', time: '11:00–14:00' },
  { id: 'pm', label: 'NY Afternoon', time: '14:00–16:00' },
];

const USER = {
  instrument: 'Both',
  sessions: ['open', 'pm'],
  minConfluences: 3,
  email: 'mert@desk.trade',
  plan: 'pro',
};

// ---- deterministic seed of ~22 trades over recent sessions ----
// fields: id, instrument, direction, pnl, conf[], note, ts(min from base)
function seedTrades() {
  const C = (...ids) => ids;
  // Anchored to a fixed reference month (June 2026) so the P&L calendar reads
  // well: ~3 trades across 9 trading days, deliberately varied daily outcomes
  // (two red days, seven green). Net/win-rate/combos identical to before —
  // only the dates changed. row = [inst, dir, pnl, confluences, note, [day,h,m]]
  const raw = [
    // Jun 2 — overtrading, low confluence → red day
    ['ES','Long', -88, C('poi'), 'One confluence. Why.', [2, 9, 50]],
    ['NQ','Short', -210, C('ob','bos'), 'Forced it. Two confluences, no HTF alignment.', [2, 10, 35]],
    ['ES','Long', -140, C('fvg','vwap','sess'), 'Chopped at VWAP, thin edge.', [2, 14, 10]],
    // Jun 3 — disciplined → green
    ['NQ','Long', 412, C('fvg','ob','htf','sweep'), 'Clean sweep of Asia low into NY open, FVG held.', [3, 9, 40]],
    ['NQ','Long', 398, C('fvg','ob','htf'), 'Standard three-confluence base hit.', [3, 11, 15]],
    ['ES','Long', 188, C('fvg','htf'), 'Reclaim of session low, took the retest.', [3, 14, 30]],
    // Jun 5
    ['ES','Short', -95, C('poi','sess','vwap'), 'Counter-trend scalp, should have skipped.', [5, 9, 45]],
    ['NQ','Short', -75, C('vwap'), 'Boredom trade.', [5, 13, 0]],
    ['NQ','Short', 520, C('sweep','mss','htf','ob'), 'Liquidity grab above PDH, dumped to the FVG.', [5, 15, 5]],
    // Jun 8 — big green
    ['NQ','Long', 640, C('fvg','ob','htf','sweep','mss'), 'A+ setup. Everything lined up, sat in it.', [8, 9, 50]],
    ['NQ','Short', 360, C('ob','bos','htf'), 'MSS into supply, clean leg down.', [8, 11, 30]],
    ['ES','Short', -120, C('poi','sess'), 'Early, no real trigger.', [8, 14, 40]],
    // Jun 10 — revenge → red
    ['NQ','Long', -200, C('fvg','ob','htf','sweep'), 'Right setup, entered late and got wicked out.', [10, 10, 10]],
    ['NQ','Short', -260, C('vwap','bos','htf'), 'Revenge after the ES win. Sloppy.', [10, 13, 20]],
    ['ES','Long', 210, C('htf','sess'), '', [10, 15, 10]],
    // Jun 11 — best day
    ['NQ','Long', 712, C('fvg','ob','htf','sweep','mss'), 'Best of the week. Patient entry on the retest.', [11, 9, 45]],
    ['ES','Long', 255, C('ob','htf','sess'), 'Prev-day high reclaim, slow but clean.', [11, 11, 0]],
    ['NQ','Long', 120, C('fvg'), 'Got lucky. One confluence is not a setup.', [11, 14, 0]],
    // Jun 15
    ['NQ','Long', 305, C('fvg','htf','poi'), '', [15, 9, 55]],
    ['ES','Long', 165, C('fvg','sess'), '', [15, 12, 30]],
    ['NQ','Short', 540, C('sweep','mss','htf','ob'), 'Afternoon distribution, textbook.', [15, 14, 30]],
    // Jun 17
    ['NQ','Long', 455, C('fvg','ob','htf','sweep'), 'The open playbook again. It just works.', [17, 9, 40]],
    ['NQ','Short', -230, C('fvg','ob','htf','sweep','mss'), 'A-grade chart, but news spiked against me.', [17, 11, 10]],
    ['ES','Short', 132, C('ob','bos','htf'), 'Small but disciplined.', [17, 15, 20]],
    // Jun 18 — today
    ['NQ','Long', 478, C('fvg','ob','htf','sweep'), 'Repeat of the open setup. Trailed to PDH.', [18, 9, 50]],
    ['NQ','Long', -180, C('sweep','mss','htf','ob'), 'Good read, terrible entry. Chased it.', [18, 13, 30]],
    ['NQ','Short', -130, C('vwap','bos'), 'Late entry, chased.', [18, 15, 0]],
  ];
  return raw.map((r, i) => ({
    id: 't' + (i + 1),
    instrument: r[0],
    direction: r[1],
    pnl: r[2],
    conf: r[3],
    note: r[4],
    ts: new Date(2026, 5, r[5][0], r[5][1], r[5][2]).getTime(),
  })).sort((a, b) => b.ts - a.ts); // newest first
}

// ---------- stats ----------
// nameOf resolves against the *active* confluence list (incl. user-added ones),
// kept in sync by the app via setActiveConfluences. Falls back to defaults, then id.
let ACTIVE_CONFLUENCES = CONFLUENCES;
const setActiveConfluences = (list) => { ACTIVE_CONFLUENCES = Array.isArray(list) && list.length ? list : CONFLUENCES; };
const nameOf = (id) => {
  const f = ACTIVE_CONFLUENCES.find((c) => c.id === id) || CONFLUENCES.find((c) => c.id === id);
  return f ? f.name : id;
};

function disciplineScore(trades, threshold) {
  if (!trades.length) return null;
  const ok = trades.filter((t) => t.conf.length >= threshold).length;
  return Math.round((ok / trades.length) * 100);
}

function winRateByCount(trades) {
  const buckets = { 1: [], 2: [], 3: [], '4+': [] };
  trades.forEach((t) => {
    const n = t.conf.length;
    const key = n >= 4 ? '4+' : String(Math.max(1, n));
    (buckets[key] || (buckets[key] = [])).push(t);
  });
  return ['1', '2', '3', '4+'].map((k) => {
    const arr = buckets[k] || [];
    const wins = arr.filter((t) => t.pnl > 0).length;
    return { label: k, trades: arr.length, winRate: arr.length ? Math.round((wins / arr.length) * 100) : 0 };
  });
}

function bestCombinations(trades, minSample = 3) {
  const map = new Map();
  trades.forEach((t) => {
    if (t.conf.length < 2) return;
    const key = [...t.conf].sort().join('|');
    if (!map.has(key)) map.set(key, []);
    map.get(key).push(t);
  });
  const rows = [];
  map.forEach((arr, key) => {
    if (arr.length < minSample) return;
    const wins = arr.filter((t) => t.pnl > 0).length;
    rows.push({
      ids: key.split('|'),
      label: key.split('|').map(nameOf).join(' + '),
      trades: arr.length,
      winRate: Math.round((wins / arr.length) * 100),
    });
  });
  rows.sort((a, b) => b.winRate - a.winRate || b.trades - a.trades);
  return rows.slice(0, 3);
}

function confluenceFrequency(trades, confluences) {
  const total = trades.length || 1;
  const counts = {};
  trades.forEach((t) => t.conf.forEach((id) => (counts[id] = (counts[id] || 0) + 1)));
  return confluences
    .map((c) => ({ id: c.id, name: c.name, uses: counts[c.id] || 0, share: Math.round(((counts[c.id] || 0) / total) * 100) }))
    .sort((a, b) => b.uses - a.uses);
}

function equityCurve(trades, threshold) {
  const chrono = [...trades].sort((a, b) => a.ts - b.ts);
  let eq = 0;
  return chrono.map((t, i) => {
    eq += t.pnl;
    return { i: i + 1, equity: eq, pnl: t.pnl, disciplined: t.conf.length >= threshold, ts: t.ts };
  });
}

function summary(trades, threshold) {
  const wins = trades.filter((t) => t.pnl > 0).length;
  const net = trades.reduce((s, t) => s + t.pnl, 0);
  const gross = trades.filter((t) => t.pnl > 0).reduce((s, t) => s + t.pnl, 0);
  const loss = Math.abs(trades.filter((t) => t.pnl < 0).reduce((s, t) => s + t.pnl, 0));
  return {
    count: trades.length,
    net,
    winRate: trades.length ? Math.round((wins / trades.length) * 100) : 0,
    profitFactor: loss ? +(gross / loss).toFixed(2) : gross ? Infinity : 0,
    avg: trades.length ? Math.round(net / trades.length) : 0,
    discipline: disciplineScore(trades, threshold),
  };
}

window.CJData = {
  CONFLUENCES, SESSIONS, USER, seedTrades, nameOf, setActiveConfluences,
  NOW: new Date(2026, 5, 18, 16, 30).getTime(),
  disciplineScore, winRateByCount, bestCombinations,
  confluenceFrequency, equityCurve, summary,
};
