const fs = require('fs');
const path = require('path');
const { marked } = require('marked');
const { markedHighlight } = require('marked-highlight');
const hljs = require('highlight.js');

marked.use(markedHighlight({
  langPrefix: 'hljs language-',
  highlight(code, lang) {
    const language = hljs.getLanguage(lang) ? lang : 'plaintext';
    return hljs.highlight(code, { language }).value;
  },
}));

// ─────────────────────────────────────────────────────────────────────────────
// CSS  —  inspiré de https://github.com/PavelLaptev/markdown-theme-shell
// ─────────────────────────────────────────────────────────────────────────────

const STYLES = `
  /* ── Reset ── */
  *, *::before, *::after { box-sizing: border-box; }
  ::selection { background: #ffc3c3; }
  html, body { height: 100%; margin: 0; }
  body {
    font-family: 'Poppins', sans-serif;
    background: #fff;
    color: #222;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }

  /* ── Sidebar ── */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 264px;
    height: 100vh;
    background: #1a1b2e;
    display: flex;
    flex-direction: column;
    z-index: 99;
    overflow: hidden;
  }
  .sidebar__title-block {
    margin: 48px 24px 8px;
    flex-shrink: 0;
  }
  .sidebar__title-block a {
    text-decoration: none;
  }
  .sidebar__title-block__title {
    color: #fff;
    font-size: 26px;
    font-weight: 700;
    margin: 0 0 4px;
    line-height: 1.25;
    pointer-events: none;
  }
  .sidebar__title-block__version {
    color: rgba(255,255,255,0.3);
    font-size: 14px;
    font-weight: 700;
    display: block;
    margin-bottom: 24px;
  }

  /* ── Sidebar menu ── */
  .sidebar__menu {
    list-style: none;
    margin: 0;
    padding: 8px 0 48px 0;
    flex: 1;
    overflow-y: auto;
  }
  .sidebar__menu::-webkit-scrollbar { width: 0; }

  /* First-level = section group label (non-clickable) */
  .sidebar__menu__group-label {
    display: block;
    padding: 16px 24px 6px;
    color: rgba(255,255,255,0.35);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  /* First-level links (root files or group header links) */
  .sidebar__menu__first-level-title { margin: 0; }
  .sidebar__menu__first-level-title__link {
    display: block;
    padding: 7px 24px;
    color: rgba(255,255,255,0.85);
    text-decoration: none;
    font-size: 16px;
    font-weight: 400;
    line-height: 1.4;
    transition: color 0.2s;
  }
  .sidebar__menu__first-level-title__link:hover { color: #ff5577; }
  .sidebar__menu__first-level-title__link.active {
    color: #ff5577;
    font-weight: 500;
  }

  /* Second-level links (files inside a group) */
  .sidebar__menu__second-level { list-style: none; padding: 0; margin: 0; }
  .sidebar__menu__second-level-title { margin: 0; }
  .sidebar__menu__second-level-title__link {
    display: block;
    padding: 5px 24px 5px 36px;
    color: rgba(255,255,255,0.55);
    text-decoration: none;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
    transition: color 0.2s;
  }
  .sidebar__menu__second-level-title__link:hover { color: #ff5577; }
  .sidebar__menu__second-level-title__link.active {
    color: #ff5577;
    opacity: 1;
  }

  /* ── Content ── */
  .content {
    margin-left: 264px;
    padding: 48px 72px 96px;
    max-width: 1080px;
    min-height: 100vh;
    background: #fff;
  }

  /* ── Typography ── */
  .content a { color: #0000ee; text-decoration: none; transition: color 0.16s; }
  .content a:hover { color: #ff5577; }
  .content a:visited { color: #551a8b; }
  .content a:visited:hover { color: #ff5577; }

  .content h1, .content h2, .content h3,
  .content h4, .content h5, .content h6 {
    color: #222;
    margin-top: 48px;
    margin-bottom: 12px;
    line-height: 1.3;
  }
  .content h1 { font-size: 2em; margin-top: 0; }
  .content h2 { font-size: 1.5em; }
  .content h3 { font-size: 1.25em; }

  .content hr { margin: 72px 0; border: none; border-top: 1px solid rgba(34,34,34,0.15); }

  .content p { color: #222; font-size: 1em; line-height: 1.64em; margin: 0 0 1em; }

  .content code {
    font-family: 'Roboto Mono', 'SFMono-Regular', Consolas, monospace;
    font-size: 85%;
    font-weight: 700;
    background: #f4f4f7;
    padding: 0.15em 0.4em;
    border-radius: 4px;
    line-height: 1.4;
  }
  .content pre { background: #f4f4f7; padding: 20px 24px; border-radius: 6px; overflow-x: auto; margin: 16px 0; }
  .content pre code { background: none; padding: 0; font-weight: 400; font-size: 13px; }

  .content blockquote {
    border-left: 3px solid rgba(34,34,34,0.25);
    margin: 24px 0;
    padding: 4px 24px;
    color: rgba(34,34,34,0.65);
  }

  .content img { max-width: 100%; margin: 8px 0; }

  .content table {
    width: 100%;
    border-spacing: 0;
    border-collapse: collapse;
    margin: 24px 0 48px;
    font-size: 14px;
    color: #222;
  }
  .content table th {
    border-bottom: 1px solid #ff5577;
    padding: 10px;
    text-align: left;
    font-weight: 600;
  }
  .content table td {
    border-bottom: 1px solid rgba(255,85,119,0.25);
    padding: 10px;
  }

  .content ul li, .content ol li {
    color: #222;
    font-size: 1em;
    line-height: 1.64em;
    margin-bottom: 8px;
  }
  .content ul li code, .content ol li code { font-weight: 700; }

  /* ── Responsive ── */
  @media screen and (max-width: 1020px) {
    .sidebar {
      left: -300px;
      transition: left 0.2s cubic-bezier(0.09, 0.46, 0.45, 0.94);
    }
    .content { margin-left: 0; padding: 32px 24px 64px; }
  }
  @media screen and (max-width: 540px) {
    .content { padding: 24px 16px 48px; }
  }`;

const SSE_SCRIPT = `
  <script>
    const es = new EventSource('/events');
    es.onmessage = () => location.reload();
    es.onerror = () => { es.close(); console.warn('Live reload disconnected'); };
  </script>`;

// ─────────────────────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────────────────────

function escapeHtml(str) {
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

/** Build the sidebar HTML from the list of all pages (Shell theme structure). */
function buildSidebar(baseDir, files, currentFile) {
  const currentRel = currentFile ? path.relative(baseDir, currentFile) : null;

  // Group by first-level subdirectory
  const groups = new Map(); // groupName → [rel, ...]
  files.forEach((f) => {
    const rel = path.relative(baseDir, f);
    const parts = rel.split(path.sep);
    const group = parts.length > 1 ? parts[0] : '';
    if (!groups.has(group)) groups.set(group, []);
    groups.get(group).push(rel);
  });

  const dirName = path.basename(baseDir);
  let html = `
  <aside class="sidebar">
    <div class="sidebar__title-block">
      <a href="/"><h1 class="sidebar__title-block__title">${escapeHtml(dirName)}</h1></a>
    </div>
    <ul class="sidebar__menu">`;

  const sortedGroups = [...groups.keys()].sort((a, b) => {
    if (a === '') return -1;
    if (b === '') return 1;
    return a.localeCompare(b);
  });

  sortedGroups.forEach((group) => {
    const pages = groups.get(group).sort();

    if (group !== '') {
      // Group label + second-level links
      html += `\n      <li class="sidebar__menu__first-level-title">
        <span class="sidebar__menu__group-label">${escapeHtml(group)}</span>
        <ul class="sidebar__menu__second-level">`;
      pages.forEach((rel) => {
        const pagePath = rel.replace(/\.md$/i, '');
        const label = path.basename(pagePath).replace(/-/g, ' ');
        const href = '/' + pagePath.split('/').map(encodeURIComponent).join('/');
        const isActive = rel === currentRel;
        const cls = isActive ? 'active' : '';
        html += `\n          <li class="sidebar__menu__second-level-title">
            <a href="${href}" class="sidebar__menu__second-level-title__link ${cls}">${escapeHtml(label)}</a>
          </li>`;
      });
      html += `\n        </ul>
      </li>`;
    } else {
      // Root-level links as first-level items
      pages.forEach((rel) => {
        const pagePath = rel.replace(/\.md$/i, '');
        const label = path.basename(pagePath).replace(/-/g, ' ');
        const href = '/' + pagePath.split('/').map(encodeURIComponent).join('/');
        const isActive = rel === currentRel;
        const cls = isActive ? 'active' : '';
        html += `\n      <li class="sidebar__menu__first-level-title">
        <a href="${href}" class="sidebar__menu__first-level-title__link ${cls}">${escapeHtml(label)}</a>
      </li>`;
      });
    }
  });

  html += `\n    </ul>
  </aside>`;
  return html;
}

// ─────────────────────────────────────────────────────────────────────────────
// Shell
// ─────────────────────────────────────────────────────────────────────────────

function htmlShell({ title, sidebar, body, watchMode }) {
  const hasSidebar = !!sidebar;
  const noSidebarStyle = hasSidebar ? '' : `
  <style>
    body { max-width: 860px; margin: 48px auto; padding: 0 32px; }
    .content { margin-left: 0; padding: 0; }
  </style>`;
  return `<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${escapeHtml(title)}</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Roboto+Mono&display=swap">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
  <style>${STYLES}</style>${noSidebarStyle}
</head>
<body>
${hasSidebar ? sidebar : ''}
<div class="content">
${body}
</div>${watchMode ? SSE_SCRIPT : ''}
</body>
</html>`;
}

// ─────────────────────────────────────────────────────────────────────────────
// Public API
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Convert a single .md file to a full HTML page.
 * @param {string} inputFile  Absolute path to the .md file
 * @param {boolean} watchMode Inject SSE live-reload script
 * @param {{ baseDir: string, files: string[] }} [nav] When set, render with sidebar
 */
function convert(inputFile, watchMode = false, nav = null) {
  const content = fs.readFileSync(inputFile, 'utf-8');
  const body = marked.parse(content);
  const title = path.basename(inputFile, '.md');
  const sidebar = nav ? buildSidebar(nav.baseDir, nav.files, inputFile) : null;
  return htmlShell({ title, sidebar, body, watchMode });
}

/**
 * Build an index/home page listing all .md files.
 * Only used when no Home.md exists.
 */
function buildIndex(baseDir, files, watchMode = false) {
  const dirName = path.basename(baseDir);
  const sidebar = buildSidebar(baseDir, files, null);

  const groups = new Map();
  files.forEach((f) => {
    const rel = path.relative(baseDir, f);
    const parts = rel.split(path.sep);
    const group = parts.length > 1 ? parts[0] : '';
    if (!groups.has(group)) groups.set(group, []);
    groups.get(group).push(rel);
  });

  const listHtml = [...groups.keys()].sort().map((group) => {
    const items = groups.get(group).sort().map((rel) => {
      const pagePath = rel.replace(/\.md$/i, '');
      const label = path.basename(pagePath).replace(/-/g, ' ');
      const href = '/' + pagePath.split('/').map(encodeURIComponent).join('/');
      return `    <li><a href="${href}">${escapeHtml(label)}</a></li>`;
    }).join('\n');
    if (group === '') return `<ul>\n${items}\n</ul>`;
    return `<h3>${escapeHtml(group)}</h3>\n<ul>\n${items}\n</ul>`;
  }).join('\n');

  const body = `<h1>📂 ${escapeHtml(dirName)}</h1>
<p>${files.length} fichier${files.length > 1 ? 's' : ''} Markdown</p>
${listHtml}`;

  return htmlShell({ title: dirName, sidebar, body, watchMode });
}

module.exports = { convert, buildIndex };

