import lighthouse from 'lighthouse';
import { launch } from 'chrome-launcher';
import PageSpeedTest from '../models/pageSpeedTest.model.js';
import path from 'path';
import fs from 'fs';

const reportsDir = path.join(process.cwd(), 'public', 'lighthouse-treemap');
// Ensure folder exists
if (!fs.existsSync(reportsDir)) fs.mkdirSync(reportsDir, { recursive: true });

const launchChromeAndRunLighthouse = async (url, device = 'mobile') => {
  const chrome = await launch({ chromeFlags: ['--headless'] });

  const options = {
    port: chrome.port,
    emulatedFormFactor: device,
    throttlingMethod: device === 'mobile' ? 'simulate' : 'devtools',
    output: 'json', // JSON for metrics
  };

  const runnerResult = await lighthouse(url, options);
  const lhr = runnerResult.lhr;

  // Create HTML treemap report (only once, for mobile)
  let treemapFile = null;
  if (device === 'mobile') {
    const fileName = `treemap-${Date.now()}.html`;
    treemapFile = `/lighthouse-treemap/${fileName}`;

    // Generate HTML report
    const htmlReport = await lighthouse(url, {
      port: chrome.port,
      emulatedFormFactor: device,
      throttlingMethod: 'simulate',
      output: 'html',
    });

    fs.writeFileSync(path.join(reportsDir, fileName), htmlReport.report);
  }

  await chrome.kill();

  // Structured result
  const result = {
    url,
    device,
    scores: {
      performance: Math.round(lhr.categories.performance?.score * 100),
      accessibility: Math.round(lhr.categories.accessibility?.score * 100),
      bestPractices: Math.round(lhr.categories['best-practices']?.score * 100),
      seo: Math.round(lhr.categories.seo?.score * 100),
      pwa: lhr.categories.pwa?.score ? Math.round(lhr.categories.pwa.score * 100) : null,
    },
    metrics: {
      firstContentfulPaint: lhr.audits['first-contentful-paint']?.displayValue || null,
      largestContentfulPaint: lhr.audits['largest-contentful-paint']?.displayValue || null,
      totalBlockingTime: lhr.audits['total-blocking-time']?.displayValue || null,
      timeToInteractive: lhr.audits['interactive']?.displayValue || null,
      speedIndex: lhr.audits['speed-index']?.displayValue || null,
      cumulativeLayoutShift: lhr.audits['cumulative-layout-shift']?.displayValue || null,
    },
    opportunities: Object.values(lhr.audits)
      .filter(a => a.details?.type === 'opportunity')
      .map(a => ({
        title: a.title,
        description: a.description,
        estimatedSavings: a.details?.overallSavingsMs
          ? `${Math.round(a.details.overallSavingsMs)} ms`
          : null,
      })),
    diagnostics: {
      usesHTTPS: lhr.audits['is-on-https']?.score === 1,
      usesEfficientCachePolicy: lhr.audits['uses-long-cache-ttl']?.score === 1,
      imageCompression: lhr.audits['uses-optimized-images']?.score === 1,
    },
    failedAudits: Object.values(lhr.audits)
      .filter(a => a.score !== null && a.score !== 1 && a.scoreDisplayMode !== 'notApplicable')
      .map(a => ({ title: a.title, description: a.description })),
    passedAudits: Object.values(lhr.audits)
      .filter(a => a.score === 1 && a.scoreDisplayMode !== 'notApplicable' && !a.details?.type)
      .map(a => a.title),
    notApplicableAudits: Object.values(lhr.audits)
      .filter(a => a.scoreDisplayMode === 'notApplicable')
      .map(a => a.title),
    screenshot: lhr.audits['final-screenshot']?.details?.data || null,
    createdAt: new Date(),
    treemapPath: treemapFile,
  };

  const report = await PageSpeedTest.create(result);
  return { report };
};

export const runAudit = async (req, res, next) => {
  try {
    const { url } = req.body;
    if (!url) return res.status(400).json({ message: 'URL is required' });

    const mobileResult  = await launchChromeAndRunLighthouse(url, 'mobile');
    const desktopResult = await launchChromeAndRunLighthouse(url, 'desktop');

    res.status(200).json({
      message: 'Audit completed successfully',
      results: {
        mobile: mobileResult.report,
        desktop: desktopResult.report,
        treemap: mobileResult.report.treemapPath, // HTML report
      },
    });
  } catch (err) {
    next(err);
  }
};
