<?php
declare(strict_types=1);

require_once dirname(__DIR__) . '/common/auth_middleware.php';
require_once dirname(__DIR__) . '/common/session_store.php';

try {
    golder_require_method('POST');

    $master = golder_master_pdo();

    golder_apply_default_rate_limit($master, 'api_login_ip', 10, 60);

    $username = trim((string)($_POST['username'] ?? ''));
    $password = (string)($_POST['password'] ?? '');
    $hardwareId = trim((string)($_POST['hardware_id'] ?? ''));
    $deviceNameInput = trim((string)($_POST['device_name'] ?? ''));
    $deviceName = ($deviceNameInput !== '') ? substr($deviceNameInput, 0, 100) : 'Bilgisayar (PC)';

    if ($username === '' || $password === '') {
        golder_json_response(['status' => 'error', 'message' => 'Username and password are required.'], 400);
    }
    if ($hardwareId === '') {
        golder_json_response(['status' => 'error', 'message' => 'hardware_id is required.'], 400);
    }

    golder_apply_default_rate_limit($master, 'api_login_user_' . strtolower($username), 10, 60);

    golder_ensure_customers_columns($master);
    golder_ensure_plan_tables($master);
    golder_ensure_customer_devices_schema($master);
    golder_ensure_api_security_tables($master);
    golder_ensure_license_public_keys_table($master);

    $customer = golder_customer_by_username($master, $username);
    if (!$customer) {
        golder_json_response(['status' => 'error', 'message' => 'Invalid credentials.'], 401);
    }

    $storedHash = trim((string)($customer['password_hash'] ?? ''));
    $isPasswordValid = false;
    if ($storedHash !== '') {
        $isPasswordValid = password_verify($password, $storedHash) || hash_equals($storedHash, $password);
    }
    if (!$isPasswordValid) {
        golder_json_response(['status' => 'error', 'message' => 'Invalid credentials.'], 401);
    }

    $customerId = (int)($customer['id'] ?? 0);
    if ($customerId <= 0) {
        golder_json_response(['status' => 'error', 'message' => 'Invalid account state.'], 500);
    }

    $customer = golder_enforce_customer_plan($master, $customerId) ?: $customer;
    $effectivePlan = golder_customer_effective_plan($customer);
    $planType = (string)($effectivePlan['plan_type'] ?? '');
    $maxPcDevices = (int)($effectivePlan['max_pc_devices'] ?? 1);
    $maxWebSessions = (int)($effectivePlan['max_web_sessions'] ?? 0);
    $desktopExpiry = (string)($effectivePlan['desktop_expiry_date'] ?? '');
    $syncExpiry = (string)($effectivePlan['sync_expiry_date'] ?? '');
    $syncStatus = (string)($effectivePlan['sync_status'] ?? 'disabled');
    $webMobileEnabled = !empty($effectivePlan['web_mobile_enabled']) ? 1 : 0;
    $licenseStatus = strtolower(trim((string)($customer['license_status'] ?? 'active')));

    if (in_array($licenseStatus, ['cancelled', 'suspended'], true)) {
        golder_json_response(['status' => 'error', 'message' => 'License is not active.'], 403);
    }
    if (golder_customer_desktop_access_expired($customer)) {
        golder_json_response(['status' => 'error', 'message' => 'Desktop license has expired.'], 403);
    }

    $deviceUid = substr($hardwareId, 0, 120);
    $st = $master->prepare(
        "SELECT id, is_blocked
         FROM customer_devices
         WHERE customer_id = :cid
           AND device_type = 'pc'
           AND device_uid = :du
         LIMIT 1"
    );
    $st->execute([':cid' => $customerId, ':du' => $deviceUid]);
    $existingDevice = $st->fetch();

    if ($existingDevice && (int)($existingDevice['is_blocked'] ?? 0) === 1) {
        golder_json_response(['status' => 'error', 'message' => 'This device was blocked by administrator.'], 403);
    }

    if (!$existingDevice) {
        $registeredPcCount = golder_count_registered_desktop_devices($master, $customerId);
        if ($registeredPcCount >= $maxPcDevices) {
            golder_json_response([
                'status' => 'error',
                'message' => sprintf(
                    'Kayitli PC lisans kotaniz dolu (%d / %d). Yeni bilgisayar icin once cihaz kilidini sifirlayin veya eski cihazi kaldirin.',
                    $registeredPcCount,
                    $maxPcDevices
                ),
                'remaining_pc_slots' => 0,
                'max_pc_devices' => $maxPcDevices,
            ], 403);
        }
    }

    if ($existingDevice) {
        $master->prepare(
            "UPDATE customer_devices
             SET hardware_id = :hw,
                 device_name = :dn,
                 user_agent_hash = :uah,
                 ip_address = :ip,
                 last_login = UTC_TIMESTAMP(),
                 last_active_at = UTC_TIMESTAMP(),
                 is_blocked = 0
             WHERE id = :id"
        )->execute([
            ':hw' => substr($hardwareId, 0, 100),
            ':dn' => $deviceName,
            ':uah' => hash('sha256', strtolower(golder_user_agent())),
            ':ip' => golder_client_ip(),
            ':id' => (int)$existingDevice['id'],
        ]);
    } else {
        $ins = $master->prepare(
            "INSERT INTO customer_devices
             (customer_id, hardware_id, device_uid, device_type, device_name, user_agent_hash, ip_address, last_login, last_active_at, is_blocked)
             VALUES (:cid, :hw, :du, 'pc', :dn, :uah, :ip, UTC_TIMESTAMP(), UTC_TIMESTAMP(), 0)"
        );
        $ins->execute([
            ':cid' => $customerId,
            ':hw' => substr($hardwareId, 0, 100),
            ':du' => $deviceUid,
            ':dn' => $deviceName,
            ':uah' => hash('sha256', strtolower(golder_user_agent())),
            ':ip' => golder_client_ip(),
        ]);
    }

    golder_revoke_desktop_tokens_by_device_uid($master, $customerId, $deviceUid);

    $master->prepare('UPDATE customers SET last_pc_login_date = UTC_TIMESTAMP() WHERE id = :id')->execute([':id' => $customerId]);

    $apiToken = '';
    $tokenExpiresAt = '';
    if (golder_customer_sync_enabled($customer)) {
        $apiToken = golder_issue_api_token($master, $customerId, 'desktop_sync', 86400 * 30, [
            'device_name' => $deviceName,
            'hardware_id' => $deviceUid,
            'ip' => golder_client_ip(),
        ]);
        $tokenExpiresAt = gmdate('Y-m-d H:i:s', time() + 86400 * 30);
    }

    $remainingPcSlots = max(0, $maxPcDevices - golder_count_registered_desktop_devices($master, $customerId));
    $licenseSigned = golder_issue_customer_license($master, $customer, $hardwareId);

    golder_json_response([
        'status' => 'success',
        'data' => [
            'plan_type' => $planType,
            'is_ai_enabled' => (int)($customer['is_ai_enabled'] ?? 0),
            'max_devices' => $maxPcDevices,
            'max_pc_devices' => $maxPcDevices,
            'max_web_sessions' => $maxWebSessions,
            'db_host' => golder_master_db_config()['host'],
            'db_name' => (string)($customer['mysql_db_name'] ?? ''),
            'db_user' => (string)($customer['mysql_db_user'] ?? ''),
            'db_pass' => (string)($customer['mysql_db_pass'] ?? ''),
            'desktop_expiry_date' => $desktopExpiry,
            'sync_expiry_date' => $syncExpiry,
            'sync_status' => $syncStatus,
            'web_mobile_enabled' => $webMobileEnabled,
            'expiry_date' => $desktopExpiry,
            'license_expiry_date' => $desktopExpiry,
            'customer_username' => (string)($customer['username'] ?? ''),
            'customer_email' => (string)($customer['email'] ?? ''),
            'customer_phone' => (string)($customer['phone_number'] ?? ''),
            'license_payload' => (string)$licenseSigned['payload'],
            'license_signature' => (string)$licenseSigned['signature'],
            'license_key_id' => (string)$licenseSigned['key_id'],
            'license_algorithm' => 'Ed25519',
            'license_public_key' => (string)$licenseSigned['public_key'],
            'api_token' => $apiToken,
            'api_token_expires_at' => $tokenExpiresAt,
            'remaining_pc_slots' => $remainingPcSlots,
        ],
    ]);
} catch (Throwable $e) {
    error_log(
        sprintf(
            '[golder api/login] %s in %s:%d',
            $e->getMessage(),
            $e->getFile(),
            $e->getLine()
        )
    );
    golder_json_error(500, 'INTERNAL_SERVER_ERROR', 'Login service failed. Check server error logs for details.');
}
