<?php
require_once 'config.php';

// Check if already logged in. If so, redirect to dashboard.
if (is_logged_in()) {
    redirect('/dashboard');
}

// Set default action and sanitize user input
$action = $_GET['action'] ?? 'login';
$action = strtolower($action);

// Flash message storage (simple implementation)
$errors = $_SESSION['errors'] ?? [];
$success_message = $_SESSION['success_message'] ?? null;
unset($_SESSION['errors'], $_SESSION['success_message']);

$email = $_POST['email'] ?? '';
$full_name = $_POST['full_name'] ?? '';

// --- ACTION HANDLER ---

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    // 1. CSRF Token Validation
    if (!validate_csrf_token($_POST['csrf_token'] ?? '')) {
        $errors['csrf'] = 'Invalid request token. Please refresh and try again.';
        goto render_form; // Skip further processing if CSRF fails
    }

    if ($action === 'signup') {
        // --- SIGNUP LOGIC (3.1) ---
        
        $password = $_POST['password'] ?? '';
        $confirm_password = $_POST['confirm_password'] ?? '';
        $tnc_agreed = $_POST['tnc'] ?? 0;

        // Basic Validation
        if (empty($full_name) || empty($email) || empty($password) || empty($confirm_password)) {
            $errors['form'] = 'All fields are required.';
        } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Invalid email format.';
        } elseif ($password !== $confirm_password) {
            $errors['password'] = 'Passwords do not match.';
        } elseif (strlen($password) < 8) {
            $errors['password'] = 'Password must be at least 8 characters.';
        } elseif (!$tnc_agreed) {
            $errors['tnc'] = 'You must agree to the Terms & Conditions.';
        }

        if (empty($errors)) {
            // Check if email already exists
            $stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
            $stmt->execute([$email]);
            if ($stmt->fetch()) {
                $errors['email'] = 'This email is already registered.';
            }
        }
        
        if (empty($errors)) {
            try {
                // 1. Create User
                $now = date('Y-m-d H:i:s');
                $password_hash = password_hash($password, PASSWORD_DEFAULT); // Uses BCRYPT/ARGON2
                
                $stmt = $pdo->prepare("INSERT INTO users (email, password_hash, name, role, is_active, created_at, updated_at) 
                                       VALUES (?, ?, ?, 'user', 1, ?, ?)");
                $stmt->execute([$email, $password_hash, $full_name, $now, $now]);
                $user_id = $pdo->lastInsertId();

                // 2. Session setup (Prepares for OTP verification)
                // We set a temporary session ID to identify the user for OTP only
                session_regenerate_id(true);
                $_SESSION['temp_otp_user_id'] = $user_id;
                $_SESSION['temp_otp_email'] = $email;

                // 3. Generate and Send OTP (Will be handled by separate function/redirect)
                // Redirect to OTP verification page/action
                $_SESSION['success_message'] = "Account created! Please check your email for the verification code.";
                redirect('/auth.php?action=otp_send'); // Redirect to send OTP and show form

            } catch (PDOException $e) {
                // Log detailed error in development
                error_log("Signup error: " . $e->getMessage());
                $errors['database'] = 'A server error occurred during registration.';
            }
        }

    } elseif ($action === 'login') {
        // --- LOGIN LOGIC (3.2 - Phase 1: Email/Password Check) ---

        $password = $_POST['password'] ?? '';
        $remember_device = isset($_POST['remember_device']) ? 1 : 0;

        // Rate Limit Check (Key: login_email, Identifier: IP address)
        $client_ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
        if (!rate_limit('login', $client_ip, RATE_LIMIT_LOGIN, RATE_LIMIT_LOGIN_PERIOD)) {
            $errors['rate'] = 'Too many login attempts. Please wait 10 minutes.';
            goto render_form;
        }

        try {
            // 1. Fetch User
            $stmt = $pdo->prepare("SELECT id, password_hash, role, is_active FROM users WHERE email = ?");
            $stmt->execute([$email]);
            $user = $stmt->fetch();

            if (!$user || !password_verify($password, $user['password_hash'])) {
                $errors['login'] = 'Invalid email or password.';
            } elseif (!$user['is_active']) {
                $errors['login'] = 'Your account is currently inactive. Please contact support.';
            }

            if (empty($errors)) {
                
                // 2. Check for "Remember Device" bypass
                if ($remember_device) {
                    // Generate a token, store the hash, and set a cookie.
                    $device_token = generate_secure_token(32);
                    $token_hash = hash('sha256', $device_token);
                    $expires_at = date('Y-m-d H:i:s', time() + (REMEMBER_DEVICE_DAYS * 86400));
                    $now = date('Y-m-d H:i:s');

                    $stmt = $pdo->prepare("INSERT INTO login_devices (user_id, device_token_hash, user_agent, ip, created_at, last_used_at, expires_at)
                                           VALUES (?, ?, ?, ?, ?, ?, ?)");
                    $stmt->execute([$user['id'], $token_hash, $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown', $client_ip, $now, $now, $expires_at]);

                    setcookie('remember_device', $device_token, [
                        'expires' => time() + (REMEMBER_DEVICE_DAYS * 86400),
                        'path' => '/',
                        'domain' => '.' . parse_url(BASE_URL, PHP_URL_HOST),
                        'secure' => true,
                        'httponly' => true,
                        'samesite' => 'Lax'
                    ]);
                }

                // 3. Redirect to OTP or directly to dashboard based on remembered device (Simplified for now)
                // For a proper implementation: OTP is mandatory on first login/new device.
                
                // Redirect to mandatory OTP verification for security (3.2 - else block)
                session_regenerate_id(true);
                $_SESSION['temp_otp_user_id'] = $user['id'];
                $_SESSION['temp_otp_email'] = $email;
                $_SESSION['is_device_remembered'] = $remember_device; // Pass flag for next step

                redirect('/auth.php?action=otp_send');

            }

        } catch (PDOException $e) {
            error_log("Login error: " . $e->getMessage());
            $errors['database'] = 'A server error occurred during login.';
        }
    }
} 
// --- END POST HANDLER ---

// --- OTP LOGIC (SEPARATE GET/POST BLOCK) ---
// This handles sending the code and the verification form display/submit.

if ($action === 'otp_send') {
    // Phase 2: Send OTP code and show verification form
    
    $user_id = $_SESSION['temp_otp_user_id'] ?? null;
    $email = $_SESSION['temp_otp_email'] ?? null;

    if (!$user_id || !$email) {
        $_SESSION['errors']['session'] = 'Session expired. Please log in or sign up again.';
        redirect('/login');
    }

    $client_ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';

    // Rate Limit for OTP sending (Key: otp_send, Identifier: IP address)
    if (!rate_limit('otp_send', $client_ip, 3, 600)) { // 3 times per 10 minutes
        $errors['otp_rate'] = 'Maximum OTP resend attempts reached. Please wait.';
        $action = 'otp_verify'; // Stay on verification screen but block resend
        goto render_form;
    }

    try {
        // 1. Generate 6-digit OTP code
        $otp_code = random_int(100000, 999999);
        $expires_at = date('Y-m-d H:i:s', time() + (OTP_EXPIRY_MINS * 60));
        $now = date('Y-m-d H:i:s');
        $purpose = 'login';

        // 2. Save in otp_codes table
        $stmt = $pdo->prepare("INSERT INTO otp_codes (user_id, code, channel, purpose, expires_at, created_at, ip, user_agent) 
                               VALUES (?, ?, 'email', ?, ?, ?, ?, ?)");
        $stmt->execute([$user_id, $otp_code, $purpose, $expires_at, $now, $client_ip, $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown']);

        // 3. Send email with OTP code (HTML content is better)
        $subject = APP_NAME . ': Your One-Time Login Code is ' . $otp_code;
        $body = "
            <h2>Hello,</h2>
            <p>Your one-time code for **" . APP_NAME . "** is:</p>
            <p style='font-size: 24px; font-weight: bold; background: #f0f0f0; padding: 10px; display: inline-block;'>" . $otp_code . "</p>
            <p>This code expires in " . OTP_EXPIRY_MINS . " minutes.</p>
            <p>If you did not request this, you can safely ignore this email.</p>
        ";
        send_email($email, $subject, $body);

        $_SESSION['success_message'] = "A new OTP code has been sent to **$email**.";
        $action = 'otp_verify'; // Switch to verification form display

    } catch (Exception $e) {
        error_log("OTP Send Error: " . $e->getMessage());
        $errors['otp_send'] = 'Could not send OTP. Please try again later.';
        $action = 'otp_verify'; // Keep the user on the verification screen
    }
    
    goto render_form;
    
} elseif ($action === 'otp_verify' && $_SERVER['REQUEST_METHOD'] === 'POST') {
    // Phase 3: Verify submitted OTP
    
    $user_id = $_SESSION['temp_otp_user_id'] ?? null;
    $otp_input = $_POST['otp_code'] ?? '';

    if (!$user_id) {
        $errors['session'] = 'Verification session expired. Please start over.';
        redirect('/login');
    }

    if (empty($otp_input) || !is_numeric($otp_input) || strlen($otp_input) !== 6) {
        $errors['otp'] = 'Please enter a valid 6-digit code.';
        goto render_form;
    }

    try {
        $now = date('Y-m-d H:i:s');
        $stmt = $pdo->prepare("SELECT id FROM otp_codes 
                               WHERE user_id = ? AND code = ? AND purpose = 'login' 
                               AND used_at IS NULL AND expires_at > ?
                               ORDER BY created_at DESC LIMIT 1");
        $stmt->execute([$user_id, $otp_input, $now]);
        $otp_record = $stmt->fetch();

        if ($otp_record) {
            // OTP SUCCESS!
            
            // 1. Mark OTP as used
            $pdo->prepare("UPDATE otp_codes SET used_at = ? WHERE id = ?")->execute([$now, $otp_record['id']]);

            // 2. Set permanent session
            session_regenerate_id(true); // Mandatory for security after login
            
            // Retrieve full user record for session
            $stmt = $pdo->prepare("SELECT id, role FROM users WHERE id = ?");
            $stmt->execute([$user_id]);
            $user_data = $stmt->fetch();

            $_SESSION['user_id'] = $user_data['id'];
            $_SESSION['role'] = $user_data['role'];

            // 3. Update last login time
            $pdo->prepare("UPDATE users SET last_login_at = ? WHERE id = ?")->execute([$now, $user_id]);

            // 4. Cleanup temporary session variables
            unset($_SESSION['temp_otp_user_id'], $_SESSION['temp_otp_email'], $_SESSION['is_device_remembered']);

            $_SESSION['success_message'] = "Login successful! Welcome back.";
            redirect('/dashboard');
            
        } else {
            $errors['otp'] = 'Invalid or expired OTP code.';
        }

    } catch (PDOException $e) {
        error_log("OTP Verify Error: " . $e->getMessage());
        $errors['database'] = 'A server error occurred during verification.';
    }
}


// --- FORM RENDERER ---

render_form:
// Generate a new CSRF token before rendering the form
$csrf_token = generate_csrf_token();
$page_title = ($action === 'signup') ? 'Create Your Account' : (($action === 'otp_verify') ? 'Verify Login' : 'Sign In');

// Include the HTML template
include 'templates/auth_template.php';

?>