<?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/normalize.php';
require_once '../app/helpers/soft_delete.php';

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

requireApiLogin();
enforceCsrfForUnsafeRequest();

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

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

try {
    switch ($action) {
        case 'list':
            handleList($pdo);
            break;

        case 'reference_options':
            handleReferenceOptions($pdo);
            break;

        case 'save':
            handleSave($pdo);
            break;

        case 'delete':
            handleDelete($pdo);
            break;

        case 'restore':
            handleRestore($pdo);
            break;

        default:
            respond(['status' => 'error', 'message' => 'Invalid action']);
    }
} catch (Throwable $e) {
    respond(['status' => 'error', 'message' => $e->getMessage()]);
}

function handleList(PDO $pdo): void
{
    $search = trim((string)($_GET['search'] ?? ''));
    $status = trim((string)($_GET['status'] ?? ''));
    $page = max(1, (int)($_GET['page'] ?? 1));
    $perPage = max(10, min(100, (int)($_GET['per_page'] ?? 50)));
    $offset = ($page - 1) * $perPage;

    $where = ['v.deleted_at IS NULL'];
    $params = [];

    if ($search !== '') {
        $where[] = '(v.plate_number LIKE :search OR v.vehicle_model LIKE :search OR v.vehicle_type LIKE :search OR v.owner LIKE :search OR v.property LIKE :search OR v.vehicle_use_type LIKE :search)';
        $params['search'] = '%' . $search . '%';
    }

    if ($status !== '') {
        $where[] = 'LOWER(v.vehicle_status) = :status';
        $params['status'] = strtolower($status);
    }

    $whereClause = implode(' AND ', $where);

    $countStmt = $pdo->prepare("SELECT COUNT(*) FROM vehicles v WHERE $whereClause");
    $countStmt->execute($params);
    $total = (int)$countStmt->fetchColumn();

    $stmt = $pdo->prepare("
        SELECT v.*
        FROM vehicles v
        WHERE $whereClause
        ORDER BY v.id DESC
        LIMIT $perPage OFFSET $offset
    ");
    $stmt->execute($params);
    $vehicles = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $meta = [
        'total' => $total,
        'page' => $page,
        'per_page' => $perPage,
        'total_pages' => (int)ceil($total / $perPage),
        'active' => 0,
        'workshop' => 0,
        'inactive' => 0
    ];

    $allStmt = $pdo->query("SELECT LOWER(vehicle_status) AS s FROM vehicles WHERE deleted_at IS NULL");
    foreach ($allStmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $s = $row['s'] ?? '';
        if ($s === 'active') { $meta['active']++; }
        elseif (in_array($s, ['maintenance', 'in maintenance'], true)) { $meta['workshop']++; }
        else { $meta['inactive']++; }
    }

    if (($_GET['export'] ?? '') === 'csv') {
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="vehicles_' . date('Y-m-d') . '.csv"');
        $fh = fopen('php://output', 'w');
        fputcsv($fh, ['Plate Number', 'Model', 'Type', 'Owner', 'Status', 'Year', 'Use Type', 'Source', 'Seats', 'Registration Date']);
        foreach ($vehicles as $v) {
            fputcsv($fh, [$v['plate_number'], $v['vehicle_model'], $v['vehicle_type'], $v['owner'], $v['vehicle_status'], $v['year_of_manufacturing'], $v['vehicle_use_type'], $v['vehicle_source'], $v['seats'], $v['registration_date']]);
        }
        fclose($fh);
        exit;
    }

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

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

    $id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
    $plateNumber = trim((string)($_POST['plate_number'] ?? ''));

    if ($plateNumber === '') {
        respond(['status' => 'error', 'message' => 'Plate number is required']);
    }

    $payload = [
        'plate_number' => $plateNumber,
        'owner' => trim((string)($_POST['owner'] ?? '')),
        'property' => trim((string)($_POST['property'] ?? '')),
        'vehicle_type' => trim((string)($_POST['vehicle_type'] ?? '')),
        'vehicle_model' => trim((string)($_POST['vehicle_model'] ?? '')),
        'year_of_manufacturing' => normalizeNullableScalar($_POST['year'] ?? null),
        'displacement' => trim((string)($_POST['displacement'] ?? '')),
        'seats' => normalizeNullableInt($_POST['seats'] ?? null),
        'vehicle_use_type' => trim((string)($_POST['vehicle_use_type'] ?? '')),
        'vehicle_status' => trim((string)($_POST['status'] ?? 'Active')) ?: 'Active',
        'vehicle_source' => trim((string)($_POST['vehicle_source'] ?? '')),
        'supplier_id' => normalizeNullableInt($_POST['supplier_id'] ?? null),
        'contract_id' => normalizeNullableInt($_POST['contract_id'] ?? null),
        'need_obd' => normalizeNullableBool($_POST['need_obd'] ?? null),
        'obd_device_no' => trim((string)($_POST['obd_device_no'] ?? '')),
        'use_mr_car' => normalizeNullableBool($_POST['use_mr_car'] ?? null),
        'standard_fuel_consumption_l_per_100km' => normalizeNullableDecimal($_POST['standard_fuel_consumption_l_per_100km'] ?? null),
        'efficiency_baseline_km' => normalizeNullableDecimal($_POST['efficiency_baseline_km'] ?? null),
        'registration_date' => normalizeNullableDate($_POST['registration_date'] ?? null),
        'first_effective_date' => normalizeNullableDate($_POST['first_effective_date'] ?? null),
        'entry_date' => normalizeNullableDate($_POST['entry_date'] ?? null),
        'exit_date' => normalizeNullableDate($_POST['exit_date'] ?? null),
        'country_id' => normalizeNullableInt($_POST['country_id'] ?? null),
        'city_id' => normalizeNullableInt($_POST['city_id'] ?? null),
        'region_id' => normalizeNullableInt($_POST['region_id'] ?? null),
        'department_id' => normalizeNullableInt($_POST['department_id'] ?? null),
        'project_id' => normalizeNullableInt($_POST['project_id'] ?? null),
        'office_id' => normalizeNullableInt($_POST['office_id'] ?? null),
        'location_id' => normalizeNullableInt($_POST['location_id'] ?? null),
        'schedule_id' => normalizeNullableInt($_POST['schedule_id'] ?? null),
        'schedule_expiration_date' => normalizeNullableDate($_POST['schedule_expiration_date'] ?? null)
    ];

    if ($id > 0) {
        $before = fetchVehicle($pdo, $id);
        $setParts = [];
        foreach (array_keys($payload) as $column) {
            $setParts[] = $column . ' = :' . $column;
        }
        $payload['id'] = $id;

        $stmt = $pdo->prepare("
            UPDATE vehicles
            SET " . implode(", ", $setParts) . "
            WHERE id = :id AND deleted_at IS NULL
        ");
        $stmt->execute($payload);

        audit($pdo, (int)$_SESSION['user_id'], 'update', 'vehicle', $id, 'Vehicle updated', $before, $payload);
    } else {
        $columns = implode(', ', array_keys($payload));
        $values = implode(', ', array_map(static fn(string $column): string => ':' . $column, array_keys($payload)));

        $stmt = $pdo->prepare("
            INSERT INTO vehicles ({$columns})
            VALUES ({$values})
        ");
        $stmt->execute($payload);

        $newId = (int)$pdo->lastInsertId();
        audit($pdo, (int)$_SESSION['user_id'], 'create', 'vehicle', $newId, 'Vehicle created', null, $payload);
    }

    respond(['status' => 'success']);
}

function handleReferenceOptions(PDO $pdo): void
{
    respond([
        'status' => 'success',
        'data' => [
            'suppliers' => fetchOptions($pdo, 'suppliers'),
            'contracts' => fetchOptions($pdo, 'contracts', 'contract_code', "CONCAT(contract_code, COALESCE(CONCAT(' - ', account_name), '')) AS label"),
            'countries' => fetchOptions($pdo, 'countries'),
            'cities' => fetchOptions($pdo, 'cities'),
            'regions' => fetchOptions($pdo, 'regions'),
            'departments' => fetchOptions($pdo, 'departments'),
            'projects' => fetchOptions($pdo, 'projects'),
            'offices' => fetchOptions($pdo, 'offices'),
            'locations' => fetchOptions($pdo, 'locations'),
            'schedules' => fetchOptions($pdo, 'schedules', 'schedule_name', 'schedule_name AS label'),
            'owners' => fetchOptions($pdo, 'owners'),
            'vehicle_models' => fetchOptions($pdo, 'vehicle_models', 'name', 'name AS label'),
            'vehicle_types' => fetchOptions($pdo, 'vehicle_types', 'name', 'name AS label'),
            'vehicle_use_types' => fetchDistinctOptions($pdo, 'vehicles', 'vehicle_use_type')
        ]
    ]);
}

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

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

    $before = fetchVehicle($pdo, $id);
    softDelete($pdo, 'vehicles', $id);

    audit($pdo, (int)$_SESSION['user_id'], 'delete', 'vehicle', $id, 'Vehicle deleted', $before, null);
    respond(['status' => 'success']);
}

function fetchVehicle(PDO $pdo, int $id): ?array
{
    $stmt = $pdo->prepare("SELECT * FROM vehicles WHERE id = ? AND deleted_at IS NULL");
    $stmt->execute([$id]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    return $row ?: null;
}

function fetchOptions(PDO $pdo, string $table, string $orderBy = 'name', string $labelExpr = ''): array
{
    $allowedTables = ['suppliers', 'contracts', 'countries', 'cities', 'regions', 'departments', 'projects', 'offices', 'locations', 'schedules', 'owners', 'vehicle_models', 'vehicle_types'];
    if (!in_array($table, $allowedTables, true)) {
        return [];
    }
    $orderBy = preg_replace('/[^a-zA-Z0-9_]/', '', $orderBy);
    if ($labelExpr === '') {
        $labelExpr = 'name AS label';
    } else {
        $labelExpr = preg_replace('/[^a-zA-Z0-9_(),.\' -]/', '', $labelExpr);
    }
    $sql = "SELECT id, {$labelExpr} FROM `{$table}` ORDER BY `{$orderBy}`";
    $stmt = $pdo->query($sql);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

function fetchDistinctOptions(PDO $pdo, string $table, string $column): array
{
    $allowedTables = ['vehicles'];
    $allowedColumns = ['vehicle_use_type'];
    if (!in_array($table, $allowedTables, true) || !in_array($column, $allowedColumns, true)) {
        return [];
    }
    $stmt = $pdo->query("SELECT DISTINCT `{$column}` AS label FROM `{$table}` WHERE `{$column}` IS NOT NULL AND `{$column}` != '' ORDER BY `{$column}`");
    $rows = [];
    while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $rows[] = ['id' => $r['label'], 'label' => $r['label']];
    }
    return $rows;
}

function handleRestore(PDO $pdo): void
{
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) {
        respond(['status' => 'error', 'message' => 'Invalid vehicle ID']);
    }
    restoreRecord($pdo, 'vehicles', $id);
    audit($pdo, (int)$_SESSION['user_id'], 'restore', 'vehicle', $id, 'Vehicle restored', null, null);
    respond(['status' => 'success']);
}

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