import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';

export function openChangelog(context: vscode.ExtensionContext) {
  const panel = vscode.window.createWebviewPanel(
    'hplToolbox.changelog',
    'HPL Toolbox Changelog',
    vscode.ViewColumn.One,
    { enableScripts: false }
  );
  const readmePath = path.join(context.extensionPath, 'README.md');
  let markdown = '# Changelog\n\nREADME.md was not found.';
  try {
    markdown = fs.readFileSync(readmePath, 'utf8');
  } catch {
    // Keep the fallback text readable in packaged or development installs.
  }
  panel.webview.html = getHtml(renderMarkdown(markdown));
}

function getHtml(content: string): string {
  return `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<style>
  * { box-sizing: border-box; }
  body {
    margin: 0;
    padding: 18px;
    font-family: var(--vscode-font-family);
    font-size: var(--vscode-font-size);
    background: var(--vscode-editor-background);
    color: var(--vscode-foreground);
  }
  main {
    max-width: 840px;
    margin: 0 auto;
  }
  h1 {
    margin: 0 0 14px;
    font-size: 20px;
    line-height: 1.25;
  }
  h2 {
    margin: 18px 0 8px;
    padding-top: 12px;
    border-top: 1px solid var(--vscode-panel-border);
    font-size: 15px;
    line-height: 1.3;
  }
  h3 {
    margin: 14px 0 6px;
    font-size: 13px;
    line-height: 1.3;
  }
  strong {
    font-weight: 600;
  }
  ul {
    margin: 6px 0 12px;
    padding-left: 20px;
  }
  li {
    margin: 4px 0;
    line-height: 1.45;
  }
  p {
    margin: 8px 0;
    line-height: 1.5;
  }
  code {
    font-family: var(--vscode-editor-font-family, monospace);
    font-size: 0.95em;
    background: var(--vscode-textCodeBlock-background);
    padding: 1px 4px;
    border-radius: 3px;
  }
  .changelog-block {
    margin: 8px 0 18px;
    padding: 10px 12px;
    border: 1px solid var(--vscode-panel-border);
    border-radius: 4px;
    background: var(--vscode-textCodeBlock-background);
  }
  .change-section {
    margin: 8px 0 4px;
    font-weight: 600;
  }
  .changelog-block ul {
    margin: 4px 0 10px;
  }
  .changelog-block li.nested {
    margin-left: 18px;
  }
</style>
</head>
<body>
  <main>${content}</main>
</body>
</html>`;
}

function renderMarkdown(markdown: string): string {
  const lines = markdown.replace(/\r\n/g, '\n').split('\n');
  const html: string[] = [];
  let inList = false;
  let inCodeBlock = false;
  let codeLines: string[] = [];

  const closeList = () => {
    if (inList) {
      html.push('</ul>');
      inList = false;
    }
  };

  for (const rawLine of lines) {
    if (rawLine.trim() === '```') {
      closeList();
      if (inCodeBlock) {
        html.push(renderChangelogBlock(codeLines));
        codeLines = [];
        inCodeBlock = false;
      } else {
        inCodeBlock = true;
      }
      continue;
    }
    if (inCodeBlock) {
      codeLines.push(rawLine);
      continue;
    }

    const line = rawLine.trim();
    if (!line) {
      closeList();
      continue;
    }
    const heading = line.match(/^(#{1,3})\s+(.+)$/);
    if (heading) {
      closeList();
      const level = Math.min(heading[1].length, 2);
      html.push(`<h${level}>${renderInlineMarkdown(heading[2])}</h${level}>`);
      continue;
    }
    const boldHeading = line.match(/^\*\*(.+)\*\*$/);
    if (boldHeading) {
      closeList();
      html.push(`<h2>${escapeHtml(boldHeading[1])}</h2>`);
      continue;
    }
    const listItem = line.match(/^-\s+(.+)$/);
    if (listItem) {
      if (!inList) {
        html.push('<ul>');
        inList = true;
      }
      html.push(`<li>${renderInlineMarkdown(listItem[1])}</li>`);
      continue;
    }
    closeList();
    html.push(`<p>${renderInlineMarkdown(line)}</p>`);
  }
  if (inCodeBlock) {
    html.push(renderChangelogBlock(codeLines));
  }
  closeList();
  return html.join('\n');
}

function renderChangelogBlock(lines: string[]): string {
  const html: string[] = ['<div class="changelog-block">'];
  let inList = false;

  const closeList = () => {
    if (inList) {
      html.push('</ul>');
      inList = false;
    }
  };

  for (const rawLine of lines) {
    const line = rawLine.trim();
    if (!line) {
      closeList();
      continue;
    }
    const listItem = line.match(/^-\s+(.+)$/);
    if (listItem) {
      if (!inList) {
        html.push('<ul>');
        inList = true;
      }
      const nested = rawLine.match(/^\s{8,}-\s+/) ? ' class="nested"' : '';
      html.push(`<li${nested}>${renderInlineMarkdown(listItem[1])}</li>`);
      continue;
    }
    closeList();
    html.push(`<div class="change-section">${renderInlineMarkdown(line)}</div>`);
  }
  closeList();
  html.push('</div>');
  return html.join('\n');
}

function renderInlineMarkdown(value: string): string {
  return escapeHtml(value)
    .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
    .replace(/`([^`]+)`/g, '<code>$1</code>');
}

function escapeHtml(value: string): string {
  return value.replace(/[&<>"']/g, ch => ({
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
  }[ch] ?? ch));
}
