<?php
declare(strict_types=1);

function handleServiceIntervals(PDO $pdo): void
{
    $vehicleId = (int)($_GET['vehicle_id'] ?? 0);
    $showDue = $_GET['due_only'] ?? '';

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

    if ($vehicleId > 0) {
        $where[] = 'si.vehicle_id = :vehicle_id';
        $params['vehicle_id'] = $vehicleId;
    }
    if ($showDue === '1') {
        $where[] = '(si.due_date IS NOT NULL AND si.due_date <= CURDATE()) OR (si.due_mileage > 0 AND si.due_mileage <= COALESCE(v.current_odometer, 0))';
    }

    $whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';

    $rows = $pdo->prepare("
        SELECT
            si.*,
            v.plate_number,
            v.vehicle_model,
            v.vehicle_type,
            v.current_odometer,
            COALESCE(v.current_odometer, 0) >= si.due_mileage AND si.due_mileage > 0 AS mileage_due,
            si.due_date IS NOT NULL AND si.due_date <= CURDATE() AS date_due
        FROM service_intervals si
        LEFT JOIN vehicles v ON v.id = si.vehicle_id AND v.deleted_at IS NULL
        $whereSql
        ORDER BY si.due_date ASC, si.due_mileage ASC
    ");
    $rows->execute($params);
    $data = $rows->fetchAll(PDO::FETCH_ASSOC);

    foreach ($data as &$r) {
        $r['is_due'] = ($r['mileage_due'] || $r['date_due']) && $r['is_active'];
    }

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

function handleSaveServiceInterval(PDO $pdo): void
{
    enforceMaintenanceWritePermission();

    $id = (int)($_POST['id'] ?? 0);
    $vehicleId = (int)($_POST['vehicle_id'] ?? 0);
    if ($vehicleId <= 0) {
        respond(['status' => 'error', 'message' => 'Vehicle is required']);
    }

    $intervalType = $_POST['interval_type'] ?? 'both';
    $intervalKm = max(0, (int)($_POST['interval_km'] ?? 0));
    $intervalDays = max(0, (int)($_POST['interval_days'] ?? 0));
    $taskDescription = trim((string)($_POST['task_description'] ?? ''));
    $isActive = (int)($_POST['is_active'] ?? 1);

    if ($intervalKm <= 0 && $intervalDays <= 0) {
        respond(['status' => 'error', 'message' => 'Set at least km or days interval']);
    }

    $vStmt = $pdo->prepare("SELECT current_odometer, last_service_odometer, last_service_date FROM vehicles WHERE id = ? AND deleted_at IS NULL");
    $vStmt->execute([$vehicleId]);
    $vehicle = $vStmt->fetch(PDO::FETCH_ASSOC);
    if (!$vehicle) {
        respond(['status' => 'error', 'message' => 'Vehicle not found']);
    }

    $odometer = (int)($vehicle['current_odometer'] ?? 0);
    $lastOdo = (int)($vehicle['last_service_odometer'] ?? 0);
    $lastDate = $vehicle['last_service_date'];

    if ($id > 0) {
        $stmt = $pdo->prepare("
            UPDATE service_intervals
            SET vehicle_id = :vehicle_id,
                interval_type = :interval_type,
                interval_km = :interval_km,
                interval_days = :interval_days,
                task_description = :task_description,
                is_active = :is_active,
                last_service_date = :last_service_date,
                last_service_mileage = :last_service_mileage,
                due_date = :due_date,
                due_mileage = :due_mileage
            WHERE id = :id AND deleted_at IS NULL
        ");
    } else {
        $stmt = $pdo->prepare("
            INSERT INTO service_intervals
                (vehicle_id, interval_type, interval_km, interval_days, task_description, is_active,
                 last_service_date, last_service_mileage, due_date, due_mileage)
            VALUES
                (:vehicle_id, :interval_type, :interval_km, :interval_days, :task_description, :is_active,
                 :last_service_date, :last_service_mileage, :due_date, :due_mileage)
        ");
    }

    $lastOdo = $lastOdo ?: $odometer;
    $dueMileage = $lastOdo + $intervalKm;

    $dueDate = null;
    if ($lastDate && $intervalDays > 0) {
        $d = new DateTime($lastDate);
        $d->modify("+$intervalDays days");
        $dueDate = $d->format('Y-m-d');
    }

    $payload = [
        'vehicle_id' => $vehicleId,
        'interval_type' => $intervalType,
        'interval_km' => $intervalKm,
        'interval_days' => $intervalDays,
        'task_description' => $taskDescription,
        'is_active' => $isActive,
        'last_service_date' => $lastDate,
        'last_service_mileage' => $lastOdo,
        'due_date' => $dueDate,
        'due_mileage' => $dueMileage,
    ];

    if ($id > 0) {
        $payload['id'] = $id;
    }

    $stmt->execute($payload);

    if ($id === 0) {
        $id = (int)$pdo->lastInsertId();
    }

    audit($pdo, (int)$_SESSION['user_id'], $id > 0 ? 'update' : 'create', 'service_interval', $id, 'Service interval saved');
    respond(['status' => 'success', 'data' => ['id' => $id]]);
}

function handleDeleteServiceInterval(PDO $pdo): void
{
    enforceMaintenanceWritePermission();
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) {
        respond(['status' => 'error', 'message' => 'Invalid ID']);
    }
    $stmt = $pdo->prepare("UPDATE service_intervals SET deleted_at = NOW() WHERE id = ? AND deleted_at IS NULL");
    $stmt->execute([$id]);
    audit($pdo, (int)$_SESSION['user_id'], 'delete', 'service_interval', $id, 'Service interval deleted');
    respond(['status' => 'success']);
}

function handleCheckDueServices(PDO $pdo): void
{
    $rows = $pdo->query("
        SELECT
            si.id,
            si.vehicle_id,
            si.task_description,
            si.interval_type,
            si.interval_km,
            si.interval_days,
            si.due_date,
            si.due_mileage,
            si.last_service_date,
            si.last_service_mileage,
            v.plate_number,
            v.vehicle_model,
            v.vehicle_type,
            v.current_odometer
        FROM service_intervals si
        JOIN vehicles v ON v.id = si.vehicle_id AND v.deleted_at IS NULL
        WHERE si.deleted_at IS NULL
          AND si.is_active = 1
          AND (
              (si.due_date IS NOT NULL AND si.due_date <= CURDATE())
              OR (si.due_mileage > 0 AND si.due_mileage <= COALESCE(v.current_odometer, 0))
          )
        ORDER BY si.due_date ASC, si.due_mileage ASC
    ")->fetchAll(PDO::FETCH_ASSOC);

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

function handleGeneratePmJob(PDO $pdo): void
{
    enforceMaintenanceWritePermission();

    $intervalId = (int)($_POST['interval_id'] ?? 0);
    if ($intervalId <= 0) {
        respond(['status' => 'error', 'message' => 'Interval ID required']);
    }

    $stmt = $pdo->prepare("
        SELECT si.*, v.plate_number, v.current_odometer
        FROM service_intervals si
        JOIN vehicles v ON v.id = si.vehicle_id AND v.deleted_at IS NULL
        WHERE si.id = ? AND si.deleted_at IS NULL AND si.is_active = 1
    ");
    $stmt->execute([$intervalId]);
    $interval = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$interval) {
        respond(['status' => 'error', 'message' => 'Service interval not found or inactive']);
    }

    $vehicleId = (int)$interval['vehicle_id'];
    $odometer = (int)($interval['current_odometer'] ?? 0);
    $lastOdo = (int)($interval['last_service_mileage'] ?? 0);
    $nextOdo = $odometer + (int)$interval['interval_km'];

    $title = 'Scheduled: ' . ($interval['task_description'] ?: 'Preventive Maintenance');

    $payload = [
        'vehicle_id' => $vehicleId,
        'driver_id' => null,
        'complaint_source' => 'Maintenance Office',
        'complaint_title' => $title,
        'complaint_description' => 'Auto-generated from service interval #' . $intervalId . ': ' . ($interval['task_description'] ?: 'PM service'),
        'complaint_date' => date('Y-m-d'),
        'complaint_log_date' => date('Y-m-d'),
        'nature_of_fault' => 'Scheduled maintenance',
        'workshop' => null,
        'current_service_mileage_km' => $odometer,
        'last_service_mileage_km' => $lastOdo,
        'next_service_mileage_km' => $nextOdo,
        'maintenance_comment' => null,
        'expected_completion_date' => null,
        'workflow_stage' => STAGE_COMPLAINT_LOGGED,
        'status' => STATUS_PENDING
    ];

    $columns = implode(', ', array_keys($payload));
    $values = implode(', ', array_map(static fn(string $col): string => ':' . $col, array_keys($payload)));

    $insertStmt = $pdo->prepare("INSERT INTO maintenance_jobs ({$columns}) VALUES ({$values})");
    $insertStmt->execute($payload);
    $jobId = (int)$pdo->lastInsertId();

    audit($pdo, (int)$_SESSION['user_id'], 'create', 'maintenance_job', $jobId, 'PM job auto-generated from service interval #' . $intervalId, null, $payload);
    logMaintenanceAction($pdo, $jobId, 'complaint_logged', STAGE_COMPLAINT_LOGGED, null, STAGE_COMPLAINT_LOGGED, null, $title);
    logJobStageHistory($pdo, $jobId, null, STAGE_COMPLAINT_LOGGED, 'complaint_logged', $title);

    // Update interval: set last_service to current, recalculate due
    $newLastOdo = $odometer;
    $newDueMileage = $newLastOdo + (int)$interval['interval_km'];
    $dueDate = null;
    if ($interval['interval_days'] > 0) {
        $d = new DateTime();
        $d->modify('+' . (int)$interval['interval_days'] . ' days');
        $dueDate = $d->format('Y-m-d');
    }

    $updateStmt = $pdo->prepare("
        UPDATE service_intervals
        SET last_service_date = CURDATE(),
            last_service_mileage = :last_mileage,
            due_date = :due_date,
            due_mileage = :due_mileage
        WHERE id = :id
    ");
    $updateStmt->execute([
        'last_mileage' => $newLastOdo,
        'due_date' => $dueDate,
        'due_mileage' => $newDueMileage,
        'id' => $intervalId
    ]);

    $pdo->prepare("UPDATE vehicles SET last_service_date = CURDATE(), last_service_odometer = ? WHERE id = ?")
        ->execute([$newLastOdo, $vehicleId]);

    respond(['status' => 'success', 'data' => ['job_id' => $jobId, 'job_title' => $title]]);
}
