<?php
declare(strict_types=1);
require_once '../config/database.php';
require_once '../app/helpers/rbac.php';
require_once '../app/helpers/audit.php';
require_once '../app/helpers/api_security.php';
require_once '../app/helpers/soft_delete.php';

header('Content-Type: application/json');

requireApiLogin();
enforceCsrfForUnsafeRequest();

$action = $_GET['action'] ?? '';

if (!isAdmin() && !can('tracker_integration.view')) {
    respond(['status' => 'error', 'message' => 'Unauthorized']);
}

try {
    switch ($action) {
        case 'list': handleList($pdo); break;
        case 'save': handleSave($pdo); break;
        case 'delete': handleDelete($pdo); break;
        case 'test_connection': handleTestConnection($pdo); break;
        case 'list_devices': handleListDevices($pdo); break;
        case 'fetch_devices': handleFetchDevices($pdo); break;
        case 'save_mapping': handleSaveMapping($pdo); break;
        case 'delete_mapping': handleDeleteMapping($pdo); break;
        case 'vehicles': handleVehicles($pdo); break;
        default: respond(['status' => 'error', 'message' => 'Unknown action']);
    }
} catch (Exception $e) {
    respond(['status' => 'error', 'message' => $e->getMessage()]);
}

function respond(array $payload): void { apiRespond($payload); }

function doAudit(PDO $pdo, string $action, string $description, ?int $recordId = null): void {
    audit($pdo, (int)($_SESSION['user_id'] ?? 0), $action, 'tracker_integration', $recordId ?? 0, $description, null, null);
}

function handleList(PDO $pdo): void
{
    $where = ['ti.deleted_at IS NULL'];
    $params = [];

    if (!empty($_GET['status'])) {
        $where[] = 'ti.status = :status';
        $params['status'] = $_GET['status'];
    }
    if (!empty($_GET['search'])) {
        $q = '%' . $_GET['search'] . '%';
        $where[] = '(ti.name LIKE :q1 OR ti.provider LIKE :q2 OR ti.base_url LIKE :q3)';
        $params['q1'] = $q; $params['q2'] = $q; $params['q3'] = $q;
    }

    $sql = "SELECT ti.*,
            (SELECT COUNT(*) FROM tracker_device_mappings WHERE integration_id = ti.id) AS device_count
            FROM tracker_integrations ti
            WHERE " . implode(' AND ', $where) . "
            ORDER BY ti.name ASC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function handleSave(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.create') && !can('tracker_integration.edit')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }

    $id = (int)($_POST['id'] ?? 0);
    $name = trim($_POST['name'] ?? '');
    if (!$name) respond(['status' => 'error', 'message' => 'Integration name is required']);

    $additionalConfig = $_POST['additional_config'] ?? null;
    if ($additionalConfig) {
        $decoded = json_decode($additionalConfig, true);
        if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
            respond(['status' => 'error', 'message' => 'Additional config must be valid JSON']);
        }
    }

    $data = [
        'name' => $name,
        'provider' => trim($_POST['provider'] ?? 'generic'),
        'base_url' => trim($_POST['base_url'] ?? ''),
        'api_key' => trim($_POST['api_key'] ?? ''),
        'api_secret' => trim($_POST['api_secret'] ?? ''),
        'auth_type' => $_POST['auth_type'] ?? 'header',
        'additional_config' => $additionalConfig,
        'poll_interval_seconds' => (int)($_POST['poll_interval_seconds'] ?? 300),
        'status' => $_POST['status'] ?? 'active',
    ];

    if ($id > 0) {
        $data['id'] = $id;
        $sets = implode(', ', array_map(function ($c) { return "{$c} = :{$c}"; }, array_keys($data)));
        $stmt = $pdo->prepare("UPDATE tracker_integrations SET {$sets} WHERE id = :id");
        $stmt->execute($data);
        doAudit($pdo, 'update', "Integration #{$id} updated", $id);
        respond(['status' => 'success', 'message' => 'Integration updated']);
    } else {
        $cols = implode(', ', array_keys($data));
        $vals = ':' . implode(', :', array_keys($data));
        $stmt = $pdo->prepare("INSERT INTO tracker_integrations ({$cols}) VALUES ({$vals})");
        $stmt->execute($data);
        $newId = (int)$pdo->lastInsertId();
        doAudit($pdo, 'create', "Integration #{$newId} created", $newId);
        respond(['status' => 'success', 'message' => 'Integration created', 'id' => $newId]);
    }
}

function handleDelete(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.delete')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);
    softDelete($pdo, 'tracker_integrations', $id);
    doAudit($pdo, 'delete', "Integration #{$id} deleted", $id);
    respond(['status' => 'success', 'message' => 'Integration deleted']);
}

function handleTestConnection(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.edit')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }

    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);

    $stmt = $pdo->prepare("SELECT * FROM tracker_integrations WHERE id = :id AND deleted_at IS NULL");
    $stmt->execute(['id' => $id]);
    $integration = $stmt->fetch();
    if (!$integration) respond(['status' => 'error', 'message' => 'Integration not found']);

    $result = testApiConnection($integration);

    $newStatus = $result['success'] ? 'active' : 'error';
    $updateStmt = $pdo->prepare("UPDATE tracker_integrations SET status = :status, last_checked_at = NOW(), error_message = :error WHERE id = :id");
    $updateStmt->execute(['status' => $newStatus, 'error' => $result['success'] ? null : $result['message'], 'id' => $id]);

    doAudit($pdo, 'test', "Tested connection for #{$id}: " . ($result['success'] ? 'OK' : 'FAIL'), $id);

    respond([
        'status' => $result['success'] ? 'success' : 'error',
        'message' => $result['success'] ? 'Connection successful!' : 'Connection failed: ' . $result['message'],
        'http_code' => $result['http_code'] ?? null,
    ]);
}

function handleListDevices(PDO $pdo): void
{
    $integrationId = (int)($_GET['integration_id'] ?? 0);
    if ($integrationId <= 0) respond(['status' => 'error', 'message' => 'Invalid integration ID']);

    $stmt = $pdo->prepare("
        SELECT dm.*, v.plate_number
        FROM tracker_device_mappings dm
        LEFT JOIN vehicles v ON v.id = dm.vehicle_id
        WHERE dm.integration_id = :id
        ORDER BY dm.tracker_device_name ASC
    ");
    $stmt->execute(['id' => $integrationId]);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function handleFetchDevices(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.devices')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }

    $integrationId = (int)($_POST['integration_id'] ?? 0);
    if ($integrationId <= 0) respond(['status' => 'error', 'message' => 'Invalid integration ID']);

    $stmt = $pdo->prepare("SELECT * FROM tracker_integrations WHERE id = :id AND deleted_at IS NULL");
    $stmt->execute(['id' => $integrationId]);
    $integration = $stmt->fetch();
    if (!$integration) respond(['status' => 'error', 'message' => 'Integration not found']);

    $devices = fetchApiDevices($integration);
    if ($devices === null) {
        respond(['status' => 'error', 'message' => 'Device listing not supported for this provider. You can add devices manually.']);
    }

    respond(['status' => 'success', 'data' => $devices]);
}

function handleSaveMapping(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.devices')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }

    $id = (int)($_POST['id'] ?? 0);
    $integrationId = (int)($_POST['integration_id'] ?? 0);
    $trackerDeviceId = trim($_POST['tracker_device_id'] ?? '');
    $trackerDeviceName = trim($_POST['tracker_device_name'] ?? '');
    $vehicleId = !empty($_POST['vehicle_id']) ? (int)$_POST['vehicle_id'] : null;

    if ($integrationId <= 0) respond(['status' => 'error', 'message' => 'Invalid integration']);
    if (!$trackerDeviceId) respond(['status' => 'error', 'message' => 'Tracker device ID is required']);

    $data = [
        'integration_id' => $integrationId,
        'tracker_device_id' => $trackerDeviceId,
        'tracker_device_name' => $trackerDeviceName,
        'vehicle_id' => $vehicleId,
    ];

    if ($id > 0) {
        $data['id'] = $id;
        $sets = implode(', ', array_map(function ($c) { return "{$c} = :{$c}"; }, array_keys($data)));
        $pdo->prepare("UPDATE tracker_device_mappings SET {$sets} WHERE id = :id")->execute($data);
    } else {
        $cols = implode(', ', array_keys($data));
        $vals = ':' . implode(', :', array_keys($data));
        $pdo->prepare("INSERT INTO tracker_device_mappings ({$cols}) VALUES ({$vals})")->execute($data);
    }

    doAudit($pdo, 'mapping', (($id > 0 ? 'Updated' : 'Created') . " device mapping #{$id}"), $integrationId);
    respond(['status' => 'success', 'message' => (($id > 0 ? 'Updated' : 'Created') . ' device mapping')]);
}

function handleDeleteMapping(PDO $pdo): void
{
    if (!isAdmin() && !can('tracker_integration.devices')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);
    $pdo->prepare("DELETE FROM tracker_device_mappings WHERE id = :id")->execute(['id' => $id]);
    doAudit($pdo, 'mapping', "Deleted device mapping #{$id}", 0);
    respond(['status' => 'success', 'message' => 'Device mapping deleted']);
}

function handleVehicles(PDO $pdo): void
{
    $stmt = $pdo->prepare("SELECT id, plate_number, vehicle_model FROM vehicles WHERE deleted_at IS NULL ORDER BY plate_number ASC");
    $stmt->execute();
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function testApiConnection(array $integration): array
{
    $url = rtrim($integration['base_url'] ?? '', '/');
    $apiKey = $integration['api_key'] ?? '';
    if (!$url) return ['success' => false, 'message' => 'Base URL is not configured', 'http_code' => null];

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);

    $headers = [];
    switch ($integration['auth_type'] ?? 'header') {
        case 'header':
            if ($apiKey) $headers[] = "X-API-Key: {$apiKey}";
            break;
        case 'bearer':
            if ($apiKey) $headers[] = "Authorization: Bearer {$apiKey}";
            break;
        case 'basic':
            $secret = $integration['api_secret'] ?? '';
            if ($apiKey || $secret) $headers[] = "Authorization: Basic " . base64_encode("{$apiKey}:{$secret}");
            break;
    }
    if ($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    if ($curlError) return ['success' => false, 'message' => $curlError, 'http_code' => $httpCode];
    if ($httpCode >= 200 && $httpCode < 500) return ['success' => true, 'message' => 'OK', 'http_code' => $httpCode];
    return ['success' => false, 'message' => "HTTP {$httpCode}", 'http_code' => $httpCode];
}

function fetchApiDevices(array $integration): ?array
{
    $provider = $integration['provider'] ?? 'generic';
    $baseUrl = rtrim($integration['base_url'] ?? '', '/');
    $apiKey = $integration['api_key'] ?? '';

    if (!$baseUrl) return null;

    switch ($provider) {
        case 'traccar':
            $url = "{$baseUrl}/api/devices";
            break;
        default:
            return null;
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);

    $headers = [];
    switch ($integration['auth_type'] ?? 'header') {
        case 'bearer':
            if ($apiKey) $headers[] = "Authorization: Bearer {$apiKey}";
            break;
        case 'header':
            if ($apiKey) $headers[] = "X-API-Key: {$apiKey}";
            break;
        case 'basic':
            $secret = $integration['api_secret'] ?? '';
            $headers[] = "Authorization: Basic " . base64_encode("{$apiKey}:{$secret}");
            break;
    }
    if ($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200 || !$response) return null;

    $decoded = json_decode($response, true);
    if (!is_array($decoded)) return null;

    $devices = [];
    foreach ($decoded as $d) {
        $devices[] = [
            'id' => $d['id'] ?? '',
            'name' => $d['name'] ?? ($d['deviceId'] ?? 'Unknown'),
            'uniqueId' => $d['uniqueId'] ?? ($d['deviceId'] ?? ''),
        ];
    }
    return $devices;
}
