import { appState } from './state/app-state.js';
import { listMdFiles } from './services/files.js';
import { startWatch, stopWatch, onFileChanged } from './services/watcher.js';
import { renderSidebar } from './ui/sidebar.js';
import { loadPage } from './ui/reader.js';
import { saveRecent, renderRecents } from './ui/home.js';

const viewHome = document.getElementById('view-home');
const viewReader = document.getElementById('view-reader');
const sidebarEl = document.querySelector('#sidebar');
const content = document.querySelector('#content');
const win = window.__TAURI__.window.getCurrentWindow();
const titlebarTitle = document.getElementById('titlebar-title');

const navigate = filePath => loadPage(filePath, appState.currentMode, sidebarEl);

export function showHome() {
  stopWatch();
  appState.currentPath = null;
  appState.currentMode = null;
  appState.baseDir = null;
  appState.currentFile = null;
  appState.files = [];
  sidebarEl.innerHTML = '';
  win.setTitle('Pena — Markdown Viewer');
  titlebarTitle.textContent = 'Pena — Markdown Viewer';
  viewReader.classList.add('hidden');
  viewHome.classList.remove('hidden');
  renderRecents(openPath);
}

export function showReader() {
  viewHome.classList.add('hidden');
  viewReader.classList.remove('hidden');
}

export async function openPath(path, mode) {
  appState.currentPath = path;
  appState.currentMode = mode;
  saveRecent(path, mode);

  if (mode === 'file') {
    showReader();
    const sep = path.includes('\\') ? '\\' : '/';
    const parentDir = path.split(sep).slice(0, -1).join(sep);
    try {
      const files = await listMdFiles(parentDir);
      appState.baseDir = parentDir;
      appState.files = files;
      sidebarEl.classList.remove('hidden');
      content.style.marginLeft = '';
      renderSidebar(parentDir, files, path, navigate);
    } catch {
      // Le dossier parent est illisible : on surveille au moins le fichier ouvert.
      appState.baseDir = path;
      appState.files = [];
      sidebarEl.innerHTML = '';
      sidebarEl.classList.add('hidden');
      content.style.marginLeft = '0';
    }
    await loadPage(path, appState.currentMode, sidebarEl);
    startWatch(appState.baseDir);
    return;
  }

  // mode === 'dir'
  sidebarEl.classList.remove('hidden');
  content.style.marginLeft = '';

  try {
    const files = await listMdFiles(path);
    appState.baseDir = path;
    appState.files = files;
    showReader();

    const sep = path.includes('\\') ? '\\' : '/';
    const home = files.find(f => {
      const name = f.split(sep).pop();
      return name === 'Home.md' || name === 'home.md';
    });

    const firstFile = home ?? files[0];
    renderSidebar(path, files, firstFile, navigate);
    await loadPage(firstFile, appState.currentMode, sidebarEl);
    startWatch(path);
  } catch (err) {
    showReader();
    content.innerHTML = `<p class="error">Impossible d'ouvrir le dossier : ${err}</p>`;
  }
}

// Compare deux listes de fichiers indépendamment de l'ordre.
function sameFiles(a, b) {
  if (a.length !== b.length) return false;
  const key = arr => arr.slice().sort().join('\n');
  return key(a) === key(b);
}

// Réaction à un changement filesystem signalé par le backend (événement débouncé,
// filtré sur les fichiers .md).
async function handleFileChanged(changedPath) {
  if (!appState.baseDir || !appState.currentMode) return;

  // Rafraîchir la sidebar uniquement si l'arborescence a changé (ajout/suppression),
  // pour ne pas replier les dossiers ouverts à chaque simple modification de contenu.
  try {
    const files = await listMdFiles(appState.baseDir);
    if (!sameFiles(files, appState.files)) {
      appState.files = files;
      renderSidebar(appState.baseDir, files, appState.currentFile, navigate);
    }
  } catch {
    // baseDir supprimé/illisible : on garde la sidebar en l'état.
  }

  // Recharger le document affiché si c'est lui qui vient d'être modifié.
  if (changedPath === appState.currentFile) {
    await loadPage(appState.currentFile, appState.currentMode, sidebarEl);
  }
}

// À appeler une fois au démarrage : enregistre le listener global de changements.
export function initWatcher() {
  return onFileChanged(event => {
    handleFileChanged(event.payload.path);
  });
}
