import { NextResponse } from 'next/server';
import { query, execute } from '@/lib/db';
import { comparePassword } from '@/lib/auth';
import { sendOTPEmail } from '@/lib/email';

const MAX_LOGIN_ATTEMPTS = 5;
const LOCKOUT_MINUTES = 15;

export async function POST(request: Request) {
    try {
        let { email, password } = await request.json();

        if (!email || !password) {
            return NextResponse.json({ error: 'Email and password are required' }, { status: 400 });
        }

        email = email.trim();
        password = password.trim();

        // Find admin by email OR username
        let admins: any;
        try {
            admins = await query(
                'SELECT * FROM admins WHERE email = ? OR username = ?',
                [email, email]
            );
        } catch (err: any) {
            if (err.message?.includes('no such table') || err.message?.includes('SQLITE_ERROR')) {
                return NextResponse.json({ 
                    error: 'Admin database not initialized. Run `node setup_admin.js` from project root.' 
                }, { status: 503 });
            }
            throw err;
        }

        if (!admins || admins.length === 0) {
            // Log failed attempt for unknown email
            await logAuthAttempt(email, 'LOGIN_FAILED', 'Unknown admin email/username');
            return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 });
        }

        const admin = admins[0];

        // Check if admin is active
        if (admin.is_active === 0) {
            await logAuthAttempt(admin.email, 'LOGIN_BLOCKED', 'Account deactivated');
            return NextResponse.json({ error: 'Access revoked. Contact Super Admin.' }, { status: 403 });
        }

        // Check for lockout
        const lockoutCheck = await checkLockout(admin.email);
        if (lockoutCheck.locked) {
            await logAuthAttempt(admin.email, 'LOGIN_LOCKED', `Account locked for ${LOCKOUT_MINUTES} minutes`);
            return NextResponse.json({ 
                error: `Too many attempts. Try again in ${LOCKOUT_MINUTES} minutes.` 
            }, { status: 429 });
        }

        // Verify password
        const isValid = await comparePassword(password, admin.password_hash);
        if (!isValid) {
            // Increment failed attempts
            await incrementFailedAttempts(admin.email);
            await logAuthAttempt(admin.email, 'LOGIN_FAILED', 'Invalid password');
            return NextResponse.json({ error: 'Invalid credentials' }, { status: 401 });
        }

        // Clear failed attempts on successful password verification
        await clearFailedAttempts(admin.email);

        // Determine OTP email recipient: use otp_email if set, else fall back to email
        const otpEmail = admin.otp_email || admin.email;

        // Generate custom 6-character OTP (Letter, 3 Digits, Letter, Special Character)
        const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        const specials = '!@#$%^&*';
        const randomLetter = () => letters[Math.floor(Math.random() * letters.length)];
        const randomSpecial = () => specials[Math.floor(Math.random() * specials.length)];
        const randomDigit = () => Math.floor(Math.random() * 10).toString();

        const otpCode = `${randomLetter()}${randomDigit()}${randomDigit()}${randomDigit()}${randomLetter().toLowerCase()}${randomSpecial()}`;
        const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString();

        // Clear previous OTPs and save new one
        await execute('DELETE FROM admin_otps WHERE admin_email = ?', [admin.email]);
        await execute(
            'INSERT INTO admin_otps (admin_email, code, expires_at) VALUES (?, ?, ?)',
            [admin.email, otpCode, expiresAt]
        );

        // Send OTP email (non-blocking)
        sendOTPEmail(otpEmail, otpCode).catch(err => {
            console.error('[OTP] Failed to send email:', err.message);
        });

        await logAuthAttempt(admin.email, 'OTP_SENT', 'OTP sent successfully');

        const isDev = process.env.NODE_ENV !== 'production';

        return NextResponse.json({
            message: 'OTP sent successfully',
            step: 'otp',
            identifier: admin.email,
            ...(isDev && { devOtp: otpCode }),
        });
    } catch (error: any) {
        console.error('[Admin Login Error]', error?.message ?? error);
        return NextResponse.json({ error: 'An internal server error occurred' }, { status: 500 });
    }
}

async function logAuthAttempt(email: string, actionType: string, metadata: string) {
    try {
        await execute(
            'INSERT INTO UserAction (id, userId, actionType, entityType, metadata) VALUES (?, ?, ?, ?, ?)',
            [
                `auth_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
                email,
                actionType,
                'ADMIN_AUTH',
                metadata
            ]
        );
    } catch (err) {
        console.error('[Auth Audit] Failed to log:', err
