/**
 * Laravel Mix Configuration for Program Theme
 *
 * This file configures the build process for the Program theme's assets.
 * It uses Laravel Mix, which is a wrapper around Webpack, to compile and
 * optimize JavaScript and SCSS files.
 */
const mix = require('laravel-mix');
const FileCollection = require('laravel-mix/src/FileCollection');

/**
 * Public Path Configuration
 *
 * Assets are compiled to the 'dist/' directory. Change realPublicPath to
 * '../../public/themes/your-theme-name/' to publish to the public folder afterwards.
 * This eliminates the need to run 'php artisan ignite:theme:publish' after each build.
 */
const realPublicPath = '';

// Set the base directory for compiled assets
mix.setPublicPath('dist/');

mix.webpackConfig({
    // Detailed warnings for child compilations
    stats: { children: false },
    // Module rules for processing different file types
    module: {
        rules: [{
            // Process JavaScript files
            test: /\.js$/,
            use: {
                loader: 'babel-loader',
                options: {
                    // Use modern JavaScript features
                    presets: ['@babel/preset-env'],
                    // Enable code compaction
                    compact: true,
                    // Enable Babel caching for faster builds
                    cacheDirectory: true,
                    // Disable cache compression for better performance
                    cacheCompression: false
                }
            }
        }]
    },
    // Filesystem caching configuration
    cache: {
        type: 'filesystem',
        buildDependencies: {
            // Invalidate cache when this config file changes
            config: [__filename]
        }
    }
});

/**
 * JavaScript Compilation
 *
 * mix.js() is added to .babel() just so the 'npm run watch' can invoke
 * mix.version() and .then() for javascript changes.
 */
mix.js('src/js/script.js', 'javascripts/scripts.js')
.babel([
    // Third-party libraries
    'node_modules/moment/moment.js',
    //'node_modules/moment-timezone/moment-timezone.js',
    'node_modules/jquery/dist/jquery.js',
    //'node_modules/popper.js/dist/popper.js',
    'node_modules/bootstrap-sass/assets/javascripts/bootstrap.js',
    'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js',
    'node_modules/jquery-match-height/dist/jquery.matchHeight.js',
    'node_modules/jquery-circle-progress/dist/circle-progress.js',
    'node_modules/jquery-validation/dist/jquery.validate.js',
    'node_modules/select2/dist/js/select2.full.js',
    // Core Ignite functionality
    '../../vendor/ignite/modules/Core/resources/assets/js/ignite.js',
    // Application script
    'src/js/script.js'
], 'dist/javascripts/scripts.js');

/**
 * SCSS Compilation
 *
 * Compiles SCSS files to CSS with specific include paths for:
 * 1. Theme-specific styles
 * 2. Default Ignite theme styles
 * 3. Bootstrap styles
 */
mix.sass('src/scss/style.scss', 'stylesheets/styles.css', {
    sassOptions: {
        includePaths: [
            './src/scss',
            '../../vendor/ignite/themes/default/src/scss',
            './node_modules/bootstrap-sass/assets/stylesheets'
        ]
    }
}).options({
    processCssUrls: false
});

/**
 * Version and Publish
 *
 * This section handles two critical tasks:
 * 1. Versioning of assets for cache busting
 * 2. Publishing of compiled assets to the public directory
 *
 * The process is intentionally split into two phases:
 *
 * Phase 1: Versioning (mix.version())
 * - Adds unique hashes to filenames for cache busting
 * - Updates mix-manifest.json with new file mappings
 * - Completes all build steps and file processing
 *
 * Phase 2: Publishing (in then() callback)
 * - Only runs after versioning is complete
 * - Uses glob to find all processed files
 * - Copies files while maintaining directory structure
 * - Ensures we're copying the final, versioned files
 *
 * Why this approach?
 * - Previous attempts using mix.copy() directly could copy files before versioning
 * - The then() callback ensures we only copy after all processing is complete
 * - glob provides reliable file pattern matching
 * - fs-extra.copySync ensures atomic file operations
 */
mix.version()
.then(() => {
    if (realPublicPath) {
        const glob = require('glob');
        const fs = require('fs-extra');
        const path = require('path');
        const files = glob.sync('dist/**/*', { nodir: true });
        files.forEach(file => {
            const relativePath = file.replace('dist/', '');
            const destination = path.join(realPublicPath, relativePath);
            fs.ensureDirSync(path.dirname(destination));
            fs.copySync(file, destination);
        });
    }
});