<?php

define('ROOT_PATH', dirname(__DIR__));

function run_test(string $name, callable $test) {
    try {
        $test();
        echo "✅ PASS: $name\n";
    } catch (\Throwable $e) {
        echo "❌ FAIL: $name\n";
        echo "   Error: " . $e->getMessage() . "\n";
    }
}

function simulate_cgi_get(string $uri, string $scriptName, ?string $cookie = null) {
    $scriptFilename = ROOT_PATH . '/public/index.php';
    
    // Pass environment variables using putenv
    putenv("REQUEST_METHOD=GET");
    putenv("REQUEST_URI=$uri");
    putenv("SCRIPT_NAME=$scriptName");
    putenv("SCRIPT_FILENAME=$scriptFilename");
    putenv("HTTP_HOST=localhost");
    putenv("HTTPS=off");
    putenv("REDIRECT_STATUS=200");
    if ($cookie !== null) {
        putenv("HTTP_COOKIE=$cookie");
    }
    
    $cmd = 'C:/xampp/php/php-cgi.exe ' . escapeshellarg($scriptFilename);
    $output = (string) shell_exec($cmd);
    
    // Clear environment variables
    putenv("REQUEST_METHOD");
    putenv("REQUEST_URI");
    putenv("SCRIPT_NAME");
    putenv("SCRIPT_FILENAME");
    putenv("HTTP_HOST");
    putenv("HTTPS");
    putenv("REDIRECT_STATUS");
    if ($cookie !== null) {
        putenv("HTTP_COOKIE");
    }
    
    return $output;
}

function simulate_cgi_post(string $uri, string $scriptName, array $postData, ?string $cookie = null) {
    $scriptFilename = ROOT_PATH . '/public/index.php';
    
    $postBody = http_build_query($postData);
    $contentLength = strlen($postBody);
    
    $descriptorspec = [
        0 => ["pipe", "r"], // stdin
        1 => ["pipe", "w"], // stdout
        2 => ["pipe", "w"]  // stderr
    ];
    
    $env = [
        "REQUEST_METHOD" => "POST",
        "REQUEST_URI" => $uri,
        "SCRIPT_NAME" => $scriptName,
        "SCRIPT_FILENAME" => $scriptFilename,
        "HTTP_HOST" => "localhost",
        "HTTPS" => "off",
        "REDIRECT_STATUS" => "200",
        "CONTENT_TYPE" => "application/x-www-form-urlencoded",
        "CONTENT_LENGTH" => (string) $contentLength
    ];
    if ($cookie !== null) {
        $env["HTTP_COOKIE"] = $cookie;
    }
    
    $process = proc_open('C:/xampp/php/php-cgi.exe', $descriptorspec, $pipes, null, $env);
    
    $stdout = '';
    if (is_resource($process)) {
        fwrite($pipes[0], $postBody);
        fclose($pipes[0]);
        
        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        
        proc_close($process);
    }
    
    return $stdout;
}

function perform_login(string $identifier, string $password) {
    // 1. GET /login to retrieve session cookie and CSRF token
    $getOutput = simulate_cgi_get('/inveetaire/login', '/inveetaire/public/index.php');
    
    // Parse cookie (any name like inveetaire_session or PHPSESSID)
    preg_match('/Set-Cookie:\s*([^=]+=[^;]+)/i', $getOutput, $cookieMatch);
    $cookie = $cookieMatch[1] ?? null;
    
    // Parse _csrf token
    preg_match('/name="_csrf"\s*value="([^"]+)"/i', $getOutput, $csrfMatch);
    $csrfToken = $csrfMatch[1] ?? '';
    
    if (!$cookie || !$csrfToken) {
        throw new Exception("Could not extract cookie or CSRF token from GET /login output");
    }
    
    // 2. POST /login with credentials and parsed token/cookie
    $postData = [
        'identifier' => $identifier,
        'password'   => $password,
        '_csrf'      => $csrfToken
    ];
    
    $postOutput = simulate_cgi_post('/inveetaire/login', '/inveetaire/public/index.php', $postData, $cookie);
    
    return $postOutput;
}

run_test('Super Admin login (admin / admin)', function () {
    $res = perform_login('admin', 'admin');
    if (strpos($res, 'Location: http://localhost/inveetaire/app/admin/dashboard') === false) {
        throw new Exception("Expected redirect to '/app/admin/dashboard', got output:\n" . $res);
    }
    if (strpos($res, 'Status: 302') === false) {
        throw new Exception("Expected 302 status, got output:\n" . $res);
    }
});

run_test('Super Admin login via email (admin@inveetaire.local / admin)', function () {
    $res = perform_login('admin@inveetaire.local', 'admin');
    if (strpos($res, 'Location: http://localhost/inveetaire/app/admin/dashboard') === false) {
        throw new Exception("Expected redirect to '/app/admin/dashboard', got output:\n" . $res);
    }
});

run_test('Crew login (crew / admin)', function () {
    $res = perform_login('crew', 'admin');
    if (strpos($res, 'Location: http://localhost/inveetaire/app/crew/dashboard') === false) {
        throw new Exception("Expected redirect to '/app/crew/dashboard', got output:\n" . $res);
    }
});

run_test('Test Couple login (test / test123)', function () {
    $res = perform_login('test', 'test123');
    if (strpos($res, 'Location: http://localhost/inveetaire/app/couple/dashboard') === false) {
        throw new Exception("Expected redirect to '/app/couple/dashboard', got output:\n" . $res);
    }
});

run_test('Test Couple login via email (test@inveetaire.local / test123)', function () {
    $res = perform_login('test@inveetaire.local', 'test123');
    if (strpos($res, 'Location: http://localhost/inveetaire/app/couple/dashboard') === false) {
        throw new Exception("Expected redirect to '/app/couple/dashboard', got output:\n" . $res);
    }
});

run_test('Incorrect password login returns error', function () {
    $res = perform_login('admin', 'wrong_password');
    // It should redirect back to /login with 302 and store flash message in session,
    // or let's verify if redirect points back to /inveetaire/login
    if (strpos($res, 'Location: http://localhost/inveetaire/login') === false) {
        throw new Exception("Expected redirect back to '/login' on failure, got output:\n" . $res);
    }
});
