import fs from 'fs';
import path from 'path';

import { defineConfig } from 'vite';

import { handleApiRequest } from './shared/api-routes.js';

export default defineConfig({
  root: '.',
  server: {
    fs: { strict: false },
    cors: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
    },
  },
  plugins: [
    {
      name: 'print-preview-url',
      configureServer(server) {
        server.httpServer?.once('listening', () => {
          const baseUrl = `http://localhost:${server.config.server.port || 5173}`;
          console.log('Preview URL: ', baseUrl + '/preview/sections/preview.html\n');
          console.log('🛑 Press Ctrl+C to stop the local server 🛑\n');
        });
      },
    },
    {
      name: 'no-vite-cache',
      configureServer(server) {
        // use process.cwd() for analytics path
        const analyticsDir = path.resolve(process.cwd(), 'preview', 'shared');
        const analyticsFile = path.resolve(analyticsDir, 'analytics.json');

        // ensure analytics folder & file exist
        fs.mkdirSync(analyticsDir, { recursive: true });
        if (!fs.existsSync(analyticsFile)) {
          fs.writeFileSync(analyticsFile, JSON.stringify({}, null, 2), 'utf-8');
        }

        // helper to bump and persist counter for a given section
        function bumpSectionCount(section) {
          const raw = fs.readFileSync(analyticsFile, 'utf-8');
          const data = JSON.parse(raw);
          const next = (data[section] || 0) + 1;
          data[section] = next;
          fs.writeFileSync(analyticsFile, JSON.stringify(data, null, 2), 'utf-8');
          return next;
        }

        server.middlewares.use((req, res, next) => {
          // Invalidate all caches so we fetch most recent sections data
          server.moduleGraph.invalidateAll();

          const url = req.url || '';

          // Skip HMR and internal Vite requests
          if (url.startsWith('/@') || url.includes('__vite') || url.includes('.hot-update.')) {
            return next();
          }

          // Add CORS headers and disable caching for our API responses
          if (url.startsWith('/api/') || url.startsWith('/chosen-section')) {
            res.setHeader('Access-Control-Allow-Origin', '*');
            res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
            res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
            res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
            res.setHeader('Pragma', 'no-cache');
            res.setHeader('Expires', '0');
          }

          // Handle preflight OPTIONS requests
          if (req.method === 'OPTIONS') {
            res.statusCode = 200;
            return res.end();
          }

          // Let Vite handle all non-API requests for proper HMR
          if (!url.startsWith('/api/') && !url.startsWith('/chosen-section')) {
            return next();
          }

          if (url.startsWith('/chosen-section')) {
            // extract "sectionName" from "/chosen-section/<sectionName>"

            const sectionName = req.url.replace(/\/$/, '').split('/').filter(Boolean).pop();
            const newCount = bumpSectionCount(sectionName);

            res.statusCode = 200;
            res.setHeader('Content-Type', 'application/json');
            return res.end(JSON.stringify({
              section: sectionName,
              count: newCount,
            }));
          }

          // Handle API routes
          if (url.startsWith('/api/v1/')) {
            // Extract auth header from request
            const authHeader = req.headers['authorization'] || '';

            // Delegate to API router
            (async () => {
              await handleApiRequest(req, res, authHeader);
            })();
            return; // Exit early for async handling
          }

          // all other requests
          next();
        },
        );
      },
    },
  ],
});
