import { Storage } from './storage.js';
import { LEVELS, DIFFICULTY } from './levels.js';
import { paletteOf } from './palettes.js';

export function $(id) {
  return document.getElementById(id);
}

export function applyTheme(palId) {
  const p = paletteOf(palId);
  const r = document.documentElement.style;
  r.setProperty('--bg', p.bg);
  r.setProperty('--accent', p.accent);
  r.setProperty('--mint', p.flooz);
  r.setProperty('--gold', p.gold);
  r.setProperty('--danger', p.danger);
  document.body.style.background = p.bg;
}

export function showScreen(name) {
  document.querySelectorAll('.screen').forEach((el) => {
    const on = el.dataset.screen === name;
    el.hidden = !on;
    el.classList.toggle('active', on);
  });
}

export function bindSettingsForm() {
  const s = Storage.settings();
  $('set-name').value = Storage.player();
  $('set-diff').value = s.difficulty;
  $('set-palette').value = s.palette;
  $('set-master').value = Math.round(s.master * 100);
  $('set-music').value = Math.round(s.music * 100);
  $('set-sfx').value = Math.round(s.sfx * 100);
  $('set-rotate').checked = !!s.rotatePieces;
  $('set-ghost').checked = !!s.ghostPath;
  $('set-undo').checked = !!s.undo;
  $('set-shake').checked = !!s.shake;
  $('set-particles').checked = !!s.particles;
  $('set-motion').checked = !!s.reducedMotion;
  paintVolLabels();
}

export function readSettingsForm() {
  Storage.setPlayer($('set-name').value);
  Storage.setSettings({
    difficulty: $('set-diff').value,
    palette: $('set-palette').value,
    master: Number($('set-master').value) / 100,
    music: Number($('set-music').value) / 100,
    sfx: Number($('set-sfx').value) / 100,
    rotatePieces: $('set-rotate').checked,
    ghostPath: $('set-ghost').checked,
    undo: $('set-undo').checked,
    shake: $('set-shake').checked,
    particles: $('set-particles').checked,
    reducedMotion: $('set-motion').checked,
  });
  applyTheme(Storage.settings().palette);
  paintVolLabels();
  return Storage.settings();
}

function paintVolLabels() {
  $('lbl-master').textContent = `${$('set-master').value}%`;
  $('lbl-music').textContent = `${$('set-music').value}%`;
  $('lbl-sfx').textContent = `${$('set-sfx').value}%`;
}

export function renderScores() {
  const rows = Storage.top(12);
  const body = $('score-body');
  body.innerHTML = '';
  $('score-empty').hidden = rows.length > 0;
  rows.forEach((r, i) => {
    const tr = document.createElement('tr');
    const diff = (DIFFICULTY[r.difficulty] || DIFFICULTY.normal).label;
    tr.innerHTML = `<td>${i + 1}</td><td>${esc(r.name)}</td><td>${r.score.toLocaleString()}</td><td>${esc(r.mode)}${r.mode === 'campaign' ? ' L' + r.level : ''}</td><td>${esc(diff)}</td>`;
    body.appendChild(tr);
  });
}

function esc(s) {
  return String(s).replace(/[&<>"']/g, (c) => ({
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
  })[c]);
}

export function showLevelIntro(game) {
  const L = game.level;
  const n = game.mode === 'endless' ? '∞' : String(L.id).padStart(2, '0');
  $('level-kicker').textContent = game.mode === 'endless' ? 'ENDLESS' : `SECTOR ${n}`;
  $('level-name').textContent = L.name;
  $('level-blurb').textContent = L.blurb;
  $('level-meta').innerHTML = [
    ['Grid', `${L.cols}×${L.rows}`],
    ['Valve', `${L.delay.toFixed(0)}s`],
    ['Contract', `${L.minDist} lengths`],
    ['Flow', L.end ? 'Must hit drain' : 'Open leak after contract'],
    ['Wrap', L.wrap ? 'Edges loop' : 'Hard walls'],
    ['Diff', (DIFFICULTY[game.settings.difficulty] || DIFFICULTY.normal).label],
  ]
    .map(([k, v]) => `<div><em>${k}</em><b>${v}</b></div>`)
    .join('');
  showScreen('level');
}

export function updateHud(game) {
  const L = game.level;
  if (!L) return;
  const campaign = game.mode === 'campaign';
  $('hud-level').textContent = campaign ? `S${String(L.id).padStart(2, '0')}` : 'ENDLESS';
  $('hud-score').textContent = Math.round(
    (campaign ? game.campaignScore + game.levelScore : game.levelScore)
  ).toLocaleString();
  $('hud-dist').textContent =
    game.mode === 'endless' ? `${game.distance}` : `${game.distance}/${game.minDist}`;
  $('side-name').textContent = L.name;
  $('side-blurb').textContent = L.blurb;
  const needEnd = L.end ? 'Reach the drain. ' : '';
  $('side-obj').textContent = `${needEnd}Carry flooz at least ${game.minDist} cells.`;
  $('side-combo').textContent = String(game.combo);
  $('side-rep').textContent = String(game.replaces);
  $('side-lives').textContent = String(game.lives);

  const fill = $('meter-fill');
  const mark = $('meter-mark');
  const title = $('meter-title');
  const read = $('meter-readout');
  if (game.phase === 'countdown') {
    title.textContent = 'VALVE';
    read.textContent = `${Math.max(0, game.countdown).toFixed(1)}s`;
    const pct = (1 - game.countdown / Math.max(0.01, game.delayMax)) * 100;
    fill.style.width = `${Math.min(100, Math.max(0, pct))}%`;
    fill.style.background = 'linear-gradient(90deg, #3ee0ff, #ffc14a)';
    mark.style.display = 'none';
  } else {
    title.textContent = 'CONTRACT';
    const pct = Math.min(1, game.distance / Math.max(1, game.minDist));
    read.textContent =
      game.mode === 'endless'
        ? `${game.distance} · spd ${(1 + game.endlessRamp * 0.08).toFixed(2)}x`
        : `${game.distance} / ${game.minDist}`;
    fill.style.width = `${pct * 100}%`;
    fill.style.background =
      pct >= 1
        ? 'linear-gradient(90deg, #5cffd4, #ffc14a)'
        : 'linear-gradient(90deg, #3ee0ff, #5cffd4)';
    mark.style.display = 'block';
    mark.style.left = '100%';
  }

  const tip = $('play-tip');
  if (tip) {
    if (game.phase === 'countdown' && game.level?.tutorial) {
      tip.hidden = false;
      tip.textContent = `Place fittings ahead of the flooz. Valve opens in ${Math.max(0, game.countdown).toFixed(0)}s · R rotates · click a cell.`;
    } else if (game.phase === 'flowing' && game.distance < 2) {
      tip.hidden = false;
      tip.textContent = 'Keep laying pipe ahead of the glow. Space fast-forwards.';
    } else {
      tip.hidden = true;
    }
  }
  $('btn-valve').disabled = game.phase !== 'countdown';
  $('btn-valve').textContent =
    game.phase === 'countdown' ? 'Release Valve' : game.phase === 'flowing' ? 'Flowing…' : '—';
  $('btn-fast').textContent = game.fast ? 'Slow down' : 'Fast-forward';
}

export function showResult(game) {
  const ov = $('overlay-result');
  ov.hidden = false;
  const ok = game.result?.ok;
  $('res-kicker').textContent = ok
    ? game.result.last
      ? 'PLANT SECURE'
      : 'SECTOR CLEAR'
    : 'PRESSURE LOSS';
  $('res-title').textContent = ok
    ? game.result.last
      ? 'Every valve held'
      : game.level.name
    : 'Leak detected';
  $('res-sub').textContent = ok
    ? 'Flooz contained. The night shift salutes you.'
    : game.result?.reason || 'The floor is a lake.';
  const medal = game.result?.medal;
  $('res-medal').textContent = ok
    ? medal === 'gold'
      ? 'GOLD RUN'
      : medal === 'silver'
        ? 'SILVER RUN'
        : medal === 'bronze'
          ? 'BRONZE RUN'
          : 'CLEARED'
    : '';
  $('res-stats').innerHTML = [
    ['Sector score', (game.levelScore | 0).toLocaleString()],
    ['Campaign', (game.campaignScore | 0).toLocaleString()],
    ['Distance', String(game.distance)],
    ['Replaces', String(game.replaces)],
  ]
    .map(([k, v]) => `<div><em>${k}</em><br><b>${v}</b></div>`)
    .join('');
  $('res-name').value = Storage.player();
  $('btn-next').hidden = !ok || game.mode !== 'campaign' || !!game.result.last;
  $('btn-next').textContent = game.result?.last ? 'Credits' : 'Next sector';
}

export function hideResult() {
  $('overlay-result').hidden = true;
}

export function showPause(on) {
  $('overlay-pause').hidden = !on;
}

export function levelsBeatenLabel() {
  return `${Storage.unlocked()} / ${LEVELS.length}`;
}
