'use strict';
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { Controller } from '@hotwired/stimulus';
// @ts-ignore
import { getComponent } from '@symfony/ux-live-component';
const RETURNING_KEY = 'ferienpass.returningUser';
const METHOD_KEY = 'ferienpass.lastLoginMethod';
export default class default_1 extends Controller {
    constructor() {
        super(...arguments);
        this.view = 'magic';
        this.pwVisible = false;
        this.magicSent = false;
    }
    initialize() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!(this.element instanceof HTMLElement)) {
                return;
            }
            try {
                this.component = yield getComponent(this.element);
                // Re-apply the client-side state after every server re-render.
                this.component.on('render:finished', () => this.applyState());
            }
            catch (e) {
                // Not (yet) a live component — state is still managed locally.
            }
        });
    }
    connect() {
        let last = null;
        try {
            last = localStorage.getItem(METHOD_KEY);
        }
        catch (e) {
        }
        this.view = 'password' === last ? 'password' : ('passkey' === last ? 'passkeyOnly' : 'magic');
        this.applyState();
    }
    revealPassword() {
        this.view = 'password';
        this.applyState();
        if (this.hasPasswordTarget) {
            this.passwordTarget.focus();
        }
    }
    revealEmail() {
        this.view = 'magic';
        this.applyState();
        this.usernameTarget.focus();
    }
    togglePassword() {
        this.pwVisible = !this.pwVisible;
        this.applyState();
    }
    enterEmail(event) {
        // In the passwordless views, Enter sends the magic link instead of
        // submitting the (hidden) password form.
        if ('password' !== this.view) {
            event.preventDefault();
            this.sendMagicLink();
        }
    }
    // Magic-link can only be requested once an e-mail address is present.
    syncMagic() {
        const hasEmail = !!this.usernameTarget.value.trim();
        this.magicButtonTargets.forEach((b) => {
            b.disabled = !hasEmail;
        });
    }
    isValidEmail() {
        const value = this.usernameTarget.value.trim();
        return value.length > 0 && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
    }
    // Blur handler: flag a non-empty but malformed address.
    validateEmail() {
        this.setEmailError(this.usernameTarget.value.trim().length > 0 && !this.isValidEmail());
    }
    // Input handler: keep the magic button in sync and clear the error as soon
    // as the address becomes valid (without nagging mid-typing).
    emailInput() {
        this.syncMagic();
        if (this.isValidEmail()) {
            this.setEmailError(false);
        }
    }
    setEmailError(hasError) {
        ['border-red-500', 'ring-4', 'ring-red-500/30'].forEach((c) => this.usernameTarget.classList.toggle(c, hasError));
        this.usernameTarget.setAttribute('aria-invalid', hasError ? 'true' : 'false');
    }
    sendMagicLink() {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate client-side to avoid a needless POST for an invalid address.
            if (!this.isValidEmail()) {
                this.validateEmail();
                this.usernameTarget.focus();
                return;
            }
            const email = this.usernameTarget.value.trim();
            if (this.hasSentEmailTarget) {
                this.sentEmailTarget.textContent = email;
            }
            if (this.magicUrlValue) {
                try {
                    yield fetch(this.magicUrlValue, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
                        body: JSON.stringify({ email }),
                    });
                }
                catch (e) {
                }
            }
            // Remember the magic link as the last method so it is offered first
            // next time. No name or e-mail is stored.
            try {
                localStorage.setItem(RETURNING_KEY, '1');
                localStorage.setItem(METHOD_KEY, 'magicLink');
            }
            catch (e) {
            }
            this.magicSent = true;
            this.applyState();
        });
    }
    // Go back from the "link sent" state to the form to try another address.
    tryOtherEmail() {
        this.magicSent = false;
        this.applyState();
        this.usernameTarget.focus();
        this.usernameTarget.select();
    }
    applyState() {
        const sent = this.magicSent;
        this.toggle(this.hasEmailBlockTarget, this.hasEmailBlockTarget ? this.emailBlockTarget : null, !sent && 'passkeyOnly' !== this.view);
        this.toggle(this.hasMagicActionsTarget, this.hasMagicActionsTarget ? this.magicActionsTarget : null, !sent && 'magic' === this.view);
        this.toggle(this.hasPasswordBlockTarget, this.hasPasswordBlockTarget ? this.passwordBlockTarget : null, !sent && 'password' === this.view);
        this.toggle(this.hasSecondaryTarget, this.hasSecondaryTarget ? this.secondaryTarget : null, !sent && 'passkeyOnly' === this.view);
        this.toggle(this.hasMagicSentTarget, this.hasMagicSentTarget ? this.magicSentTarget : null, sent);
        if (this.hasPasswordTarget) {
            this.passwordTarget.type = this.pwVisible ? 'text' : 'password';
        }
        this.toggle(this.hasPasswordEyeTarget, this.hasPasswordEyeTarget ? this.passwordEyeTarget : null, !this.pwVisible);
        this.toggle(this.hasPasswordEyeOffTarget, this.hasPasswordEyeOffTarget ? this.passwordEyeOffTarget : null, this.pwVisible);
        this.syncMagic();
    }
    toggle(has, el, visible) {
        if (has && el) {
            // Inline style always wins over class-based display utilities
            // (avoids `hidden` losing to `inline-flex`/`grid`). Empty string
            // falls back to the element's class-defined display.
            el.style.display = visible ? '' : 'none';
        }
    }
    submit(event) {
        return __awaiter(this, void 0, void 0, function* () {
            // Validate the e-mail client-side to avoid a needless POST.
            if (!this.isValidEmail()) {
                this.validateEmail();
                this.usernameTarget.focus();
                return;
            }
            const response = yield fetch('/check_login', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
                body: JSON.stringify({
                    username: this.usernameTarget.value,
                    password: this.passwordTarget.value,
                    REQUEST_TOKEN: this.requestTokenValue
                })
            });
            const json = yield response.json();
            if ("redirect_to" in json) {
                window.location.href = json.redirect_to;
                return;
            }
            if (!("user" in json)) {
                this.errorTarget.classList.remove('hidden');
            }
            else {
                this.errorTarget.classList.add('hidden');
                // Remember the visitor + that the last successful method was a
                // password, so the password form is shown upfront next time. No
                // name or e-mail is stored.
                try {
                    localStorage.setItem(RETURNING_KEY, '1');
                    localStorage.setItem(METHOD_KEY, 'password');
                }
                catch (e) {
                }
                if (this.targetPathValue) {
                    window.location.href = this.targetPathValue;
                }
            }
        });
    }
}
default_1.values = {
    requestToken: String,
    targetPath: String,
    magicUrl: String,
};
default_1.targets = [
    "error", "username", "password", "remember_me",
    "emailBlock", "magicActions", "magicSent", "passwordBlock",
    "secondary", "passwordEye", "passwordEyeOff", "magicButton", "sentEmail",
];
