/**
 * vite-plugin-editor-api.js - Vite dev server plugin voor de Markdown editor
 *
 * Biedt API endpoints voor het opslaan van Markdown en het uploaden van afbeeldingen.
 * Alleen actief tijdens development (npm run dev), niet in productie builds.
 *
 * Endpoints:
 * - POST /__editor/save    - Slaat Markdown content op naar content/installatie.md
 * - POST /__editor/upload   - Upload een afbeelding naar public/images/installatie/
 * - GET  /__editor/images   - Lijst beschikbare afbeeldingen
 */

/* eslint-disable no-undef */
import fs from 'fs';
import path from 'path';

export function editorApiPlugin() {
  return {
    name: 'editor-api',
    configureServer(server) {
      const rootDir = server.config.root;

      // POST /__editor/save - Markdown content opslaan
      server.middlewares.use('/__editor/save', (req, res, next) => {
        if (req.method !== 'POST') return next();

        let body = '';
        req.on('data', chunk => { body += chunk; });
        req.on('end', () => {
          try {
            const { content, filename } = JSON.parse(body);
            // Bestandsnaam uit request, fallback naar installatie.md
            const safeName = (filename || 'installatie.md').replace(/[^a-zA-Z0-9._-]/g, '');
            const filePath = path.join(rootDir, 'content', safeName);

            // Zorg dat de content directory bestaat
            const dir = path.dirname(filePath);
            if (!fs.existsSync(dir)) {
              fs.mkdirSync(dir, { recursive: true });
            }

            fs.writeFileSync(filePath, content, 'utf-8');

            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ success: true, path: filePath }));
          } catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
          }
        });
      });

      // POST /__editor/upload - Afbeelding uploaden
      server.middlewares.use('/__editor/upload', (req, res, next) => {
        if (req.method !== 'POST') return next();

        const chunks = [];
        req.on('data', chunk => chunks.push(chunk));
        req.on('end', () => {
          try {
            const buffer = Buffer.concat(chunks);
            const boundary = req.headers['content-type'].split('boundary=')[1];
            const { filename, fileData } = parseMultipart(buffer, boundary);

            if (!filename) {
              res.writeHead(400, { 'Content-Type': 'application/json' });
              res.end(JSON.stringify({ error: 'Geen bestand gevonden' }));
              return;
            }

            // Valideer bestandstype
            const ext = path.extname(filename).toLowerCase();
            const allowed = ['.png', '.jpg', '.jpeg', '.gif', '.webp'];
            if (!allowed.includes(ext)) {
              res.writeHead(400, { 'Content-Type': 'application/json' });
              res.end(JSON.stringify({ error: `Bestandstype ${ext} niet toegestaan` }));
              return;
            }

            // Bepaal bestandsnaam (voeg timestamp toe bij duplicaat)
            const imageDir = path.join(rootDir, 'public', 'images', 'installatie');
            if (!fs.existsSync(imageDir)) {
              fs.mkdirSync(imageDir, { recursive: true });
            }

            let finalName = filename;
            const destPath = path.join(imageDir, finalName);
            if (fs.existsSync(destPath)) {
              const base = path.basename(filename, ext);
              const timestamp = Date.now();
              finalName = `${base}-${timestamp}${ext}`;
            }

            fs.writeFileSync(path.join(imageDir, finalName), fileData);

            const relativePath = `images/installatie/${finalName}`;
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ success: true, path: relativePath, filename: finalName }));
          } catch (err) {
            res.writeHead(500, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ error: err.message }));
          }
        });
      });

      // GET /__editor/images - Lijst beschikbare afbeeldingen
      server.middlewares.use('/__editor/images', (req, res, next) => {
        if (req.method !== 'GET') return next();

        try {
          const imageDir = path.join(rootDir, 'public', 'images', 'installatie');
          if (!fs.existsSync(imageDir)) {
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({ images: [] }));
            return;
          }

          const files = fs.readdirSync(imageDir)
            .filter(f => /\.(png|jpg|jpeg|gif|webp)$/i.test(f))
            .map(f => ({
              filename: f,
              path: `images/installatie/${f}`,
            }));

          res.writeHead(200, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ images: files }));
        } catch (err) {
          res.writeHead(500, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: err.message }));
        }
      });
    },
  };
}

/**
 * Simpele multipart/form-data parser.
 * Extraheert het eerste bestand uit de multipart body.
 */
function parseMultipart(buffer, boundary) {
  const boundaryBuffer = Buffer.from(`--${boundary}`);
  const parts = [];
  let start = 0;

  while (true) {
    const idx = buffer.indexOf(boundaryBuffer, start);
    if (idx === -1) break;
    if (start > 0) {
      // Verwijder de trailing \r\n voor de boundary
      parts.push(buffer.slice(start, idx - 2));
    }
    start = idx + boundaryBuffer.length + 2; // Skip boundary + \r\n
  }

  for (const part of parts) {
    const headerEnd = part.indexOf('\r\n\r\n');
    if (headerEnd === -1) continue;

    const headers = part.slice(0, headerEnd).toString('utf-8');
    const filenameMatch = headers.match(/filename="(.+?)"/);

    if (filenameMatch) {
      return {
        filename: filenameMatch[1],
        fileData: part.slice(headerEnd + 4),
      };
    }
  }

  return { filename: null, fileData: null };
}
