<?php
/**
 * Admin Login Endpoint
 * 
 * Handles authentication for admin users with robust error handling
 */

// This must execute before any possible error occurs
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        if (!headers_sent()) {
            header('Content-Type: application/json');
            header('Cache-Control: no-cache, no-store, must-revalidate');
            header('Pragma: no-cache');
            header('Expires: 0');
            http_response_code(500);
        }
        // Show details only when APP_DEBUG=1
        $debug = $_ENV['APP_DEBUG'] ?? $_SERVER['APP_DEBUG'] ?? getenv('APP_DEBUG') ?? '0';
        $payload = ['success' => false, 'error' => 'Server error'];
        if ($debug === '1' || strtolower((string)$debug) === 'true') {
            $payload['error'] = 'Fatal error: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'];
        }
        echo json_encode($payload);
    }
});

// Standard error handling
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/admin_error.log');

// Set headers first to ensure they're sent even if there's an error
header('Content-Type: application/json');
// Critical: Add cache control headers
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// CRITICAL: Allow origin with credentials
$allowed_origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
header("Access-Control-Allow-Origin: $allowed_origin");
header('Access-Control-Allow-Methods: POST, GET, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
header('Access-Control-Allow-Credentials: true');

// Ensure unified session initialization (sets session name and cookie flags)
if (!defined('TONSUI_LOADED')) {
    define('TONSUI_LOADED', true);
}
require_once __DIR__ . '/session_init.php';
// Centralized DB (reads from .env)
require_once __DIR__ . '/includes/Database.php';

// Function to safely return JSON response
function returnJson($data, $statusCode = 200) {
    http_response_code($statusCode);
    echo json_encode($data);
    exit;
}

// Error handler to ensure we always return JSON
function jsonErrorHandler($errno, $errstr, $errfile, $errline) {
    error_log("PHP Error: [$errno] $errstr in $errfile on line $errline");
    returnJson(['success' => false, 'error' => 'Server error: ' . $errstr], 500);
    return true; // Don't execute PHP's internal error handler
}

// Set custom error handler
set_error_handler('jsonErrorHandler');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    returnJson(['success' => true]);
}

// Session is initialized by session_init.php

// Function to get database connection
function getDbConnection() {
    try {
        $db = Database::getInstance();
        return $db->getConnection();
    } catch (Exception $e) {
        error_log("DB Connection Error: " . $e->getMessage());
        throw $e;
    }
}

// Main processing logic - always wrapped in try/catch to ensure JSON output
try {
    // Login request (POST)
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // Determine content type
        $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
        
        // Handle JSON input
        if (strpos($contentType, 'application/json') !== false) {
            $jsonInput = file_get_contents('php://input');
            if ($jsonInput === false) {
                throw new Exception('Failed to read request body');
            }
            
            error_log('Raw JSON request body: ' . $jsonInput);
            $data = json_decode($jsonInput, true);
            
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new Exception('Invalid JSON input: ' . json_last_error_msg());
            }
        } 
        // Handle form data
        else if (strpos($contentType, 'application/x-www-form-urlencoded') !== false || 
                 strpos($contentType, 'multipart/form-data') !== false) {
            $data = $_POST;
            error_log('Processing form data: ' . print_r($data, true));
        } else {
            throw new Exception('Unsupported Content-Type. Use application/json or form data.');
        }
        
        error_log('Processing admin login request for username: ' . ($data['username'] ?? 'not provided'));
        
        // Validate required fields
        if ((empty($data['username']) && empty($data['email'])) || empty($data['password'])) {
            returnJson(['success' => false, 'error' => 'Username and password are required'], 400);
        }
    
        $username = isset($data['username']) ? trim($data['username']) : '';
        if ($username === '' && !empty($data['email'])) {
            $username = trim($data['email']); // accept email in username field for compatibility
        }
        $password = $data['password'];
        
        // Get database connection
        $pdo = getDbConnection();
        
        // Query admin from database (by username OR email)
        // Use two placeholders to support PDO with emulate prepares disabled
        $stmt = $pdo->prepare("SELECT * FROM admins WHERE username = ? OR email = ? LIMIT 1");
        $stmt->execute([$username, $username]);
        $admin = $stmt->fetch(PDO::FETCH_ASSOC);
        
        error_log('Admin query executed for username: ' . $username . ', found: ' . ($admin ? 'yes' : 'no'));
        
        if (!$admin) {
            // Admin not found
            error_log('Admin not found: ' . $username);
            returnJson(['success' => false, 'error' => 'Invalid username or password'], 401);
        }
        
        // Debug the password verification
        error_log('Stored password hash: ' . ($admin['password'] ?? 'not found'));
        error_log('Password being verified: ' . $password);
        error_log('Password hash info: ' . print_r(password_get_info($admin['password']), true));
        
        // Check if password is correct
        $passwordVerified = password_verify($password, $admin['password']);
        error_log('Password verification result: ' . ($passwordVerified ? 'true' : 'false'));
        
        if ($passwordVerified) {
            // Set session variables (admin context)
            $_SESSION['user_id'] = (int)$admin['id'];
            $_SESSION['admin_id'] = (int)$admin['id'];
            $_SESSION['logged_in'] = true;
            $_SESSION['admin_logged_in'] = true;
            $_SESSION['admin_username'] = $admin['username'];
            $_SESSION['username'] = $admin['username'];
            if (isset($admin['email'])) {
                $_SESSION['email'] = $admin['email'];
            }
            $_SESSION['role'] = 'admin';
    
            // Return success with admin data (excluding password)
            unset($admin['password']);
            
            $response = [
                'success' => true,
                'message' => 'Login successful',
                'admin' => $admin
            ];
            
            error_log('Admin login successful for: ' . $username);
            returnJson($response);
        } else {
            // Invalid credentials
            error_log('Password verification failed for admin: ' . $username);
            returnJson(['success' => false, 'error' => 'Invalid username or password'], 401);
        }
    }
    
    // Check admin session status (GET)
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        if (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true) {
            try {
                // Get database connection
                $pdo = getDbConnection();
                
                // Get admin info from database
                $stmt = $pdo->prepare("SELECT id, username, name, email FROM admins WHERE id = ?");
                $stmt->execute([isset($_SESSION['admin_id']) ? $_SESSION['admin_id'] : 0]);
                $admin = $stmt->fetch(PDO::FETCH_ASSOC);

                if ($admin) {
                    returnJson([
                        'success' => true,
                        'loggedIn' => true,
                        'admin' => $admin
                    ]);
                } else {
                    // Admin not found in database but session exists
                    returnJson([
                        'success' => true,
                        'loggedIn' => true,
                        'admin' => [
                            'id' => isset($_SESSION['admin_id']) ? $_SESSION['admin_id'] : 0,
                            'username' => $_SESSION['admin_username']
                        ]
                    ]);
                }
            } catch (Exception $e) {
                returnJson([
                    'success' => false,
                    'loggedIn' => false,
                    'error' => 'Server error: ' . $e->getMessage()
                ], 500);
            }
        } else {
            returnJson([
                'success' => false,
                'loggedIn' => false,
                'error' => 'Not authenticated'
            ], 401);
        }
    }
    
    // Logout admin (DELETE)
    if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
        // Destroy session
        session_unset();
        session_destroy();
    
        returnJson([
            'success' => true,
            'message' => 'Logged out successfully'
        ]);
    }
    
    // If we get here, method not allowed
    returnJson([
        'success' => false,
        'error' => 'Method not allowed'
    ], 405);
    
} catch (PDOException $e) {
    // Database error
    error_log('Database error in admin login: ' . $e->getMessage());
    returnJson(['success' => false, 'error' => 'Database error: ' . $e->getMessage()], 500);
} catch (Exception $e) {
    // Other errors
    error_log('Unexpected error in admin login: ' . $e->getMessage());
    returnJson(['success' => false, 'error' => 'Server error: ' . $e->getMessage()], 500);
}
