<?php
/**
 * Auth Login Endpoint
 */

use App\Core\Database;
use App\Core\JWT;
use App\Core\Validator;

use App\Middleware\RateLimitMiddleware;
use App\Core\Security;

// 0. Rate Limiting (5 attempts per minute per IP)
RateLimitMiddleware::check(5, 60);

$data = Security::sanitize(input());

// 1. Validation
$errors = Validator::validate($data, [
    'email'    => 'required|email',
    'password' => 'required'
]);

if ($errors) {
    json_error('Validation Failed', 422, $errors);
}

$email = $data['email'];
$password = $data['password'];

// 2. DB Check (Using hash for lookup since email is encrypted)
$db = Database::getInstance();
$emailHash = hash('sha256', strtolower($email));
$stmt = $db->prepare("SELECT * FROM users WHERE email_hash = ? LIMIT 1");
$stmt->execute([$emailHash]);
$user = $stmt->fetch();

if (!$user || !password_verify($password, $user['password_hash'])) {
    json_error('بيانات الدخول غير صحيحة', 401);
}

// 3. Handle device registration if provided (for mobile app login)
$deviceId = $data['device_id'] ?? null;
$deviceName = $data['device_name'] ?? 'Web Browser';
$deviceSecret = null;

if ($deviceId) {
    $deviceSecret = hash('sha256', $user['id'] . $deviceId . bin2hex(random_bytes(16)));
    $stmt = $db->prepare("
        INSERT INTO user_devices (id, user_id, device_fingerprint, device_name, platform, app_version, device_secret, is_trusted, last_seen_at)
        VALUES (UUID(), ?, ?, ?, ?, ?, ?, TRUE, NOW())
        ON DUPLICATE KEY UPDATE
            device_name = VALUES(device_name),
            platform = VALUES(platform),
            app_version = VALUES(app_version),
            device_secret = VALUES(device_secret),
            is_trusted = TRUE,
            last_seen_at = NOW(),
            updated_at = NOW()
    ");
    $stmt->execute([
        $user['id'],
        $deviceId,
        $deviceName,
        $data['platform'] ?? 'web',
        $data['app_version'] ?? '1.0.0',
        password_hash($deviceSecret, PASSWORD_DEFAULT),
    ]);
}

// 4. Issue Token
$secret = env('JWT_SECRET');
if (!$secret || strlen($secret) < 32) {
    error_log('FATAL: JWT_SECRET is missing or too short in .env');
    json_error('Server configuration error', 500);
}

// Longer expiry for mobile (30 days), short for web (15 mins)
$expiry = $deviceId ? (30 * 24 * 3600) : (15 * 60);

$payload = [
    'user_id'   => $user['id'],
    'tenant_id' => $user['tenant_id'],
    'role'      => $user['role'],
    'device_id' => $deviceId,
    'source'    => $deviceId ? 'mobile' : 'web',
    'exp'       => time() + $expiry
];

$token = JWT::encode($payload, $secret);

// 5. Update Refresh Token (Hashed before storage for security)
$refreshToken = bin2hex(random_bytes(32));
$refreshTokenHash = hash('sha256', $refreshToken);
$stmt = $db->prepare("UPDATE users SET refresh_token_hash = ?, last_login_at = NOW() WHERE id = ?");
$stmt->execute([$refreshTokenHash, $user['id']]);

// 6. Secure Refresh Token delivery via HttpOnly Cookie (for web)
if (!$deviceId) {
    setcookie('refresh_token', $refreshToken, [
        'expires'  => time() + (7 * 24 * 60 * 60), // 7 days
        'path'     => '/api/v1/auth/refresh',
        'secure'   => true,
        'httponly' => true,
        'samesite' => 'Strict',
    ]);
}

json_success([
    'access_token'  => $token,
    'refresh_token' => $refreshToken,
    'device_secret' => $deviceSecret,
    'user' => [
        'id'    => $user['id'],
        'name'  => (App\Core\Encryption::decrypt($user['name']) ?: $user['name']),
        'email' => (App\Core\Encryption::decrypt($user['email']) ?: $user['email']),
        'role'  => $user['role'],
        'tenant_id' => $user['tenant_id']
    ]
], 'تم تسجيل الدخول بنجاح');
