const express      = require('express');
const { execSync } = require('child_process');
const fs           = require('fs');
const path         = require('path');
const router       = express.Router();
const authMw       = require('../middleware/auth');
const { writeAudit } = require('./audit');

const ps = (cmd, timeout = 30000) =>
  execSync(`powershell -ExecutionPolicy Bypass -Command "${cmd}"`, { timeout }).toString().trim();

// ── List sites ─────────────────────────────────────────────
router.get('/', authMw, (req, res) => {
  try {
    const raw = ps(`Import-Module WebAdministration; Get-Website | ConvertTo-Json -Depth 2`);
    if (!raw) return res.json([]);
    const list = JSON.parse(raw);
    res.json(Array.isArray(list) ? list : [list]);
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── IIS status ─────────────────────────────────────────────
router.get('/iis-status', authMw, (req, res) => {
  try {
    // Method 1 — check W3SVC service (works on all Windows versions)
    const svc = ps(`(Get-Service -Name W3SVC -ErrorAction SilentlyContinue).Status`).trim();
    if (svc === 'Running' || svc === 'Stopped') {
      return res.json({ installed: true });
    }
    // Method 2 — check if IIS files exist
    const iisExists = ps(`Test-Path 'C:\\Windows\\System32\\inetsrv\\iisreset.exe'`).trim();
    if (iisExists === 'True') {
      return res.json({ installed: true });
    }
    res.json({ installed: false });
  } catch {
    res.json({ installed: false });
  }
});

// ── IIS install ────────────────────────────────────────────
router.post('/iis-install', authMw, (req, res) => {
  try {
    // Detect Windows Server vs Windows 10/11
    const caption = ps(`(Get-WmiObject Win32_OperatingSystem).Caption`).trim();
    const isServer = caption.toLowerCase().includes('server');

    if (isServer) {
      ps(`Import-Module ServerManager -ErrorAction SilentlyContinue; Install-WindowsFeature -Name Web-Server,Web-Mgmt-Console,Web-Asp-Net45 -IncludeManagementTools`, 300000);
    } else {
      // Windows 10/11 — use Enable-WindowsOptionalFeature
      const features = [
        'IIS-WebServerRole', 'IIS-WebServer', 'IIS-CommonHttpFeatures',
        'IIS-DefaultDocument', 'IIS-HttpErrors', 'IIS-StaticContent',
        'IIS-ApplicationDevelopment', 'IIS-ASPNET45', 'IIS-NetFxExtensibility45',
        'IIS-ISAPIExtensions', 'IIS-ISAPIFilter', 'IIS-HealthAndDiagnostics',
        'IIS-HttpLogging', 'IIS-Security', 'IIS-RequestFiltering',
        'IIS-WebServerManagementTools', 'IIS-ManagementConsole'
      ];
      features.forEach(f => {
        try {
          ps(`Enable-WindowsOptionalFeature -Online -FeatureName ${f} -NoRestart -ErrorAction SilentlyContinue`, 120000);
        } catch {}
      });
    }
    writeAudit(req, 'sites.iis-install', 'IIS installation triggered');
    res.json({ ok: true });
  } catch(e) {
    res.status(500).json({ error: e.message });
  }
});

// ── Create site ────────────────────────────────────────────
router.post('/create', authMw, (req, res) => {
  const { name, port, hostname, path: sitePath, pool, createFolder } = req.body;
  if (!name || !port || !sitePath)
    return res.status(400).json({ error: 'Site name, port and path are required' });
  if (!/^[a-zA-Z0-9_\-. ]+$/.test(name))
    return res.status(400).json({ error: 'Site name contains invalid characters' });

  try {
    if (createFolder) {
      fs.mkdirSync(sitePath, { recursive: true });
      const indexFile = path.join(sitePath, 'index.html');
      if (!fs.existsSync(indexFile)) {
        fs.writeFileSync(indexFile,
          `<!DOCTYPE html><html><head><title>${name}</title></head><body><h1>${name}</h1><p>Site created by ServerPanel.</p></body></html>`
        );
      }
    }
    const appPool = pool || 'DefaultAppPool';
    const hostHdr = hostname ? `-HostHeader '${hostname}'` : '';
    ps([
      `Import-Module WebAdministration;`,
      `New-Website -Name '${name}' -Port ${parseInt(port)} -PhysicalPath '${sitePath}' -ApplicationPool '${appPool}' ${hostHdr} -Force`
    ].join(' '));
    writeAudit(req, 'sites.create', `Created site "${name}" on port ${port} at ${sitePath}`);
    res.json({ ok: true });
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Edit site ──────────────────────────────────────────────
router.put('/:name', authMw, (req, res) => {
  const { name } = req.params;
  const { port, hostname, path: sitePath, pool } = req.body;
  try {
    if (sitePath)
      ps(`Import-Module WebAdministration; Set-ItemProperty "IIS:\\Sites\\${name}" -Name physicalPath -Value '${sitePath}'`);
    if (port) {
      const host = hostname || '';
      ps(`Import-Module WebAdministration; $b=(Get-WebBinding -Name '${name}' | Select-Object -First 1); $b.bindingInformation="*:${parseInt(port)}:${host}"; $b | Set-WebBinding`);
    }
    if (pool)
      ps(`Import-Module WebAdministration; Set-ItemProperty "IIS:\\Sites\\${name}" -Name applicationPool -Value '${pool}'`);
    writeAudit(req, 'sites.edit', `Edited site "${name}"`);
    res.json({ ok: true });
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Start / Stop / Restart ─────────────────────────────────
router.post('/:name/start', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Start-Website -Name '${req.params.name}'`);
  sCacheClear('sites');
    writeAudit(req, 'sites.start', `Started site "${req.params.name}"`);
    res.json({ ok: true });
  } catch(e) { res.status(500).json({ error: e.message }); }
});
router.post('/:name/stop', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Stop-Website -Name '${req.params.name}'`);
  sCacheClear('sites');
    writeAudit(req, 'sites.stop', `Stopped site "${req.params.name}"`);
    res.json({ ok: true });
  } catch(e) { res.status(500).json({ error: e.message }); }
});
router.post('/:name/restart', authMw, (req, res) => {
  try {
    ps(`Import-Module WebAdministration; Stop-Website -Name '${req.params.name}'; Start-Website -Name '${req.params.name}'`);
  sCacheClear('sites');
    writeAudit(req, 'sites.restart', `Restarted site "${req.params.name}"`);
    res.json({ ok: true });
  } catch(e) { res.status(500).json({ error: e.message }); }
});


// ── Backup site ────────────────────────────────────────────
router.post('/:name/backup', authMw, (req, res) => {
  const { name } = req.params;
  try {
    const sitePath = ps(`Import-Module WebAdministration; (Get-Website -Name '${name}').physicalPath`);
    if (!sitePath) return res.status(404).json({ error: 'Site not found or has no physical path' });
    const backupDir = path.join(__dirname, '../data/backups');
    fs.mkdirSync(backupDir, { recursive: true });
    const stamp   = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
    const zipName = `${name}_${stamp}.zip`;
    const zipPath = path.join(backupDir, zipName);
    ps(`Compress-Archive -Path '${sitePath}\\*' -DestinationPath '${zipPath}' -Force`, 120000);
    const stat = fs.statSync(zipPath);
    writeAudit(req, 'sites.backup', `Backed up site "${name}" → ${zipName}`);
    res.json({ ok: true, file: zipName, size: stat.size, path: zipPath });
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── List backups ───────────────────────────────────────────
router.get('/backups', authMw, (req, res) => {
  const backupDir = path.join(__dirname, '../data/backups');
  try {
    if (!fs.existsSync(backupDir)) return res.json([]);
    const files = fs.readdirSync(backupDir)
      .filter(f => f.endsWith('.zip'))
      .map(f => {
        const stat = fs.statSync(path.join(backupDir, f));
        return { name: f, size: stat.size, created: stat.birthtime };
      })
      .sort((a, b) => new Date(b.created) - new Date(a.created));
    res.json(files);
  } catch(e) { res.status(500).json({ error: e.message }); }
});

module.exports = router;