// Lux Website - Interactive Features

(function() {
    'use strict';

    // Example code for each playground tab
    const examples = {
        hello: `fn main(): Unit with {Console} = {
    Console.print("Hello, Lux!")
}

run main() with {}`,

        effects: `// Effects are declared in the type signature
effect Logger {
    fn log(msg: String): Unit
}

fn greet(name: String): Unit with {Logger} = {
    Logger.log("Greeting " + name)
    Logger.log("Hello, " + name + "!")
}

// Run with a handler
run greet("World") with {
    Logger = fn log(msg) => print(msg)
}`,

        patterns: `type Shape =
    | Circle(Float)
    | Rectangle(Float, Float)
    | Triangle(Float, Float, Float)

fn area(s: Shape): Float =
    match s {
        Circle(r) => 3.14159 * r * r,
        Rectangle(w, h) => w * h,
        Triangle(a, b, c) => {
            let s = (a + b + c) / 2.0
            sqrt(s * (s - a) * (s - b) * (s - c))
        }
    }

let shapes = [Circle(5.0), Rectangle(3.0, 4.0)]
let areas = List.map(shapes, area)
// [78.54, 12.0]`,

        handlers: `effect Counter {
    fn increment(): Unit
    fn get(): Int
}

fn countToThree(): Int with {Counter} = {
    Counter.increment()
    Counter.increment()
    Counter.increment()
    Counter.get()
}

// Handler maintains state
handler counter: Counter {
    let state = ref 0
    fn increment() = {
        state := !state + 1
        resume(())
    }
    fn get() = resume(!state)
}

// Run with the counter handler
run countToThree() with { Counter = counter }
// Result: 3`,

        behavioral: `// Behavioral types provide compile-time guarantees

fn add(a: Int, b: Int): Int
    is pure           // No side effects
    is total          // Always terminates
    is commutative    // add(a,b) == add(b,a)
= {
    a + b
}

fn chargeCard(amount: Int, cardId: String): Receipt
    is idempotent     // Safe to retry
    with {Payment} = {
    Payment.charge(amount, cardId)
}

// The compiler verifies these properties!
// Retry is safe because chargeCard is idempotent
retry(3, || chargeCard(100, "card_123"))`
    };

    // Simulated outputs for examples
    const outputs = {
        hello: `Hello, Lux!`,

        effects: `[Logger] Greeting World
[Logger] Hello, World!`,

        patterns: `shapes = [Circle(5.0), Rectangle(3.0, 4.0)]
areas = [78.53975, 12.0]`,

        handlers: `Counter.increment() -> state = 1
Counter.increment() -> state = 2
Counter.increment() -> state = 3
Counter.get() -> 3

Result: 3`,

        behavioral: `Analyzing behavioral properties...

add:
  ✓ is pure (no effects in signature)
  ✓ is total (no recursion, no partial patterns)
  ✓ is commutative (verified by SMT solver)

chargeCard:
  ✓ is idempotent (Payment.charge is idempotent)

All behavioral properties verified!`
    };

    // Simple interpreter for basic expressions
    class LuxInterpreter {
        constructor() {
            this.env = new Map();
            this.output = [];
        }

        interpret(code) {
            this.output = [];
            this.env.clear();

            try {
                // Check for known examples
                const normalized = code.trim().replace(/\s+/g, ' ');
                for (const [key, example] of Object.entries(examples)) {
                    if (normalized === example.trim().replace(/\s+/g, ' ')) {
                        return outputs[key];
                    }
                }

                // Simple expression evaluation
                return this.evaluateSimple(code);
            } catch (e) {
                return `Error: ${e.message}`;
            }
        }

        evaluateSimple(code) {
            const lines = code.split('\n');
            const results = [];

            for (const line of lines) {
                const trimmed = line.trim();
                if (!trimmed || trimmed.startsWith('//')) continue;

                // let binding
                const letMatch = trimmed.match(/^let\s+(\w+)\s*=\s*(.+)$/);
                if (letMatch) {
                    const [, name, expr] = letMatch;
                    const value = this.evalExpr(expr);
                    this.env.set(name, value);
                    results.push(`${name} = ${this.formatValue(value)}`);
                    continue;
                }

                // Console.print
                const printMatch = trimmed.match(/Console\.print\((.+)\)/);
                if (printMatch) {
                    const value = this.evalExpr(printMatch[1]);
                    this.output.push(String(value).replace(/^"|"$/g, ''));
                    continue;
                }
            }

            if (this.output.length > 0) {
                return this.output.join('\n');
            }

            if (results.length > 0) {
                return results.join('\n');
            }

            if (code.includes('fn ') || code.includes('effect ') || code.includes('type ')) {
                return `// Code parsed successfully!
//
// To run locally:
//   lux run yourfile.lux`;
            }

            return '// No output';
        }

        evalExpr(expr) {
            expr = expr.trim();

            if (expr.startsWith('"') && expr.endsWith('"')) {
                return expr.slice(1, -1);
            }

            if (/^-?\d+(\.\d+)?$/.test(expr)) {
                return parseFloat(expr);
            }

            if (expr === 'true') return true;
            if (expr === 'false') return false;

            if (this.env.has(expr)) {
                return this.env.get(expr);
            }

            const arithMatch = expr.match(/^(.+?)\s*([\+\-\*\/])\s*(.+)$/);
            if (arithMatch) {
                const left = this.evalExpr(arithMatch[1]);
                const right = this.evalExpr(arithMatch[3]);
                switch (arithMatch[2]) {
                    case '+': return left + right;
                    case '-': return left - right;
                    case '*': return left * right;
                    case '/': return left / right;
                }
            }

            if (expr.startsWith('[') && expr.endsWith(']')) {
                const inner = expr.slice(1, -1);
                if (!inner.trim()) return [];
                return inner.split(',').map(item => this.evalExpr(item.trim()));
            }

            return expr;
        }

        formatValue(value) {
            if (Array.isArray(value)) {
                return '[' + value.map(v => this.formatValue(v)).join(', ') + ']';
            }
            if (typeof value === 'string') {
                return `"${value}"`;
            }
            return String(value);
        }
    }

    const interpreter = new LuxInterpreter();

    // DOM ready
    document.addEventListener('DOMContentLoaded', function() {
        // Mobile menu
        const mobileMenuBtn = document.getElementById('mobile-menu-btn');
        const navLinks = document.getElementById('nav-links');
        const menuIcon = document.getElementById('menu-icon');

        if (mobileMenuBtn && navLinks) {
            mobileMenuBtn.addEventListener('click', function() {
                navLinks.classList.toggle('open');
                menuIcon.innerHTML = navLinks.classList.contains('open') ? '&#10005;' : '&#9776;';
            });

            navLinks.querySelectorAll('a').forEach(function(link) {
                link.addEventListener('click', function() {
                    navLinks.classList.remove('open');
                    menuIcon.innerHTML = '&#9776;';
                });
            });
        }

        // Playground tabs
        const tabs = document.querySelectorAll('.playground-tab');
        const codeInput = document.getElementById('code-input');
        const codeOutput = document.getElementById('code-output');

        tabs.forEach(function(tab) {
            tab.addEventListener('click', function() {
                const tabName = tab.dataset.tab;

                tabs.forEach(function(t) { t.classList.remove('active'); });
                tab.classList.add('active');

                if (examples[tabName]) {
                    codeInput.value = examples[tabName];
                    codeOutput.innerHTML = '<span class="cm">// Click "Run" to execute</span>';
                }
            });
        });

        // Run button
        const runBtn = document.getElementById('run-btn');
        if (runBtn && codeInput && codeOutput) {
            runBtn.addEventListener('click', function() {
                const code = codeInput.value;
                runBtn.disabled = true;
                runBtn.textContent = 'Running...';

                setTimeout(function() {
                    const result = interpreter.interpret(code);
                    codeOutput.textContent = result;
                    runBtn.disabled = false;
                    runBtn.textContent = 'Run';
                }, 300);
            });
        }

        // Keyboard shortcut: Ctrl/Cmd + Enter to run
        if (codeInput) {
            codeInput.addEventListener('keydown', function(e) {
                if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                    e.preventDefault();
                    runBtn.click();
                }
            });
        }

        // Copy buttons
        document.querySelectorAll('.copy-btn').forEach(function(btn) {
            btn.addEventListener('click', async function() {
                const text = btn.dataset.copy;
                try {
                    await navigator.clipboard.writeText(text);
                    const original = btn.textContent;
                    btn.textContent = 'Copied!';
                    btn.classList.add('copied');
                    setTimeout(function() {
                        btn.textContent = original;
                        btn.classList.remove('copied');
                    }, 2000);
                } catch (e) {
                    console.error('Failed to copy:', e);
                }
            });
        });

        // Smooth scroll
        document.querySelectorAll('a[href^="#"]').forEach(function(anchor) {
            anchor.addEventListener('click', function(e) {
                e.preventDefault();
                const target = document.querySelector(this.getAttribute('href'));
                if (target) {
                    target.scrollIntoView({ behavior: 'smooth', block: 'start' });
                }
            });
        });
    });

    // Console message
    console.log('%c Lux ', 'background: #d4af37; color: #0a0a0a; font-size: 24px; padding: 10px; border-radius: 4px; font-weight: bold;');
    console.log('%cSide effects can\'t hide.', 'font-size: 14px; color: #d4af37;');
    console.log('%chttps://git.qrty.ink/blu/lux', 'font-size: 12px; color: #888;');
})();
