/**
 * modules/auth/login.js — Orquestador de métodos de entrada.
 */
(function (g) {
    g.modules = g.modules || {};
    g.modules.auth = g.modules.auth || {};

    var crypto = g.modules.core.crypto;
    var store = g.modules.users.userStore;
    var pinMod = g.modules.auth.pinLogin;
    var pattern = g.modules.auth.patternLogin;
    var bio = g.modules.auth.biometricLogin;
    var sel = g.modules.auth.loginTypeSelector;

    async function verifyPassword(user, password) {
        var h = await crypto.hashSecret(String(password || ''), user.passwordSalt);
        return crypto.timingSafeEqualB64(h, user.passwordHash);
    }

    g.modules.auth.login = {
        verifyPassword: verifyPassword,

        /** Intenta login según identifier (email o teléfono) + método. */
        attempt: async function (opts) {
            var identifier = String(opts.identifier || '').trim();
            var method = sel.normalize(opts.method || 'password');
            var user = identifier.indexOf('@') >= 0
                ? await store.findByEmail(identifier)
                : await store.findByPhone(identifier);
            if (!user) return { ok: false, code: 'user_not_found' };

            if (method === 'password') {
                var ok = await verifyPassword(user, opts.password || '');
                return ok ? { ok: true, user: user } : { ok: false, code: 'bad_credentials' };
            }
            if (method === 'pin') {
                var pok = await pinMod.verify(user, opts.pin || '');
                return pok ? { ok: true, user: user } : { ok: false, code: 'bad_credentials' };
            }
            if (method === 'pattern') {
                var y = await pattern.verify(user, opts.patternSeq || '');
                return y ? { ok: true, user: user } : { ok: false, code: 'bad_credentials' };
            }
            if (method === 'webauthn') {
                try {
                    await bio.authenticate(user);
                    return { ok: true, user: user };
                } catch (e) {
                    return { ok: false, code: e && e.message === 'cancelled' ? 'cancelled' : 'webauthn_failed' };
                }
            }
            return { ok: false, code: 'unknown_method' };
        },

        /** Respeta preferencia guardada si opts.usePreferred. */
        attemptPreferred: async function (identifier, secrets) {
            var identifierTrim = String(identifier || '').trim();
            var user = identifierTrim.indexOf('@') >= 0
                ? await store.findByEmail(identifierTrim)
                : await store.findByPhone(identifierTrim);
            if (!user) return { ok: false, code: 'user_not_found' };
            var method = sel.normalize(user.metadata && user.metadata.loginType);
            return await this.attempt(Object.assign({ identifier: identifierTrim, method: method }, secrets || {}));
        },
    };
})(typeof window !== 'undefined' ? window : this);
