#!/usr/bin/env node
'use strict';

const path = require('path');
const fs = require('fs');
const minimist = require('minimist');
const { convert, buildIndex } = require('./lib/converter');
const { startServer } = require('./lib/server');
const { startWatcher } = require('./lib/watcher');

const argv = minimist(process.argv.slice(2), {
  alias: { o: 'output', p: 'port', w: 'watch', v: 'preview', h: 'help' },
  default: { port: 3000 },
  boolean: ['watch', 'preview', 'open', 'help'],
});

if (argv.help) {
  console.log(`
Usage: md-render <fichier.md|dossier> [options]

Options:
  -w, --watch          Surveille les modifications et recharge automatiquement
  -v, --preview        Comme --watch, mais ouvre aussi le navigateur
      --open           Ouvre le navigateur (combinable avec --watch)
  -p, --port <port>    Port du serveur (défaut: 3000)
  -o, --output <dir>   Dossier de sortie HTML (mode dossier, sans --watch)
  -h, --help           Affiche cette aide

Exemples:
  md-render README.md                    Convertit README.md → README.html
  md-render README.md --watch            Live reload sur localhost:3000
  md-render README.md --watch --open     Live reload + ouvre le navigateur
  md-render README.md --preview          Alias de --watch --open
  md-render ../my-portal.wiki/           Convertit tous les .md du dossier
  md-render ../my-portal.wiki/ --watch   Wiki live sur localhost:3000
`);
  process.exit(0);
}

const input = argv._[0];

if (!input) {
  console.error('\n✗ Erreur : veuillez fournir un fichier ou un dossier en argument.');
  console.error('  Aide : md-render --help\n');
  process.exit(1);
}

const absInput = path.resolve(input);

if (!fs.existsSync(absInput)) {
  console.error(`\n✗ Erreur : introuvable : ${absInput}\n`);
  process.exit(1);
}

const stat = fs.statSync(absInput);
const isDir = stat.isDirectory();

// ── SERVER MODE (--watch ou --preview) ──────────────────────────────────────
if (argv.watch || argv.preview) {
  const port = parseInt(argv.port, 10);
  if (isNaN(port) || port < 1 || port > 65535) {
    console.error(`\n✗ Erreur : port invalide "${argv.port}".\n`);
    process.exit(1);
  }

  const shouldOpen = argv.preview || argv.open;

  function openBrowser(url) {
    const { exec } = require('child_process');
    const cmd =
      process.platform === 'darwin' ? `open "${url}"` :
      process.platform === 'win32'  ? `start "" "${url}"` :
                                      `xdg-open "${url}"`;
    exec(cmd, (err) => {
      if (err) console.warn(`  ⚠  Impossible d'ouvrir le navigateur : ${err.message}`);
    });
  }

  const serverObj = startServer({
    inputFile: isDir ? null : absInput,
    inputDir: isDir ? absInput : null,
    port,
    onReady: shouldOpen ? (p) => {
      console.log('   Appuyez sur Ctrl+C pour arrêter.\n');
      openBrowser(`http://localhost:${p}`);
    } : null,
  });

  startWatcher({
    inputFile: isDir ? null : absInput,
    inputDir: isDir ? absInput : null,
    server: serverObj,
  });

  process.on('SIGINT', () => {
    serverObj.server.close();
    console.log('\n👋  Au revoir !');
    process.exit(0);
  });
  return;
}

// ── ONE-SHOT MODE ────────────────────────────────────────────────────────────
if (isDir) {
  // Convert all .md files in the directory
  const outputDir = argv.output ? path.resolve(argv.output) : absInput;

  const files = findMarkdownFilesSync(absInput);
  if (files.length === 0) {
    console.error(`\n✗ Aucun fichier .md trouvé dans : ${absInput}\n`);
    process.exit(1);
  }

  let ok = 0;
  files.forEach((f) => {
    try {
      const rel = path.relative(absInput, f).replace(/\.md$/i, '.html');
      const outFile = path.join(outputDir, rel);
      fs.mkdirSync(path.dirname(outFile), { recursive: true });
      fs.writeFileSync(outFile, convert(f, false), 'utf-8');
      console.log(`  ✓ ${rel}`);
      ok++;
    } catch (err) {
      console.error(`  ✗ ${path.relative(absInput, f)} — ${err.message}`);
    }
  });
  console.log(`\n${ok}/${files.length} fichier(s) converti(s).`);
} else {
  const outputFile = argv.output
    ? path.resolve(argv.output)
    : absInput.replace(/\.md$/i, '.html');

  try {
    fs.writeFileSync(outputFile, convert(absInput, false), 'utf-8');
    console.log(`✓ Converti : ${outputFile}`);
  } catch (err) {
    console.error(`\n✗ Erreur de conversion : ${err.message}\n`);
    process.exit(1);
  }
}

function findMarkdownFilesSync(dir) {
  const results = [];
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    if (entry.name.startsWith('.')) continue;
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) results.push(...findMarkdownFilesSync(full));
    else if (/\.md$/i.test(entry.name)) results.push(full);
  }
  return results;
}

