import { Controller } from '@hotwired/stimulus';

/* Connexion en 3 étapes : email → code OTP → concessions. Port de auth/login/page.tsx. */
export default class extends Controller {
    static targets = [
        'bar2',
        'emailStep', 'codeStep',
        'emailInput', 'emailError', 'emailErrorText', 'emailSubmit',
        'code', 'codeError', 'codeErrorText', 'codeSubmit', 'emailDisplay', 'resend',
    ];

    connect() {
        this.email = '';
        this.countdown = 0;
    }

    // ─── Étape 1 : email ───
    async sendCode(event) {
        event.preventDefault();
        this.email = this.emailInputTarget.value.trim();
        if (!this.email) return;

        this.hide(this.emailErrorTarget);
        this.setLoading(this.emailSubmitTarget, true, 'Envoi en cours…');
        try {
            const res = await fetch('/api/auth/send-code', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email: this.email }),
            });
            const data = await res.json().catch(() => ({}));
            if (!res.ok) {
                this.showEmailError(data.error || 'Une erreur est survenue');
                return;
            }
            this.goToCode();
        } catch {
            this.showEmailError('Erreur réseau. Vérifiez votre connexion.');
        } finally {
            this.setLoading(this.emailSubmitTarget, false, 'Recevoir le code par email');
        }
    }

    goToCode() {
        this.hide(this.emailStepTarget);
        this.show(this.codeStepTarget);
        this.activateBar(this.bar2Target);
        this.emailDisplayTarget.textContent = this.email;
        this.clearCode();
        this.startCountdown(60);
        setTimeout(() => this.codeTargets[0]?.focus(), 50);
    }

    backToEmail() {
        this.show(this.emailStepTarget);
        this.hide(this.codeStepTarget);
        this.deactivateBar(this.bar2Target);
        this.clearCode();
        this.hide(this.codeErrorTarget);
        this.stopCountdown();
    }

    // ─── Étape 2 : code ───
    verifyForm(event) {
        event.preventDefault();
        this.verify();
    }

    async verify(forcedCode) {
        const code = forcedCode || this.codeTargets.map((i) => i.value).join('');
        if (code.length !== 6) {
            this.showCodeError('Entrez les 6 chiffres du code');
            return;
        }
        this.hide(this.codeErrorTarget);
        this.setLoading(this.codeSubmitTarget, true, 'Vérification…');
        try {
            const res = await fetch('/api/auth/verify', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email: this.email, code }),
            });
            const data = await res.json().catch(() => ({}));
            if (!res.ok) {
                this.showCodeError(data.error || 'Code invalide');
                this.clearCode();
                setTimeout(() => this.codeTargets[0]?.focus(), 50);
                return;
            }
            // Connecté → direct à l'accueil. Le choix des concessions se fait sur la page Scan.
            this.stopCountdown();
            window.location.href = '/';
        } catch {
            this.showCodeError('Erreur réseau. Vérifiez votre connexion.');
        } finally {
            this.setLoading(this.codeSubmitTarget, false, 'Se connecter');
        }
    }

    onCodeInput(event) {
        const idx = this.codeTargets.indexOf(event.target);
        const digit = event.target.value.replace(/\D/g, '').slice(-1);
        event.target.value = digit;
        this.hide(this.codeErrorTarget);
        if (digit && idx < 5) this.codeTargets[idx + 1].focus();
        if (digit && idx === 5) {
            const full = this.codeTargets.map((i) => i.value).join('');
            if (full.length === 6) this.verify(full);
        }
    }

    onCodeKeydown(event) {
        const idx = this.codeTargets.indexOf(event.target);
        if (event.key === 'Backspace' && !event.target.value && idx > 0) {
            this.codeTargets[idx - 1].focus();
        } else if (event.key === 'ArrowLeft' && idx > 0) {
            this.codeTargets[idx - 1].focus();
        } else if (event.key === 'ArrowRight' && idx < 5) {
            this.codeTargets[idx + 1].focus();
        }
    }

    onCodePaste(event) {
        event.preventDefault();
        const pasted = (event.clipboardData.getData('text') || '').replace(/\D/g, '').slice(0, 6);
        if (!pasted) return;
        this.codeTargets.forEach((input, i) => { input.value = pasted[i] || ''; });
        const next = Math.min(pasted.length, 5);
        this.codeTargets[next].focus();
        if (pasted.length === 6) this.verify(pasted);
    }

    async resend() {
        if (this.countdown > 0) return;
        this.clearCode();
        this.hide(this.codeErrorTarget);
        try {
            const res = await fetch('/api/auth/send-code', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ email: this.email }),
            });
            const data = await res.json().catch(() => ({}));
            if (!res.ok) {
                this.showCodeError(data.error || 'Erreur lors du renvoi');
                return;
            }
            this.startCountdown(60);
            setTimeout(() => this.codeTargets[0]?.focus(), 50);
        } catch {
            this.showCodeError('Erreur réseau.');
        }
    }

    // ─── Countdown ───
    startCountdown(seconds) {
        this.countdown = seconds;
        this.updateResend();
        this.stopCountdown();
        this.countdownTimer = setInterval(() => {
            this.countdown -= 1;
            if (this.countdown <= 0) this.stopCountdown();
            this.updateResend();
        }, 1000);
    }

    stopCountdown() {
        if (this.countdownTimer) clearInterval(this.countdownTimer);
        this.countdownTimer = null;
    }

    updateResend() {
        this.resendTarget.disabled = this.countdown > 0;
        this.resendTarget.textContent = this.countdown > 0
            ? `Renvoyer dans ${this.countdown}s`
            : 'Renvoyer le code';
    }

    // ─── Helpers ───
    clearCode() {
        this.codeTargets.forEach((i) => { i.value = ''; });
    }

    clearError() {
        this.hide(this.emailErrorTarget);
    }

    showEmailError(msg) {
        this.emailErrorTextTarget.textContent = msg;
        this.show(this.emailErrorTarget, 'flex');
    }

    showCodeError(msg) {
        this.codeErrorTextTarget.textContent = msg;
        this.show(this.codeErrorTarget, 'flex');
    }

    setLoading(btn, loading, text) {
        btn.disabled = loading;
        btn.textContent = text;
    }

    show(el, display = 'block') {
        el.classList.remove('hidden');
        if (display === 'flex') el.classList.add('flex');
    }

    hide(el) {
        el.classList.add('hidden');
        el.classList.remove('flex');
    }

    activateBar(bar) {
        bar.classList.remove('bg-gray-200');
        bar.classList.add('bg-red-brand');
    }

    deactivateBar(bar) {
        bar.classList.add('bg-gray-200');
        bar.classList.remove('bg-red-brand');
    }
}
