/* panels/explorer.js — opening explorer: move statistics at the current
   position from the local game databases, with W/D/L bars and the games
   that reached the position. */
'use strict';

import { h, clear, debounce } from '../ui/dom.js';
import { makePanel, emptyState, loadingState } from '../ui/widgets.js';
import { gamedb } from '../svc/gamedb.js';

export function createExplorerPanel({ getFen, onPlaySan, onOpenGame }) {
  let dbFilter = '';           // '' = all databases
  let showGames = false;

  const dbSel = h('select.select', {
    style: { height: '20px', fontSize: '11px', maxWidth: '110px' },
    onchange: () => { dbFilter = dbSel.value; refresh(); },
  }, h('option', { value: '' }, 'All databases'));

  const body = h('div', { style: { display: 'flex', flexDirection: 'column', height: '100%' } });
  const rowsEl = h('div', { style: { flex: 1, overflowY: 'auto' } });
  const gamesEl = h('div', { style: { flex: 'none', maxHeight: '40%', overflowY: 'auto', borderTop: '1px solid var(--border)' } });
  body.append(rowsEl, gamesEl);

  const panel = makePanel({
    id: 'explorer', title: 'Opening explorer', icon: 'bookOpen',
    actions: [{ icon: 'list', title: 'Toggle games list', onClick: () => { showGames = !showGames; refresh(); } }],
    body,
  });
  panel.el.querySelector('.panel-actions').prepend(dbSel);

  async function refreshDbs() {
    const dbs = await gamedb.listDatabases();
    const cur = dbSel.value;
    clear(dbSel);
    dbSel.append(h('option', { value: '' }, 'All databases'));
    for (const db of dbs) dbSel.append(h('option', { value: db.name, selected: db.name === cur }, `${db.name} (${db.count})`));
  }

  let refreshSeq = 0;
  const refresh = debounce(async () => {
    const seq = ++refreshSeq;
    const fen = getFen && getFen();
    if (!fen) return;
    const stats = await gamedb.explorer(fen, dbFilter || null);
    if (seq !== refreshSeq) return;
    clear(rowsEl);
    clear(gamesEl);
    if (!stats.length) {
      rowsEl.append(emptyState({ icon: 'bookOpen', title: 'No games here', hint: 'Import PGN files in Database mode to build your explorer.' }));
      return;
    }
    const total = stats.reduce((a, b) => a + b.count, 0);
    for (const s of stats) {
      const w = s.count ? s.w / s.count * 100 : 0;
      const d = s.count ? s.d / s.count * 100 : 0;
      const l = s.count ? s.l / s.count * 100 : 0;
      rowsEl.append(h('div.xp-row', {
        onclick: () => onPlaySan && onPlaySan(s.san),
        title: `${s.san}: ${s.count} games (${Math.round(s.count / total * 100)}%)` + (s.avgElo ? ` · avg ${s.avgElo}` : '') + (s.recent ? ` · ${s.recent} recent` : ''),
      },
        h('span.xp-move', {}, s.san),
        h('span.xp-count', {}, String(s.count)),
        h('div.xp-bar', {},
          w > 0 ? h('span.w', { style: { width: w + '%' } }, w >= 18 ? Math.round(w) + '%' : '') : null,
          d > 0 ? h('span.d', { style: { width: d + '%' } }, d >= 18 ? Math.round(d) + '%' : '') : null,
          l > 0 ? h('span.b', { style: { width: l + '%' } }, l >= 18 ? Math.round(l) + '%' : '') : null,
        )));
    }
    if (showGames) {
      const games = await gamedb.gamesAtPosition(fen, dbFilter || null, 30);
      if (seq !== refreshSeq) return;
      for (const g of games) {
        gamesEl.append(h('div.list-row', {
          onclick: () => onOpenGame && onOpenGame(g.id),
          title: `${g.event} ${g.date}`,
        },
          h('span.grow', { style: { overflow: 'hidden', textOverflow: 'ellipsis' } }, `${g.white} – ${g.black}`),
          h('span.faint.mono', {}, g.result)));
      }
    }
  }, 150);

  refreshDbs();
  return { panel, refresh, refreshDbs };
}
