<?php
session_start();

// Set proper JSON headers
header('Content-Type: application/json');

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Include your database connection file
    include 'layouts/dbconn.php';
    
    // Get username and password from the login form
    $username = trim($_POST['username']);
    $password = $_POST['password'];
    
    // Validate input
    if (empty($username) || empty($password)) {
        echo json_encode(array(
            'success' => false, 
            'message' => 'Username and password are required'
        ));
        exit;
    }
    
    // Get client IP address
    $ip_address = $_SERVER['REMOTE_ADDR'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    
    try {
        // Check if user exists and get all relevant data including role information
        $sql = "SELECT u.*, ur.role_name
                FROM users u 
                INNER JOIN user_roles ur ON u.role_id = ur.role_id 
                WHERE (u.username = ? OR u.email = ?) AND u.status = 'ACTIVE'";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("ss", $username, $username);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($result->num_rows > 0) {
            $user = $result->fetch_assoc();
            
            // Get maximum login attempts from system settings (default 5)
            $max_attempts = 5;
            try {
                $max_attempts_sql = "SELECT setting_value FROM settings WHERE setting_key = 'max_login_attempts'";
                $max_attempts_result = $conn->query($max_attempts_sql);
                if ($max_attempts_result && $max_attempts_result->num_rows > 0) {
                    $max_attempts = (int)$max_attempts_result->fetch_assoc()['setting_value'];
                }
            } catch (Exception $e) {
                // Use default if settings table doesn't exist or error occurs
            }
            
            // Check login attempts
            $failed_attempts = $user['failed_attempts'] ?? 0;
            if ($failed_attempts >= $max_attempts) {
                echo json_encode(array(
                    'success' => false,
                    'message' => 'Account locked due to too many failed login attempts. Please contact administrator.'
                ));
                exit;
            }
            
            // Verify the entered password with the hashed password from the database
            if (password_verify($password, $user['password'])) {
                // Password is correct - Reset failed attempts and update last login
                $update_sql = "UPDATE users SET 
                              failed_attempts = 0,
                              last_login = CURRENT_TIMESTAMP 
                              WHERE user_id = ?";
                $update_stmt = $conn->prepare($update_sql);
                $update_stmt->bind_param("i", $user['user_id']);
                $update_stmt->execute();
                $update_stmt->close();
                
                // Set session variables for cargo management system
                $_SESSION['user_id'] = $user['user_id'];
                $_SESSION['username'] = $user['username'];
                $_SESSION['email'] = $user['email'];
                $_SESSION['full_name'] = $user['full_name'];
                $_SESSION['phone'] = $user['phone'];
                $_SESSION['role_id'] = $user['role_id'];
                $_SESSION['role_name'] = $user['role_name'];
                $_SESSION['login_time'] = time();
                
                // Generate session token for additional security
                $_SESSION['session_token'] = bin2hex(random_bytes(32));
                
                // Get user's customer profile if they are a customer
                $customer_sql = "SELECT * FROM customers WHERE email = ? OR phone = ?";
                $customer_stmt = $conn->prepare($customer_sql);
                $customer_stmt->bind_param("ss", $user['email'], $user['phone']);
                $customer_stmt->execute();
                $customer_result = $customer_stmt->get_result();
                
                if ($customer_result->num_rows > 0) {
                    $customer = $customer_result->fetch_assoc();
                    $_SESSION['customer_id'] = $customer['customer_id'];
                    $_SESSION['customer_code'] = $customer['customer_code'];
                    $_SESSION['customer_type'] = $customer['customer_type'];
                    $_SESSION['company_name'] = $customer['company_name'];
                    $_SESSION['credit_limit'] = $customer['credit_limit'];
                    $_SESSION['is_credit_customer'] = $customer['is_credit_customer'];
                }
                $customer_stmt->close();
                
                // Get managed warehouses if user is warehouse manager
                if (in_array($user['role_name'], ['Warehouse Staff', 'Operations Manager'])) {
                    $warehouse_sql = "SELECT GROUP_CONCAT(warehouse_id) as managed_warehouse_ids, 
                                     COUNT(*) as managed_warehouses_count 
                                     FROM warehouses WHERE is_active = 1";
                    $warehouse_stmt = $conn->prepare($warehouse_sql);
                    $warehouse_stmt->execute();
                    $warehouse_result = $warehouse_stmt->get_result();
                    
                    if ($warehouse_result->num_rows > 0) {
                        $warehouse_data = $warehouse_result->fetch_assoc();
                        $_SESSION['managed_warehouse_ids'] = $warehouse_data['managed_warehouse_ids'];
                        $_SESSION['managed_warehouses_count'] = $warehouse_data['managed_warehouses_count'];
                    }
                    $warehouse_stmt->close();
                }
                
                // Log successful login activity
                $log_sql = "INSERT INTO activity_log (user_id, action, module, record_id, new_values, ip_address, user_agent, logged_at) 
                           VALUES (?, 'LOGIN', 'users', ?, ?, ?, ?, NOW())";
                $log_stmt = $conn->prepare($log_sql);
                $session_id = session_id();
                $login_data = json_encode(array(
                    'login_time' => date('Y-m-d H:i:s'),
                    'ip_address' => $ip_address,
                    'user_agent' => substr($user_agent, 0, 200),
                    'role' => $user['role_name'],
                    'session_id' => $session_id
                ));
                $log_stmt->bind_param("issss", $user['user_id'], $user['user_id'], $login_data, $ip_address, substr($user_agent, 0, 255));
                $log_stmt->execute();
                $log_stmt->close();
                
                // Determine redirect URL based on role
                $redirect_url = match($user['role_name']) {
                    'Administrator' => 'index.php',
                    'Operations Manager' => 'index.php',
                    'Finance Manager' => 'index.php',
                    'Customer Service' => 'index.php',
                    'Warehouse Staff' => 'warehouse_dashboard.php',
                    'Driver' => 'driver_dashboard.php',
                    'Customs Officer' => 'customs_dashboard.php',
                    default => 'index.php'
                };
                
                // Get some quick stats for the user
                $stats = array();
                
                // For Operations Managers - get their operational statistics
                if ($user['role_name'] === 'Operations Manager') {
                    $ops_stats_sql = "SELECT 
                                      COUNT(DISTINCT s.shipment_id) as total_shipments,
                                      COUNT(DISTINCT CASE WHEN s.status IN ('BOOKED', 'COLLECTED', 'IN_TRANSIT', 'OUT_FOR_DELIVERY') THEN s.shipment_id END) as active_shipments,
                                      COUNT(DISTINCT m.manifest_id) as total_manifests,
                                      COUNT(DISTINCT c.customer_id) as total_customers
                                      FROM shipments s
                                      LEFT JOIN manifests m ON 1=1
                                      LEFT JOIN customers c ON s.sender_customer_id = c.customer_id
                                      WHERE s.booking_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    $ops_stats_stmt = $conn->prepare($ops_stats_sql);
                    $ops_stats_stmt->execute();
                    $ops_stats_result = $ops_stats_stmt->get_result();
                    
                    if ($ops_stats_result->num_rows > 0) {
                        $stats = $ops_stats_result->fetch_assoc();
                    }
                    $ops_stats_stmt->close();
                }
                
                // For Customer Service - get customer interaction statistics
                if ($user['role_name'] === 'Customer Service') {
                    $cs_stats_sql = "SELECT 
                                    COUNT(DISTINCT s.shipment_id) as shipments_handled,
                                    COUNT(DISTINCT s.sender_customer_id) as customers_served,
                                    COUNT(DISTINCT CASE WHEN s.status = 'DELIVERED' THEN s.shipment_id END) as delivered_shipments,
                                    COALESCE(SUM(s.total_charges), 0) as total_revenue_handled
                                    FROM shipments s
                                    WHERE s.created_by = ? AND s.booking_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    $cs_stats_stmt = $conn->prepare($cs_stats_sql);
                    $cs_stats_stmt->bind_param("i", $user['user_id']);
                    $cs_stats_stmt->execute();
                    $cs_stats_result = $cs_stats_stmt->get_result();
                    
                    if ($cs_stats_result->num_rows > 0) {
                        $cs_stats = $cs_stats_result->fetch_assoc();
                        $stats = array_merge($stats, $cs_stats);
                    }
                    $cs_stats_stmt->close();
                }
                
                // For Warehouse Staff - get warehouse statistics
                if ($user['role_name'] === 'Warehouse Staff') {
                    $warehouse_stats_sql = "SELECT 
                                          COUNT(DISTINCT m.manifest_id) as manifests_processed,
                                          COUNT(DISTINCT CASE WHEN m.status = 'ARRIVED' THEN m.manifest_id END) as arrived_manifests,
                                          COUNT(DISTINCT CASE WHEN m.status = 'DEPARTED' THEN m.manifest_id END) as departed_manifests
                                          FROM manifests m
                                          WHERE m.created_by = ? AND m.created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    $wh_stats_stmt = $conn->prepare($warehouse_stats_sql);
                    $wh_stats_stmt->bind_param("i", $user['user_id']);
                    $wh_stats_stmt->execute();
                    $wh_stats_result = $wh_stats_stmt->get_result();
                    
                    if ($wh_stats_result->num_rows > 0) {
                        $wh_stats = $wh_stats_result->fetch_assoc();
                        $stats = array_merge($stats, $wh_stats);
                    }
                    $wh_stats_stmt->close();
                }
                
                // Prepare response data
                $response_data = array(
                    'success' => true,
                    'message' => 'Login successful',
                    'user' => array(
                        'user_id' => $user['user_id'],
                        'username' => $user['username'],
                        'full_name' => $user['full_name'],
                        'email' => $user['email'],
                        'phone' => $user['phone'],
                        'role_id' => $user['role_id'],
                        'role_name' => $user['role_name'],
                        'customer_id' => $_SESSION['customer_id'] ?? null,
                        'customer_code' => $_SESSION['customer_code'] ?? null,
                        'customer_type' => $_SESSION['customer_type'] ?? null,
                        'company_name' => $_SESSION['company_name'] ?? null,
                        'managed_warehouses_count' => $_SESSION['managed_warehouses_count'] ?? 0
                    ),
                    'stats' => $stats,
                    'redirect_url' => $redirect_url,
                    'session_token' => $_SESSION['session_token']
                );
                
                echo json_encode($response_data);
                
            } else {
                // Invalid password - increment failed attempts
                $increment_sql = "UPDATE users SET failed_attempts = COALESCE(failed_attempts, 0) + 1, 
                                last_attempt_time = CURRENT_TIMESTAMP WHERE user_id = ?";
                $increment_stmt = $conn->prepare($increment_sql);
                $increment_stmt->bind_param("i", $user['user_id']);
                $increment_stmt->execute();
                $increment_stmt->close();
                
                // Log failed login attempt
                $log_sql = "INSERT INTO activity_log (user_id, action, module, record_id, new_values, ip_address, user_agent, logged_at) 
                           VALUES (?, 'FAILED_LOGIN', 'users', ?, ?, ?, ?, NOW())";
                $log_stmt = $conn->prepare($log_sql);
                $failed_data = json_encode(array(
                    'reason' => 'invalid_password',
                    'attempt_time' => date('Y-m-d H:i:s'),
                    'attempts_count' => $failed_attempts + 1
                ));
                $log_stmt->bind_param("issss", $user['user_id'], $user['user_id'], $failed_data, $ip_address, substr($user_agent, 0, 255));
                $log_stmt->execute();
                $log_stmt->close();
                
                $remaining_attempts = $max_attempts - ($failed_attempts + 1);
                $message = $remaining_attempts > 0 
                    ? "Invalid username or password. $remaining_attempts attempts remaining."
                    : "Invalid username or password. Account will be locked after next failed attempt.";
                
                echo json_encode(array(
                    'success' => false,
                    'message' => $message
                ));
            }
        } else {
            // User not found - log the attempt
            $log_sql = "INSERT INTO activity_log (action, module, record_id, new_values, ip_address, user_agent, logged_at) 
                       VALUES ('FAILED_LOGIN', 'users', '0', ?, ?, ?, NOW())";
            $log_stmt = $conn->prepare($log_sql);
            $failed_data = json_encode(array(
                'reason' => 'user_not_found',
                'username_attempted' => $username,
                'attempt_time' => date('Y-m-d H:i:s')
            ));
            $log_stmt->bind_param("sss", $failed_data, $ip_address, substr($user_agent, 0, 255));
            $log_stmt->execute();
            $log_stmt->close();
            
            echo json_encode(array(
                'success' => false,
                'message' => 'Invalid username or password'
            ));
        }
        
        $stmt->close();
        
    } catch (Exception $e) {
        error_log("Login error: " . $e->getMessage());
        
        echo json_encode(array(
            'success' => false,
            'message' => 'An error occurred during login. Please try again.'
        ));
    }
    
    $conn->close();
} else {
    echo json_encode(array(
        'success' => false,
        'message' => 'Invalid request method'
    ));
}
?>