import { defineConfig, loadEnv } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import html from '@rollup/plugin-html';
import { glob } from 'glob';
import fs from 'fs';
import path from 'path';

/**
 * Get Files from a directory
 * @param {string} query
 * @returns array
 */
function GetFilesArray(query) {
  return glob.sync(query);
}

function getModuleAssets() {
  const moduleAssets = [];

  try {
    // Read module statuses
    const moduleStatusesPath = path.join(process.cwd(), 'modules_statuses.json');
    const moduleStatuses = JSON.parse(fs.readFileSync(moduleStatusesPath, 'utf-8'));

    // Process each enabled module
    Object.entries(moduleStatuses).forEach(([moduleName, isEnabled]) => {
      if (isEnabled) {
        // Get JS files from module
        const moduleJsFiles = GetFilesArray(`Modules/${moduleName}/resources/assets/js/**/*.js`);
        moduleAssets.push(...moduleJsFiles);

        // Get SCSS/CSS files from module
        const moduleScssFiles = GetFilesArray(`Modules/${moduleName}/resources/assets/sass/**/*.scss`);
        const moduleCssFiles = GetFilesArray(`Modules/${moduleName}/resources/assets/css/**/*.css`);
        moduleAssets.push(...moduleScssFiles, ...moduleCssFiles);
      }
    });

    console.log(`Loaded assets from ${Object.values(moduleStatuses).filter(Boolean).length} enabled modules`);
  } catch (error) {
    console.warn('Could not load module assets:', error.message);
  }

  return moduleAssets;
}

/**
 * Js Files
 */
// Page JS Files
const pageJsFiles = GetFilesArray('resources/assets/js/*.js');

const pageAppJsFiles = GetFilesArray('resources/assets/js/app/*.js');

// Page specific JS files in pages directory
const pageDirJsFiles = GetFilesArray('resources/assets/js/pages/*.js');

// Employee report JS files
const employeeReportJsFiles = GetFilesArray('resources/assets/js/employees/**/*.js');

// Leave report JS files
const leaveReportJsFiles = GetFilesArray('resources/assets/js/leave/**/*.js');

// Processing Vendor JS Files
const vendorJsFiles = GetFilesArray('resources/assets/vendor/js/*.js');

// Processing Libs JS Files
const LibsJsFiles = GetFilesArray('resources/assets/vendor/libs/**/*.js');

/**
 * Scss Files
 */
// Processing Core, Themes & Pages Scss Files
const CoreScssFiles = GetFilesArray('resources/assets/vendor/scss/**/!(_)*.scss');

// Processing Libs Scss & Css Files
const LibsScssFiles = GetFilesArray('resources/assets/vendor/libs/**/!(_)*.scss');
const LibsCssFiles = GetFilesArray('resources/assets/vendor/libs/**/*.css');

const pageCssFiles = GetFilesArray('resources/assets/css/*.css');

// Processing Page Scss Files
const pageScssFiles = GetFilesArray('resources/assets/scss/**/*.scss');

// Processing Fonts Scss Files
const FontsScssFiles = GetFilesArray('resources/assets/vendor/fonts/!(_)*.scss');

// Get all module assets dynamically
const moduleAssets = getModuleAssets();

/**
 * Check if AIAgentFramework module exists and get its portal entry points
 * @returns array
 */
function getAgentPortalAssets() {
  const agentPortalAssets = [];
  const agentModulePath = 'Modules/AIAgentFramework/resources/js/main.ts';
  const agentStylesPath = 'Modules/AIAgentFramework/resources/css/portal.css';

  try {
    // Check if the module directory exists
    if (fs.existsSync(path.join(process.cwd(), agentModulePath))) {
      agentPortalAssets.push(agentModulePath);
      console.log('✓ AIAgentFramework portal entry point found');
    }

    // Check if portal styles exist
    if (fs.existsSync(path.join(process.cwd(), agentStylesPath))) {
      agentPortalAssets.push(agentStylesPath);
      console.log('✓ AIAgentFramework portal styles found');
    }

    if (agentPortalAssets.length === 0) {
      console.log('ℹ AIAgentFramework module not found - portal will not be included');
    }
  } catch (error) {
    console.warn('Could not check for AIAgentFramework module:', error.message);
  }

  return agentPortalAssets;
}

// Get agent portal assets if module exists
const agentPortalAssets = getAgentPortalAssets();


// Processing Window Assignment for Libs like jKanban, pdfMake
function libsWindowAssignment() {
  return {
    name: 'libsWindowAssignment',

    transform(src, id) {
      if (id.includes('jkanban.js')) {
        return src.replace('this.jKanban', 'window.jKanban');
      } else if (id.includes('vfs_fonts')) {
        return src.replaceAll('this.pdfMake', 'window.pdfMake');
      }
    }
  };
}

export default defineConfig(({ mode }) => {
  // Load env file based on `mode` in the current working directory.
  const env = loadEnv(mode, process.cwd(), '');

  // Extract host from APP_URL (e.g., http://192.168.0.5:8000 -> 192.168.0.5)
  let hmrHost = 'localhost';
  if (env.APP_URL) {
    try {
      const url = new URL(env.APP_URL);
      hmrHost = url.hostname;
    } catch (e) {
      console.warn('Could not parse APP_URL, using localhost for HMR');
    }
  }

  return {
    plugins: [
      laravel({
        input: [
          'resources/css/app.css',
          'resources/assets/css/demo.css',
          'resources/js/app.js',
          ...pageJsFiles,
          ...pageAppJsFiles,
          ...pageDirJsFiles,
          ...employeeReportJsFiles,
          ...leaveReportJsFiles,
          ...vendorJsFiles,
          ...LibsJsFiles,
          ...LibsJsFiles,
          'resources/js/main-helper.js', // Processing Main Helper JS File
          'resources/js/main-datatable.js', // Processing Main Datatable JS File
          'resources/js/main-select2.js', // Processing Main Select2 JS File
          ...CoreScssFiles,
          ...LibsScssFiles,
          ...LibsCssFiles,
          ...FontsScssFiles,
          ...pageCssFiles,
          ...pageScssFiles,
          // Include all module assets dynamically
          ...moduleAssets,
          // Include Agent Portal assets if module exists
          ...agentPortalAssets
        ],
        refresh: true
      }),
      vue(),
      html(),
      libsWindowAssignment()
    ],
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'resources/js'),
        '@agent-portal': path.resolve(__dirname, 'Modules/AIAgentFramework/resources/js')
      }
    },
    server: {
      host: '0.0.0.0',
      ...(() => {
        const keyPath = path.resolve(process.env.HOME || '', '.config/valet/Certificates/opencorebs.test.key');
        const certPath = path.resolve(process.env.HOME || '', '.config/valet/Certificates/opencorebs.test.crt');
        if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
          return {
            https: {
              key: fs.readFileSync(keyPath),
              cert: fs.readFileSync(certPath),
            }
          };
        }
        return {};
      })(),
      hmr: {
        host: hmrHost
      }
    },
    build: {
      // Chunk size limits
      chunkSizeWarningLimit: 1000,

      // Use esbuild for faster, more memory-efficient minification
      minify: 'esbuild',

      rollupOptions: {
        // laravel-echo is now bundled for Agent Portal WebSocket support
        output: {
          manualChunks: {
            'agent-portal': ['vue', 'vue-router', 'pinia'],
            'websocket': ['laravel-echo', 'pusher-js']
          }
        }
      },

      // Disable sourcemap for production to save memory
      sourcemap: false,

      // Optimize CSS
      cssCodeSplit: true,
      cssMinify: 'esbuild'
    }
  };
});
