import * as authService from '../services/auth.service.js';

// Ein Standard-Regulärer-Ausdruck (Regex) zur Prüfung eines gültigen E-Mail-Formats
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

/**
 * Controller-Methode für die Registierung-Route.
 */
export const register = async (req, res) => {
    try {
        // Daten aus dem Body extrahieren
        const { username, email, password } = req.body;

        // Basis-Validierung (leere Felder, Passwortlänge)
        if (!username || !email || !password) {
            return res.status(400).json({
                // ERR_MISSING_FIELDS: Bitte alle Felder ausfüllen.
                error: 'ERR_MISSING_FIELDS'
            });
        }
        if (password.length < 8) {
            return res.status(400).json({
                // ERR_PASSWORD_TOO_SHORT: Das Passwort muss mindestens 8 Zeichen lang sein.
                error: 'ERR_PASSWORD_TOO_SHORT'
            });
        }
        if (username.length < 3) {
            return res.status(400).json({
                // ERR_USERNAME_TOO_SHORT: Der Benutzername muss mindestens 3 Zeichen lang sein.
                error: 'ERR_USERNAME_TOO_SHORT'
            });
        }
        if (!EMAIL_REGEX.test(email)) {
            return res.status(400).json({
                /// ERR_INVALID_EMAIL: Das E-Mail-Format ist ungültig.
                error: 'ERR_INVALID_EMAIL'
            });
        }

        // Den Auth-Service aufrufen (die eigenliche Arbeit)
        const result = await authService.registerUser(username, email, password);

        // Erfolgreiche Antwort an der Frontend senden
        return res.status(201).json({
            success: true,
            // MSG_REGISTER_SUCCESS: Registrierung erfolgreich. Bitte prüfe deine E-Mails.
            message: 'MSG_REGISTER_SUCCESS',
            accountId: result.accountId
        });

    } catch (error) {
        // Fehlerbehandlung: Wenn es unser eigener Conflict-Fehler ist (zB Email existiert)
        if (error.code === 'ERR_USERNAME_TAKEN') {
            return res.status(409).json({
                // ERR_USERNAME_TAKEN: Dieser Benutzername ist bereits vergeben.
                error: 'ERR_USERNAME_TAKEN'
            });
        }
        if (error.code === 'ERR_EMAIL_TAKEN') {
            return res.status(409).json({
                // ERR_USERNAME_TAKEN: Diese E-Mail-Addresse ist bereits vergeben.
                error: 'ERR_EMAIL_TAKEN'
            });
        }

        // Bei unerwarteten Fehlern (z.B. Datenbank oder Brovo nicht erreichbar.)
        console.error('[AuthController] Fehler bei der Registierung:', error);
        return res.status(500).json({
            // ERR_INTERNAL_SERVER: Ein interner Serverfehler ist aufgetreten.
            error: 'ERR_INTERNAL_SERVER'
        });
    }
};

/**
 * Controller-Methode für die E-Mail-Verifizierungs-Route
 */
export const verifyEmail = async (req, res) => {
    try {
        // Daten aus dem Request-Body extrahieren
        const { email , otpCode } = req.body;

        // Vasis-Validierung
        if (!email || !otpCode) {
            return res.status(400).json({
                error: 'ERR_MISSING_FIELDS'
            });
        }

        // Den Service aufrufen, um die eigenliche Arbeit zu machen
        await authService.verifyEmail(email, otpCode);

        // Erfolgreiche Antwort ans Frontend senden
        return res.status(200).json({
            success: true,
            message: 'MSG_EMAIL_VERIFIED'
        });

    } catch (error) {
        if (['ERR_USER_NOT_FOUND', 'ERR_ALREADY_VERIFIED', 'ERR_INVALID_OTP', 'ERR_OTP_EXPIRED'].includes(error.code)) {

            return res.status(400).json({
                error: error.code
            });
        }

        console.error('[AuthController] Fehler bei E-Mail-Verifizierung:', error);
        return res.status(500).json({
            error: 'ERR_INTERNAL_SERVER'
        });
    }
};

/**
 * Controller-Methode für die Login-Route
 */
export const login = async (req, res) => {
    try {
        const { identifier, password } = req.body;

        // Basis-Validierung
        if (!identifier || !password) {
            return res.status(400).json({
                error: 'ERR_MISSING_FIELDS'
            });
        }

        // Service aufrufen
        const result = await authService.loginUser(identifier, password);

        // Erfolgreiche Antwort mit den Tokens
        return res.status(200).json({
            success: true,
            // MSG_LOGIN_SUCCESS: Erfolgreich eingeloggt
            message: 'MSG_LOGIN_SUCCESS',
            accessToken: result.accessToken,
            refreshToken: result.refreshToken,
            user: result.user
        });

    } catch (error) {
        if (error.code === 'ERR_INVALID_CREDENTIALS') {
            return res.status(401).json({
                error: 'ERR_INVALID_CREDENTIALS'
            });
        }
        if (error.code === 'ERR_EMAIL_NOT_VERIFIED') {
            return res.status(403).json({
                error: 'ERR_EMAIL_NOT_VERIFIED',
                email: error.email
            });
        }

        console.error('[AuthController] Fehler beim Login:', error);
        return res.status(500).json({
            error: 'ERR_INTERNAL_SERVER'
        });
    }
}

/**
 * Controller-Methode für die Token-Refresh-Route
 */
export const refresh = async (req, res) => {
    try {
        // Das Refresh-Token aus dem Request-Body holen
        const { refreshToken } = req.body;

        // Validierung: Is überhaupt ein Token mitgesendet worden ?
        if (!refreshToken) {
            // ERR_MISSING_TOKEN: Es wurde kein Refresh-Token übergeben
            return res.status(400).json({
                error: 'ERR_MISSING_TOKEN'
            });
        }

        // Den Service aufrufen, um das Token zu prüfen und ein neues zu generieren
        const result = await authService.refreshAccessToken(refreshToken);

        // Das neue Access-Token an das Frontend zurück geben
        return res.status(200).json({
            success: true,
            accessToken: result.accessToken,
            user: result.user
        });

    } catch (error) {
        // Ungültige, abgelaufene oder in der DB gelöschte Tokens abfangen
        if (error.code === 'ERR_UNAUTHORIZED') {
            return res.status(401).json({
                // ERR_UNAUTHORIZED: Zugriff verweigert. Die Sitzung ist ungültig.
                error: 'ERR_UNAUTHORIZED'
            });
        }

        // Bei unerwarteten Fehlern (z.B. Datenbank oder Brovo nicht erreichbar.)
        console.error('[AuthController] Fehler beim Token-Refresh:', error);
        return res.status(500).json({
            // ERR_INTERNAL_SERVER: Ein interner Serverfehler ist aufgetreten.
            error: 'ERR_INTERNAL_SERVER'
        });
    }
}

/**
 * Controller-Methode für die Resend-OTP-Route
 * Wird aufgerufen, wenn der Nutzer im Frontend auf "Code erneut senden" klickt
 */
export const resendOTP = async (req, res) => {
    try {
        const { email } = req.body;

        if (!email) {
            return res.status(400).json({
                error: 'ERR_MISSING_FIELDS'
            });
        }

        // Aufruf unseres Service
        await authService.resendOTP(email);

        return res.status(200).json({
            success: true,
            // MSG_OTP_RESENT: Ein neuer Code wurde an deine E-Mail gesendet.
            message: 'MSG_OTP_RESENT'
        });

    } catch (error) {
        if (['ERR_USER_NOT_FOUND', 'ERR_ALREADY_VERIFIED', 'ERR_COOLDOWN_ACTIVE'].includes(error.code)) {
            const statusCode = error.code === 'ERR_COOLDOWN_ACTIVE' ? 429 : 400;
            return res.status(statusCode).json({
                error: error.code
            });
        }

        console.error('[AuthController] Fehler beim erneuten Senden des OTP:', error);
        return res.status(500).json({
            error: 'ERR_INTERNAL_SERVER'
        });
    }
};

/**
 * Controller-Methode für die Passwort vergessen anfrage
 */
export const requestPasswordReset = async (req, res) => {
    try {
        const { email } = req.body;

        if (!email) {
            return res.status(400).json({
                error: 'ERR_MISSING_FIELDS'
            });
        }

        await authService.requestPasswordReset(email);

        // Auch wenn die E-Mail nicht existiert, geben wir oft ein Success zurück,
        // damit Angreifer nicht testen können, welche E-Mails registriert sind.
        // In unserem Service werfen wir aber ERR_USER_NOT_FOUND. Wir fangen das unten ab.
        return res.status(200).json({
            success: true,
            message: 'MSG_RESET_EMAIL_SENT' // Muss später ins i18n
        });

    } catch (error) {
        // Wenn der Nutzer nicht existiert, tun wir für das Frontend trotzdem so, als wäre
        // die E-Mail rausgegangen (Sicherheitsbest-Practice).
        if (error.code === 'ERR_USER_NOT_FOUND') {
            return res.status(200).json({
                success: true,
                message: 'MSG_RESET_EMAIL_SENT'
            });
        }

        if (error.code === 'ERR_COOLDOWN_ACTIVE') {
            return res.status(429).json({
                error: error.code
            });
        }

        console.error('[AuthController] Fehler bei requestPasswordReset:', error);
        return res.status(500).json({ error: 'ERR_INTERNAL_SERVER' });
    }
};

/**
 * Controller-Methode für das finale Setzen des neuen Passworts.
 */
export const resetPassword = async (req, res) => {
    try {
        const { email, otpCode, newPassword } = req.body;

        // Basis-Validierung
        if (!email || !otpCode || !newPassword) {
            return res.status(400).json({ error: 'ERR_MISSING_FIELDS' });
        }

        // Passwort-Richtlinie prüfen (wie bei der Registrierung)
        if (newPassword.length < 8) {
            return res.status(400).json({ error: 'ERR_PASSWORD_TOO_SHORT' });
        }

        // Service aufrufen
        await authService.resetPassword(email, otpCode, newPassword);

        return res.status(200).json({
            success: true,
            message: 'MSG_PASSWORD_RESET_SUCCESS' // Muss später ins i18n
        });

    } catch (error) {
        if (['ERR_USER_NOT_FOUND', 'ERR_INVALID_OTP', 'ERR_OTP_EXPIRED'].includes(error.code)) {
            return res.status(400).json({ error: error.code });
        }

        console.error('[AuthController] Fehler bei resetPassword:', error);
        return res.status(500).json({ error: 'ERR_INTERNAL_SERVER' });
    }
};