import http from 'node:http';
import { spawn, execSync } from 'node:child_process';
import { createReadStream, existsSync } from 'node:fs';
import { stat } from 'node:fs/promises';
import path from 'node:path';

import { buildHTML, VIDEO_PATH } from './server/html-builder.js';
import { dispatch } from './routes/index.js';

const PORT    = 3001;
const SDD_DIR = '.sdd';

export function runWeb(opts = {}) {
  const port        = opts.port ?? PORT;
  const cwd         = opts.cwd  ?? process.cwd();
  const projectName = path.basename(cwd);
  const ctx         = { cwd, port, SDD_DIR };

  const server = http.createServer(async (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET,POST,DELETE,OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
    if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; }

    const url = new URL(req.url, 'http://localhost:' + port);

    // GET / → HTML shell
    if (req.method === 'GET' && url.pathname === '/') {
      res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' });
      res.end(buildHTML(projectName));
      return;
    }

    // GET /intro.mp4 — serve the intro video with range-request support
    if (req.method === 'GET' && url.pathname === '/intro.mp4') {
      if (!existsSync(VIDEO_PATH)) { res.writeHead(404); res.end(); return; }
      try {
        const stats = await stat(VIDEO_PATH);
        const total = stats.size;
        const range = req.headers['range'];
        if (range) {
          const [startStr, endStr] = range.replace(/bytes=/, '').split('-');
          const start = parseInt(startStr, 10);
          const end   = endStr ? parseInt(endStr, 10) : total - 1;
          res.writeHead(206, {
            'Content-Range':  `bytes ${start}-${end}/${total}`,
            'Accept-Ranges':  'bytes',
            'Content-Length': end - start + 1,
            'Content-Type':   'video/mp4',
          });
          createReadStream(VIDEO_PATH, { start, end }).pipe(res);
        } else {
          res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4', 'Accept-Ranges': 'bytes' });
          createReadStream(VIDEO_PATH).pipe(res);
        }
      } catch (e) { res.writeHead(500); res.end(e.message); }
      return;
    }

    // All /api/* routes
    await dispatch(req, res, url, ctx);
  });

  server.timeout = 0;
  server.keepAliveTimeout = 0;

  server.listen(port, () => {
    const baseUrl = 'http://localhost:' + port;
    console.log('\n  SDD-FP Web → ' + baseUrl + '\n');
    const open = process.platform === 'darwin' ? 'open'
               : process.platform === 'win32'  ? 'start'
               : 'xdg-open';
    spawn(open, [baseUrl], { detached: true, stdio: 'ignore' }).unref();
  });

  server.on('error', (err) => {
    if (err.code === 'EADDRINUSE') {
      console.log('  Porta ' + port + ' em uso. Matando processo anterior e reiniciando...');
      try {
        execSync(
          process.platform === 'win32'
            ? `for /f "tokens=5" %a in ('netstat -aon ^| find ":${port} "') do taskkill /F /PID %a`
            : `lsof -ti :${port} | xargs kill -9`,
          { stdio: 'ignore' }
        );
      } catch {}
      setTimeout(() => server.listen(port), 1000);
    } else {
      console.error('  Erro no servidor web:', err.message);
      process.exit(1);
    }
  });
}
