const http = require('http');
const fs = require('fs');
const fsp = require('fs/promises');
const path = require('path');
const { URL } = require('url');

// Azure sets PORT
const PORT = process.env.PORT || 8080;

// Default site if host doesn't map
const DEFAULT_SITE = 'default';

// Explicit host ? folder mapping
const HOST_MAP = {
  'adpadmin.usimdev.com': 'admin',
  'adpclient.usimdev.com': 'client',
  'adpregist.usimdev.com': 'regist',
  'adptestapi.usimdev.com': 'testapi',
  'localhost': 'default'
};

const server = http.createServer(async (req, res) => {
  try {
    const hostHeader = (req.headers.host || '').toLowerCase();
    console.log(`[SRV ${new Date().toISOString()}] ${req.method} ${req.url} (Host: ${hostHeader})`);

    // Parse URL with WHATWG API (avoids url.parse deprecation)
    const parsedUrl = new URL(req.url || '/', `http://${hostHeader || 'localhost'}`);
    const pathname = decodeURIComponent(parsedUrl.pathname || '/');
    const parts = pathname.replace(/^\/+/, '').split('/');
    const firstSegment = parts[0] || '';

    // Decide which site folder to serve from
    const siteFolder = getSiteFolder(hostHeader);
    const BASEDIR = path.join(__dirname, 'websites', siteFolder);

    console.log(`Site folder resolved: /websites/${siteFolder} (host=${hostHeader})`);

    // --- favicon special case ---
    if (firstSegment === 'favicon.ico') {
      const favPath = safeJoin(BASEDIR, 'favicon.ico');
      if (await exists(favPath)) {
        res.writeHead(200, { 'Content-Type': 'image/x-icon' });
        return fs.createReadStream(favPath).pipe(res);
      } else {
        res.writeHead(204);
        return res.end();
      }
    }

    // --- robots.txt (optional per-site) ---
    if (firstSegment === 'robots.txt') {
      const robotsPath = safeJoin(BASEDIR, 'robots.txt');
      if (await exists(robotsPath)) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        return fs.createReadStream(robotsPath).pipe(res);
      }
      // no robots for this site ? 404
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      return res.end('Not found');
    }

    // Static file resolution
    let requested = firstSegment || 'index.html';
    if (parts.length > 1) {
      requested = parts.join('/');
    }

    let filePath = safeJoin(BASEDIR, requested);

    if (await isDir(filePath)) {
      filePath = safeJoin(filePath, 'index.html');
    }

    // Handle Index.html vs index.html (case difference on dev machines)
    if (!(await exists(filePath)) && /Index\.html$/.test(filePath)) {
      const alt = filePath.replace(/Index\.html$/, 'index.html');
      if (await exists(alt)) filePath = alt;
    }

    // If the requested file doesn't exist:
    // 1) try this site's index.html (SPA routing)
    // 2) try shared 404.html in root
    if (!(await exists(filePath))) {
      const siteIndex = safeJoin(BASEDIR, 'index.html');
      if (await exists(siteIndex)) {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        return fs.createReadStream(siteIndex).pipe(res);
      }

      const shared404 = path.join(__dirname, '404.html');
      if (await exists(shared404)) {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        return fs.createReadStream(shared404).pipe(res);
      }

      res.writeHead(404, { 'Content-Type': 'text/plain' });
      return res.end('404 Not Found');
    }

    // Serve the static file
    res.writeHead(200, { 'Content-Type': getType(filePath) });
    return fs.createReadStream(filePath).pipe(res);

  } catch (err) {
    console.error('[SERVER ERROR]', err);
    res.writeHead(500, { 'Content-Type': 'application/json' });
    return res.end(JSON.stringify({ status: 'error', error: err?.message || String(err) }));
  }
});

server.listen(PORT, () => {
  console.log('===========================================');
  console.log(`Static HTTP server listening on ${PORT}`);
  console.log(`Default site: /websites/${DEFAULT_SITE}/`);
  console.log('Host mappings:');
  Object.entries(HOST_MAP).forEach(([host, folder]) => {
    console.log(`  ${host}  ?  /websites/${folder}/`);
  });
  console.log('Fallback (subdomain): sub.domain.tld ? /websites/<sub>/');
  console.log('Shared 404 (optional): /404.html');
  console.log('===========================================');
});

module.exports = server;

/* ------------ helpers ------------ */

function getSiteFolder(hostnameRaw) {
  if (!hostnameRaw) return DEFAULT_SITE;

  const hostname = hostnameRaw.toLowerCase();

  // 1) Explicit map wins
  if (HOST_MAP[hostname]) {
    return HOST_MAP[hostname];
  }

  // 2) localhost or IP ? default
  if (hostname === 'localhost' || /^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
    return DEFAULT_SITE;
  }

  // 3) For multi-tenant subdomains: foo.example.com ? "foo"
  const parts = hostname.split('.');
  if (parts.length >= 3) {
    return parts[0];
  }

  // 4) Anything else ? default
  return DEFAULT_SITE;
}

function safeJoin(base, target) {
  const resolved = path.resolve(base, target);
  if (!resolved.startsWith(base)) {
    // Prevent directory traversal – fall back to base
    return base;
  }
  return resolved;
}

async function exists(p) {
  try {
    await fsp.access(p, fs.constants.R_OK);
    return true;
  } catch {
    return false;
  }
}

async function isDir(p) {
  try {
    return (await fsp.stat(p)).isDirectory();
  } catch {
    return false;
  }
}

function getType(filename) {
  const ext = path.extname(filename).toLowerCase();
  switch (ext) {
    case '.html': return 'text/html';
    case '.css': return 'text/css';
    case '.js': return 'application/javascript';
    case '.png': return 'image/png';
    case '.jpg':
    case '.jpeg': return 'image/jpeg';
    case '.svg': return 'image/svg+xml';
    case '.ico': return 'image/x-icon';
    case '.json': return 'application/json';
    case '.map': return 'application/json';
    case '.woff2': return 'font/woff2';
    case '.woff': return 'font/woff';
    case '.ttf': return 'font/ttf';
    case '.eot': return 'application/vnd.ms-fontobject';
    default: return 'text/plain';
  }
}
