/**
 * Subtitle menu and track management.
 * Handles sidecar, embedded, and user-chosen subtitle files.
 */
import { api } from './api';
import { library, cb } from './store';

// ---- DOM refs ----
let player: HTMLVideoElement;
let subsBtn: HTMLElement;
let subsMenu: HTMLElement;
let subtitleTrackEl: HTMLTrackElement | null = null;
let subsMenuOpen = false;

export function initSubtitles(): void {
  player = document.getElementById('player') as HTMLVideoElement;
  subsBtn = document.getElementById('subsBtn')!;
  subsMenu = document.getElementById('subsMenu')!;

  subsBtn.setAttribute('aria-haspopup', 'true');
  subsBtn.setAttribute('aria-expanded', 'false');

  subsBtn.addEventListener('click', async (e) => {
    e.stopPropagation();
    if (!library) return;
    if (subsMenuOpen) closeSubsMenu();
    else await openSubsMenu();
  });

  subsBtn.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && subsMenuOpen) {
      closeSubsMenu();
      subsBtn.focus();
    }
  });

  window.addEventListener('click', () => { if (subsMenuOpen) closeSubsMenu(); });
  subsMenu.addEventListener('click', (e) => e.stopPropagation());
}

export function ensureSubtitleTrack(): HTMLTrackElement {
  if (!subtitleTrackEl) {
    subtitleTrackEl = document.createElement('track');
    subtitleTrackEl.kind = 'subtitles';
    subtitleTrackEl.label = 'Subtitles';
    subtitleTrackEl.srclang = 'en';
    subtitleTrackEl.default = true;
    player.appendChild(subtitleTrackEl);
  }
  return subtitleTrackEl;
}

export async function refreshSubtitles(): Promise<void> {
  ensureSubtitleTrack();
  try {
    const res = await api.getCurrentSubtitle();
    if (res && res.ok && res.has) {
      subtitleTrackEl!.src = res.url!;
      subtitleTrackEl!.label = res.label || 'Subtitles';
      setTimeout(() => {
        try {
          if (player.textTracks && player.textTracks.length > 0) {
            for (const tt of Array.from(player.textTracks)) {
              if (tt.kind === 'subtitles') tt.mode = 'showing';
            }
          }
        } catch (_) {}
      }, 50);
      cb.notify?.('Subtitles loaded.');
    } else {
      subtitleTrackEl!.src = '';
    }
  } catch (_) {}
}

export function applySubtitle(url: string, label: string): void {
  ensureSubtitleTrack();
  subtitleTrackEl!.src = url;
  subtitleTrackEl!.label = label || 'Subtitles';
  setTimeout(() => {
    try {
      if (player.textTracks && player.textTracks.length > 0) {
        for (const tt of Array.from(player.textTracks)) {
          if (tt.kind === 'subtitles') tt.mode = 'showing';
        }
      }
    } catch (_) {}
  }, 50);
}

export function clearSubtitles(): void {
  try {
    if (player.textTracks && player.textTracks.length > 0) {
      for (const tt of Array.from(player.textTracks)) {
        tt.mode = 'hidden';
      }
    }
    if (subtitleTrackEl) subtitleTrackEl.src = '';
  } catch (_) {}
}

export function closeSubsMenu(): void {
  subsMenuOpen = false;
  subsMenu?.classList.remove('show');
  subsBtn?.setAttribute('aria-expanded', 'false');
}

function menuItemKeyHandler(e: KeyboardEvent): void {
  const item = e.currentTarget as HTMLElement;
  if (e.key === 'ArrowDown') {
    e.preventDefault(); e.stopPropagation();
    let next = item.nextElementSibling as HTMLElement | null;
    while (next && !next.classList.contains('subsMenuItem')) next = next.nextElementSibling as HTMLElement | null;
    if (next) next.focus();
  } else if (e.key === 'ArrowUp') {
    e.preventDefault(); e.stopPropagation();
    let prev = item.previousElementSibling as HTMLElement | null;
    while (prev && !prev.classList.contains('subsMenuItem')) prev = prev.previousElementSibling as HTMLElement | null;
    if (prev) prev.focus();
  } else if (e.key === 'Escape' || e.key === 'Tab') {
    e.preventDefault(); e.stopPropagation();
    closeSubsMenu();
    subsBtn.focus();
  } else if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault(); e.stopPropagation();
    item.click();
  }
}

export async function openSubsMenu(): Promise<void> {
  if (!library) return;
  subsMenu.innerHTML = '';

  try {
    const available = await api.getAvailableSubtitles();
    if (available && available.ok) {
      // Sidecar subtitle files
      if (available.sidecar && available.sidecar.length > 0) {
        const header = document.createElement('div');
        header.className = 'subsMenuHeader';
        header.textContent = 'External Files';
        subsMenu.appendChild(header);

        for (const sub of available.sidecar) {
          const item = document.createElement('div');
          item.className = 'subsMenuItem';
          item.setAttribute('role', 'menuitem');
          item.tabIndex = -1;
          item.addEventListener('keydown', menuItemKeyHandler);
          item.innerHTML = `<i class="fa-solid fa-file-lines" aria-hidden="true"></i> ${sub.label} <span style="opacity:.5;font-size:10px;margin-left:auto;">${sub.format}</span>`;
          item.onclick = async () => {
            closeSubsMenu();
            const res = await api.loadSidecarSubtitle(sub.path);
            if (res && res.ok && res.url) {
              applySubtitle(res.url, res.label!);
              cb.notify?.('Subtitles loaded.');
            } else {
              cb.notify?.(res?.error || 'Failed to load subtitle');
            }
          };
          subsMenu.appendChild(item);
        }
      }

      // Embedded subtitle tracks
      if (available.embedded && available.embedded.length > 0) {
        if (available.sidecar && available.sidecar.length > 0) {
          const div = document.createElement('div');
          div.className = 'subsDivider';
          subsMenu.appendChild(div);
        }

        const header = document.createElement('div');
        header.className = 'subsMenuHeader';
        header.textContent = 'Embedded Tracks';
        subsMenu.appendChild(header);

        for (const track of available.embedded) {
          const item = document.createElement('div');
          item.className = 'subsMenuItem embedded';
          item.setAttribute('role', 'menuitem');
          item.tabIndex = -1;
          item.addEventListener('keydown', menuItemKeyHandler);
          item.innerHTML = `<i class="fa-solid fa-film" aria-hidden="true"></i> ${track.label} <span style="opacity:.5;font-size:10px;margin-left:auto;">${track.codec}</span>`;
          item.onclick = async () => {
            closeSubsMenu();
            const res = await api.extractEmbeddedSubtitle(track.index);
            if (res && res.ok && res.url) {
              applySubtitle(res.url, res.label!);
              cb.notify?.('Embedded subtitle loaded.');
            } else {
              cb.notify?.(res?.error || 'Failed to extract subtitle');
            }
          };
          subsMenu.appendChild(item);
        }
      }

      // Divider
      if ((available.sidecar && available.sidecar.length > 0) || (available.embedded && available.embedded.length > 0)) {
        const div = document.createElement('div');
        div.className = 'subsDivider';
        subsMenu.appendChild(div);
      }
    }
  } catch (_) {}

  // "Load from file" option
  const loadItem = document.createElement('div');
  loadItem.className = 'subsMenuItem';
  loadItem.setAttribute('role', 'menuitem');
  loadItem.tabIndex = -1;
  loadItem.addEventListener('keydown', menuItemKeyHandler);
  loadItem.innerHTML = '<i class="fa-solid fa-file-import" aria-hidden="true"></i> Load from file...';
  loadItem.onclick = async () => {
    closeSubsMenu();
    try {
      const res = await api.chooseSubtitleFile();
      if (res && res.ok && res.url) {
        applySubtitle(res.url, res.label!);
        cb.notify?.('Subtitles loaded.');
      } else if (res && res.error) {
        cb.notify?.(res.error);
      }
    } catch (_) {}
  };
  subsMenu.appendChild(loadItem);

  // "Disable" option
  const disableItem = document.createElement('div');
  disableItem.className = 'subsMenuItem';
  disableItem.setAttribute('role', 'menuitem');
  disableItem.tabIndex = -1;
  disableItem.addEventListener('keydown', menuItemKeyHandler);
  disableItem.innerHTML = '<i class="fa-solid fa-xmark" aria-hidden="true"></i> Disable subtitles';
  disableItem.onclick = () => {
    closeSubsMenu();
    try {
      if (player.textTracks) {
        for (const tt of Array.from(player.textTracks)) {
          tt.mode = 'hidden';
        }
      }
      cb.notify?.('Subtitles disabled.');
    } catch (_) {}
  };
  subsMenu.appendChild(disableItem);

  subsMenu.classList.add('show');
  subsMenuOpen = true;
  subsBtn.setAttribute('aria-expanded', 'true');
  const first = subsMenu.querySelector('.subsMenuItem') as HTMLElement | null;
  if (first) first.focus();
}
