import './bootstrap';

import Chart from 'chart.js/auto';
import confetti from 'canvas-confetti';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

// ---------------------------------------------------------------- globals
window.Chart = Chart;
window.confetti = confetti;
window.gsap = gsap;

Chart.defaults.font.family = '"Plus Jakarta Sans", system-ui, sans-serif';
Chart.defaults.color = '#28366a';
Chart.defaults.borderColor = 'rgba(28, 43, 95, 0.08)';
Chart.defaults.plugins.tooltip.backgroundColor = '#15204a';
Chart.defaults.plugins.tooltip.padding = 12;
Chart.defaults.plugins.tooltip.cornerRadius = 12;
Chart.defaults.plugins.tooltip.titleFont = { weight: '700' };

window.brand = {
    navy: '#1c2b5f',
    navyLight: '#4b64ac',
    sky: '#58b9e6',
    skyDeep: '#2787b8',
    skySoft: '#b9e4f8',
    mist: '#eef1f9',
    kes: new Intl.NumberFormat('en-KE', { style: 'currency', currency: 'KES', maximumFractionDigits: 0 }),
    num: new Intl.NumberFormat('en-KE', { maximumFractionDigits: 0 }),
};

// ---------------------------------------------------------------- pan-African currency engine
// `factor` ≈ units per 1 KES — used ONLY to scale slider ranges and example
// amounts so each market sees realistic numbers. Not an FX service.
const MW_CURRENCIES = {
    KES: { name: 'Kenya', currency: 'Kenyan Shilling', locale: 'en-KE', factor: 1 },
    NGN: { name: 'Nigeria', currency: 'Nigerian Naira', locale: 'en-NG', factor: 12 },
    GHS: { name: 'Ghana', currency: 'Ghanaian Cedi', locale: 'en-GH', factor: 0.105 },
    ZAR: { name: 'South Africa', currency: 'South African Rand', locale: 'en-ZA', factor: 0.14 },
    TZS: { name: 'Tanzania', currency: 'Tanzanian Shilling', locale: 'sw-TZ', factor: 20 },
    UGX: { name: 'Uganda', currency: 'Ugandan Shilling', locale: 'en-UG', factor: 28 },
    USD: { name: 'Diaspora (USD)', currency: 'US Dollar', locale: 'en-US', factor: 0.0078 },
};

// Snap a scaled amount to a friendly round number (1 / 2 / 2.5 / 5 × 10^n)
function mwNice(value) {
    if (value <= 0) return 0;
    const power = Math.pow(10, Math.floor(Math.log10(value)));
    const unit = value / power;
    const snapped = unit < 1.5 ? 1 : unit < 2.25 ? 2 : unit < 3.5 ? 2.5 : unit < 7.5 ? 5 : 10;
    return snapped * power;
}

window.MW = {
    currencies: MW_CURRENCIES,

    code() {
        const saved = localStorage.getItem('mw-currency');
        return MW_CURRENCIES[saved] ? saved : 'USD'; // international default
    },

    setCurrency(code) {
        if (!MW_CURRENCIES[code]) return;
        localStorage.setItem('mw-currency', code);
        window.dispatchEvent(new CustomEvent('currency-changed', { detail: { code } }));
    },

    factor() {
        return MW_CURRENCIES[this.code()].factor;
    },

    fmt(value) {
        const code = this.code();
        const meta = MW_CURRENCIES[code];
        return new Intl.NumberFormat(meta.locale, {
            style: 'currency',
            currency: code,
            maximumFractionDigits: 0,
        }).format(Math.max(0, Math.round(value)));
    },

    // Scale a KES-baseline amount into the active currency, rounded friendly.
    scale(baseKes) {
        return mwNice(baseKes * this.factor());
    },

    // Exact (non-snapped) scaling for slider steps and small numbers.
    scaleExact(baseKes) {
        return baseKes * this.factor();
    },
};

const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

// ---------------------------------------------------------------- GSAP page engine
function initAnimations() {
    if (reducedMotion) {
        document.querySelectorAll('[data-gsap]').forEach((el) => el.style.opacity = 1);
        return;
    }

    // Entrance reveals: data-gsap="fade-up | fade-down | fade-left | fade-right | zoom | blur"
    const variants = {
        'fade-up': { y: 48, opacity: 0 },
        'fade-down': { y: -48, opacity: 0 },
        'fade-left': { x: 56, opacity: 0 },
        'fade-right': { x: -56, opacity: 0 },
        'zoom': { scale: 0.88, opacity: 0 },
        'blur': { opacity: 0, filter: 'blur(10px)' },
    };

    document.querySelectorAll('[data-gsap]:not([data-gsap-done])').forEach((el) => {
        el.setAttribute('data-gsap-done', '');
        const from = variants[el.dataset.gsap] ?? variants['fade-up'];
        const delay = parseFloat(el.dataset.gsapDelay ?? 0);

        gsap.from(el, {
            ...from,
            duration: 0.9,
            delay,
            ease: 'power3.out',
            clearProps: 'all',
            scrollTrigger: { trigger: el, start: 'top 88%', once: true },
        });
    });

    // Stagger groups: <div data-gsap-stagger> ... children animate in sequence
    document.querySelectorAll('[data-gsap-stagger]:not([data-gsap-done])').forEach((group) => {
        group.setAttribute('data-gsap-done', '');
        gsap.from(group.children, {
            y: 44,
            opacity: 0,
            duration: 0.8,
            ease: 'power3.out',
            stagger: 0.1,
            clearProps: 'all',
            scrollTrigger: { trigger: group, start: 'top 85%', once: true },
        });
    });

    // Parallax: data-parallax="0.2" (positive = slower/background)
    document.querySelectorAll('[data-parallax]:not([data-gsap-done])').forEach((el) => {
        el.setAttribute('data-gsap-done', '');
        const speed = parseFloat(el.dataset.parallax || 0.2);
        gsap.to(el, {
            yPercent: speed * 100,
            ease: 'none',
            scrollTrigger: { trigger: el.parentElement, start: 'top bottom', end: 'bottom top', scrub: 0.6 },
        });
    });

    // Counters: <span data-countup="1500" data-suffix="+">
    document.querySelectorAll('[data-countup]:not([data-gsap-done])').forEach((el) => {
        el.setAttribute('data-gsap-done', '');
        const target = parseFloat(el.dataset.countup);
        const suffix = el.dataset.suffix ?? '';
        const prefix = el.dataset.prefix ?? '';
        const counter = { value: 0 };

        ScrollTrigger.create({
            trigger: el,
            start: 'top 90%',
            once: true,
            onEnter: () =>
                gsap.to(counter, {
                    value: target,
                    duration: 1.8,
                    ease: 'power2.out',
                    onUpdate: () => (el.textContent = prefix + window.brand.num.format(Math.round(counter.value)) + suffix),
                }),
        });
    });

    // Hero timelines: [data-hero] containers stagger their [data-hero-item] children on load
    document.querySelectorAll('[data-hero]:not([data-gsap-done])').forEach((hero) => {
        hero.setAttribute('data-gsap-done', '');
        gsap.from(hero.querySelectorAll('[data-hero-item]'), {
            y: 36,
            opacity: 0,
            duration: 1,
            ease: 'power3.out',
            stagger: 0.12,
            clearProps: 'all',
            delay: 0.1,
        });
    });

    // 3D tilt cards: [data-tilt]
    document.querySelectorAll('[data-tilt]:not([data-tilt-done])').forEach((card) => {
        card.setAttribute('data-tilt-done', '');
        const strength = parseFloat(card.dataset.tilt || 8);

        card.addEventListener('mousemove', (e) => {
            const r = card.getBoundingClientRect();
            const px = (e.clientX - r.left) / r.width - 0.5;
            const py = (e.clientY - r.top) / r.height - 0.5;
            gsap.to(card, { rotateY: px * strength, rotateX: -py * strength, transformPerspective: 900, duration: 0.4, ease: 'power2.out' });
        });
        card.addEventListener('mouseleave', () => gsap.to(card, { rotateX: 0, rotateY: 0, duration: 0.6, ease: 'elastic.out(1, 0.5)' }));
    });

    // Floating accents: [data-float] gentle infinite drift
    document.querySelectorAll('[data-float]:not([data-gsap-done])').forEach((el, i) => {
        el.setAttribute('data-gsap-done', '');
        gsap.to(el, {
            y: '-=14',
            duration: 2.6 + (i % 3) * 0.5,
            yoyo: true,
            repeat: -1,
            ease: 'sine.inOut',
            delay: i * 0.3,
        });
    });

    // Progress bars: [data-grow-width="72"] animates width % on scroll
    document.querySelectorAll('[data-grow-width]:not([data-gsap-done])').forEach((el) => {
        el.setAttribute('data-gsap-done', '');
        gsap.fromTo(el, { width: '0%' }, {
            width: el.dataset.growWidth + '%',
            duration: 1.3,
            ease: 'power3.out',
            scrollTrigger: { trigger: el, start: 'top 92%', once: true },
        });
    });

    ScrollTrigger.refresh();
}

document.addEventListener('DOMContentLoaded', initAnimations);
document.addEventListener('livewire:navigated', () => setTimeout(initAnimations, 50));

// Re-scan after Livewire DOM morphs (assessment steps etc.)
document.addEventListener('livewire:init', () => {
    if (window.Livewire) {
        Livewire.hook('morphed', () => setTimeout(initAnimations, 30));
    }
});

// Capture the first visible Chart.js chart on the page as a white-backed PNG data URL,
// so the on-screen visual can be embedded in the dompdf report (which can't run JS).
function captureChartImage() {
    try {
        for (const canvas of document.querySelectorAll('canvas')) {
            const chart = window.Chart?.getChart?.(canvas);
            if (chart && canvas.offsetParent !== null && canvas.width > 0) {
                const tmp = document.createElement('canvas');
                tmp.width = canvas.width;
                tmp.height = canvas.height;
                const ctx = tmp.getContext('2d');
                ctx.fillStyle = '#ffffff';
                ctx.fillRect(0, 0, tmp.width, tmp.height);
                ctx.drawImage(canvas, 0, 0);
                return tmp.toDataURL('image/png');
            }
        }
    } catch (e) { /* charts are a nice-to-have in the PDF */ }
    return null;
}

// ---------------------------------------------------------------- PDF report download
window.downloadToolPdf = async (tool, payload) => {
    const chart = captureChartImage();
    const res = await fetch(`/tools/${tool}/pdf`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content,
        },
        body: JSON.stringify({ currency: window.MW.code(), chart, ...payload }),
    });

    if (!res.ok) return false;

    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `moneywise-${tool}-report.pdf`;
    a.click();
    URL.revokeObjectURL(url);
    return true;
};

// ---------------------------------------------------------------- cursor spotlight (.card-glow)
document.addEventListener('pointermove', (e) => {
    const card = e.target.closest?.('.card-glow');
    if (!card) return;
    const r = card.getBoundingClientRect();
    card.style.setProperty('--mx', ((e.clientX - r.left) / r.width) * 100 + '%');
    card.style.setProperty('--my', ((e.clientY - r.top) / r.height) * 100 + '%');
}, { passive: true });

// ---------------------------------------------------------------- celebration
window.celebrate = () => {
    const colors = ['#58b9e6', '#1c2b5f', '#b9e4f8', '#ffffff'];
    confetti({ particleCount: 90, spread: 75, origin: { y: 0.6 }, colors });
    setTimeout(() => confetti({ particleCount: 50, angle: 60, spread: 60, origin: { x: 0 }, colors }), 180);
    setTimeout(() => confetti({ particleCount: 50, angle: 120, spread: 60, origin: { x: 1 }, colors }), 320);
};

document.addEventListener('celebrate', () => window.celebrate());
