const http = require("http");
const { markdownToHtml, htmlToPdf } = require("./convert");

const PORT = process.env.PORT || 3000;

const UPLOAD_PAGE = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Markdown Converter</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  background: #f6f8fa;
  color: #24292f;
  display: flex;
  justify-content: center;
  padding: 40px 20px;
  min-height: 100vh;
}
.container { max-width: 800px; width: 100%; }
h1 { font-size: 1.8em; margin-bottom: 8px; }
p.sub { color: #656d76; margin-bottom: 24px; }
.card {
  background: #fff;
  border: 1px solid #d0d7de;
  border-radius: 8px;
  padding: 24px;
  margin-bottom: 16px;
}
label { display: block; font-weight: 600; margin-bottom: 8px; }
textarea {
  width: 100%;
  height: 300px;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.9rem;
  padding: 12px;
  border: 1px solid #d0d7de;
  border-radius: 6px;
  resize: vertical;
}
.actions { display: flex; gap: 12px; margin-top: 16px; flex-wrap: wrap; }
.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.btn-primary { background: #0969da; color: #fff; }
.btn-primary:hover { background: #0860ca; }
.btn-secondary { background: #24292f; color: #fff; }
.btn-secondary:hover { background: #32383f; }
.btn-outline { background: #fff; color: #24292f; border: 1px solid #d0d7de; }
.btn-outline:hover { background: #f6f8fa; }
.or { color: #656d76; padding: 0 4px; font-size: 0.85rem; }
.drop-zone {
  border: 2px dashed #d0d7de;
  border-radius: 6px;
  padding: 24px;
  text-align: center;
  color: #656d76;
  margin-bottom: 16px;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
}
.drop-zone.over { border-color: #0969da; background: #ddf4ff; }
.drop-zone input { display: none; }
.status { margin-top: 12px; font-size: 0.85rem; color: #656d76; }
</style>
</head>
<body>
<div class="container">
  <h1>Markdown Converter</h1>
  <p class="sub">Convert Markdown to styled HTML or PDF with TOC and Mermaid diagrams</p>

  <div class="card">
    <label>Upload a .md file</label>
    <div class="drop-zone" id="dropZone">
      <p>Drag & drop a .md file here, or click to browse</p>
      <input type="file" id="fileInput" accept=".md,.markdown,.txt">
    </div>

    <label>Or paste Markdown</label>
    <textarea id="mdInput" placeholder="# Hello World&#10;&#10;Your markdown here..."></textarea>

    <div class="actions">
      <button class="btn btn-primary" onclick="convert('html')">Convert to HTML</button>
      <button class="btn btn-secondary" onclick="convert('pdf')">Convert to PDF</button>
      <button class="btn btn-outline" onclick="preview()">Preview</button>
    </div>
    <div class="status" id="status"></div>
  </div>
</div>

<script>
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const mdInput = document.getElementById('mdInput');
const status = document.getElementById('status');

dropZone.addEventListener('click', () => fileInput.click());
dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('over'); });
dropZone.addEventListener('dragleave', () => dropZone.classList.remove('over'));
dropZone.addEventListener('drop', (e) => {
  e.preventDefault();
  dropZone.classList.remove('over');
  const file = e.dataTransfer.files[0];
  if (file) readFile(file);
});
fileInput.addEventListener('change', () => {
  if (fileInput.files[0]) readFile(fileInput.files[0]);
});

function readFile(file) {
  const reader = new FileReader();
  reader.onload = (e) => {
    mdInput.value = e.target.result;
    status.textContent = 'Loaded: ' + file.name;
  };
  reader.readAsText(file);
}

async function convert(format) {
  const md = mdInput.value.trim();
  if (!md) { status.textContent = 'Please enter some markdown first.'; return; }

  status.textContent = 'Converting to ' + format.toUpperCase() + '...';
  try {
    const res = await fetch('/convert', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ markdown: md, format })
    });
    if (!res.ok) throw new Error(await res.text());

    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'output.' + (format === 'pdf' ? 'pdf' : 'html');
    a.click();
    URL.revokeObjectURL(url);
    status.textContent = 'Done!';
  } catch (err) {
    status.textContent = 'Error: ' + err.message;
  }
}

async function preview() {
  const md = mdInput.value.trim();
  if (!md) { status.textContent = 'Please enter some markdown first.'; return; }

  status.textContent = 'Generating preview...';
  try {
    const res = await fetch('/convert', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ markdown: md, format: 'html' })
    });
    if (!res.ok) throw new Error(await res.text());
    const html = await res.text();
    const w = window.open('', '_blank');
    w.document.write(html);
    w.document.close();
    status.textContent = 'Preview opened in new tab.';
  } catch (err) {
    status.textContent = 'Error: ' + err.message;
  }
}
</script>
</body>
</html>`;

function parseBody(req) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    let size = 0;
    const limit = 10 * 1024 * 1024; // 10MB
    req.on("data", (chunk) => {
      size += chunk.length;
      if (size > limit) {
        reject(new Error("Request body too large"));
        req.destroy();
        return;
      }
      chunks.push(chunk);
    });
    req.on("end", () => resolve(Buffer.concat(chunks).toString()));
    req.on("error", reject);
  });
}

const server = http.createServer(async (req, res) => {
  if (req.method === "GET" && (req.url === "/" || req.url === "")) {
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end(UPLOAD_PAGE);
    return;
  }

  if (req.method === "POST" && req.url === "/convert") {
    try {
      const body = JSON.parse(await parseBody(req));
      const { markdown, format } = body;

      if (!markdown) {
        res.writeHead(400, { "Content-Type": "text/plain" });
        res.end("Missing 'markdown' field");
        return;
      }

      const html = markdownToHtml(markdown);

      if (format === "pdf") {
        const pdfBuffer = await htmlToPdf(html);
        res.writeHead(200, {
          "Content-Type": "application/pdf",
          "Content-Disposition": "attachment; filename=output.pdf",
        });
        res.end(pdfBuffer);
      } else {
        res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
        res.end(html);
      }
    } catch (err) {
      console.error("Convert error:", err);
      res.writeHead(500, { "Content-Type": "text/plain" });
      res.end("Conversion failed: " + err.message);
    }
    return;
  }

  if (req.method === "GET" && req.url === "/health") {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ status: "ok" }));
    return;
  }

  res.writeHead(404, { "Content-Type": "text/plain" });
  res.end("Not found");
});

server.listen(PORT, () => {
  console.log(`md2html server listening on http://0.0.0.0:${PORT}`);
});
