#!/usr/bin/env node

/**
 * Build script for production deployment
 * Handles CSS compilation, asset optimization, and production setup
 */

const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');

const execAsync = promisify(exec);

// Configuration
const BUILD_DIR = path.join(__dirname, '..', 'dist');
const PUBLIC_DIR = path.join(__dirname, '..', 'public');
const VIEWS_DIR = path.join(__dirname, '..', 'views');

async function buildForProduction() {
    try {
        console.log('🏗️  Starting production build...');
        
        // Create build directory
        await createBuildDirectory();
        
        // Install production dependencies
        await installProductionDependencies();
        
        // Optimize assets
        await optimizeAssets();
        
        // Generate service worker with workbox
        await generateServiceWorker();
        
        // Create production environment file
        await createProductionEnv();
        
        // Copy necessary files
        await copyProductionFiles();
        
        console.log('✅ Production build completed successfully!');
        console.log('📦 Build output available in:', BUILD_DIR);
        console.log('🚀 Ready for deployment!');
        
    } catch (error) {
        console.error('❌ Production build failed:', error);
        process.exit(1);
    }
}

async function createBuildDirectory() {
    try {
        if (fs.existsSync(BUILD_DIR)) {
            console.log('🗑️  Cleaning existing build directory...');
            await execAsync(`rm -rf ${BUILD_DIR}`);
        }
        
        fs.mkdirSync(BUILD_DIR, { recursive: true });
        console.log('📁 Created build directory');
    } catch (error) {
        console.error('❌ Error creating build directory:', error);
        throw error;
    }
}

async function installProductionDependencies() {
    try {
        console.log('📦 Installing production dependencies...');
        await execAsync('npm ci --only=production');
        console.log('✅ Production dependencies installed');
    } catch (error) {
        console.error('❌ Error installing dependencies:', error);
        throw error;
    }
}

async function optimizeAssets() {
    try {
        console.log('🎨 Optimizing CSS and JavaScript...');
        
        // Create optimized CSS
        const cssContent = fs.readFileSync(path.join(PUBLIC_DIR, 'css', 'main.css'), 'utf8');
        const optimizedCSS = await optimizeCSS(cssContent);
        
        const buildCSSDir = path.join(BUILD_DIR, 'public', 'css');
        fs.mkdirSync(buildCSSDir, { recursive: true });
        fs.writeFileSync(path.join(buildCSSDir, 'main.min.css'), optimizedCSS);
        
        // Create optimized JavaScript
        const jsContent = fs.readFileSync(path.join(PUBLIC_DIR, 'js', 'main.js'), 'utf8');
        const optimizedJS = await optimizeJS(jsContent);
        
        const buildJSDir = path.join(BUILD_DIR, 'public', 'js');
        fs.mkdirSync(buildJSDir, { recursive: true });
        fs.writeFileSync(path.join(buildJSDir, 'main.min.js'), optimizedJS);
        
        // Copy other assets
        await copyDirectory(path.join(PUBLIC_DIR, 'images'), path.join(BUILD_DIR, 'public', 'images'));
        
        console.log('✅ Assets optimized');
    } catch (error) {
        console.error('❌ Error optimizing assets:', error);
        throw error;
    }
}

async function optimizeCSS(css) {
    // Simple CSS minification (remove comments, extra whitespace)
    return css
        .replace(/\/\*[\s\S]*?\*\//g, '') // Remove comments
        .replace(/\s{2,}/g, ' ') // Replace multiple spaces with single space
        .replace(/;\s*}/g, '}') // Remove semicolon before closing brace
        .replace(/\s*{\s*/g, '{') // Remove spaces around opening brace
        .replace(/;\s*/g, ';') // Remove spaces after semicolons
        .replace(/,\s*/g, ',') // Remove spaces after commas
        .trim();
}

async function optimizeJS(js) {
    // Simple JS minification (remove comments, extra whitespace)
    return js
        .replace(/\/\/.*$/gm, '') // Remove single-line comments
        .replace(/\/\*[\s\S]*?\*\//g, '') // Remove multi-line comments
        .replace(/\s{2,}/g, ' ') // Replace multiple spaces with single space
        .replace(/\n\s*/g, '') // Remove newlines and indentation
        .trim();
}

async function generateServiceWorker() {
    try {
        console.log('⚙️  Generating optimized service worker...');
        
        const swContent = fs.readFileSync(path.join(PUBLIC_DIR, 'sw.js'), 'utf8');
        const optimizedSW = await optimizeJS(swContent);
        
        fs.writeFileSync(path.join(BUILD_DIR, 'public', 'sw.js'), optimizedSW);
        
        // Copy manifest
        fs.copyFileSync(
            path.join(PUBLIC_DIR, 'manifest.json'),
            path.join(BUILD_DIR, 'public', 'manifest.json')
        );
        
        console.log('✅ Service worker generated');
    } catch (error) {
        console.error('❌ Error generating service worker:', error);
        throw error;
    }
}

async function createProductionEnv() {
    try {
        console.log('🔧 Creating production environment configuration...');
        
        const prodEnv = `
# Production Environment Configuration
NODE_ENV=production
PORT=3000

# Database
MONGODB_URI=mongodb://localhost:27017/smartsoltech

# Security
SESSION_SECRET=your-super-secret-session-key-change-this-in-production
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production

# File Upload
UPLOAD_PATH=./uploads
MAX_FILE_SIZE=10485760

# Email Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password

# Telegram Bot (Optional)
TELEGRAM_BOT_TOKEN=your-telegram-bot-token

# Admin Account
ADMIN_EMAIL=admin@smartsoltech.kr
ADMIN_PASSWORD=change-this-password

# Security Headers
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
`.trim();

        fs.writeFileSync(path.join(BUILD_DIR, '.env.production'), prodEnv);
        console.log('✅ Production environment file created');
    } catch (error) {
        console.error('❌ Error creating production environment:', error);
        throw error;
    }
}

async function copyProductionFiles() {
    try {
        console.log('📋 Copying production files...');
        
        // Copy main application files
        const filesToCopy = [
            'server.js',
            'package.json',
            'package-lock.json'
        ];
        
        for (const file of filesToCopy) {
            fs.copyFileSync(
                path.join(__dirname, '..', file),
                path.join(BUILD_DIR, file)
            );
        }
        
        // Copy directories
        await copyDirectory(
            path.join(__dirname, '..', 'models'),
            path.join(BUILD_DIR, 'models')
        );
        
        await copyDirectory(
            path.join(__dirname, '..', 'routes'),
            path.join(BUILD_DIR, 'routes')
        );
        
        await copyDirectory(
            path.join(__dirname, '..', 'views'),
            path.join(BUILD_DIR, 'views')
        );
        
        await copyDirectory(
            path.join(__dirname, '..', 'middleware'),
            path.join(BUILD_DIR, 'middleware')
        );
        
        // Create uploads directory
        fs.mkdirSync(path.join(BUILD_DIR, 'uploads'), { recursive: true });
        
        console.log('✅ Production files copied');
    } catch (error) {
        console.error('❌ Error copying production files:', error);
        throw error;
    }
}

async function copyDirectory(src, dest) {
    try {
        if (!fs.existsSync(src)) {
            return;
        }
        
        fs.mkdirSync(dest, { recursive: true });
        
        const items = fs.readdirSync(src);
        
        for (const item of items) {
            const srcPath = path.join(src, item);
            const destPath = path.join(dest, item);
            
            const stat = fs.statSync(srcPath);
            
            if (stat.isDirectory()) {
                await copyDirectory(srcPath, destPath);
            } else {
                fs.copyFileSync(srcPath, destPath);
            }
        }
    } catch (error) {
        console.error(`❌ Error copying directory ${src}:`, error);
        throw error;
    }
}

if (require.main === module) {
    buildForProduction();
}

module.exports = { buildForProduction };