<?php
declare(strict_types=1);

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../app/helpers/rbac.php';
require_once __DIR__ . '/../app/helpers/api_security.php';

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

requireApiLogin();
enforceCsrfForUnsafeRequest();

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

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

try {
    switch ($action) {
        case 'init':
            $period = max(1, (int)($_GET['period'] ?? 30));
            respond(['status' => 'success', 'data' => getInitData($pdo, $period)]);
            break;
        case 'fuel_trend':
            $months = max(1, (int)($_GET['months'] ?? 12));
            respond(['status' => 'success', 'data' => getFuelTrend($pdo, $months)]);
            break;
        case 'maintenance_chart':
            respond(['status' => 'success', 'data' => getMaintenanceChart($pdo)]);
            break;
        default:
            respond(['status' => 'error', 'message' => 'Invalid action.']);
    }
} catch (Throwable $e) {
    respond(['status' => 'error', 'message' => 'Server error: ' . $e->getMessage()]);
}

function getInitData(PDO $pdo, int $period): array
{
    $fleetStats = getFleetStats($pdo);
    $total = ($fleetStats['active_vehicles'] + $fleetStats['in_workshop'] + $fleetStats['inactive_vehicles']);
    $kpis = [
        'utilization' => $total > 0 ? round((($fleetStats['active_vehicles'] ?? 0) / $total) * 100) : 0,
        'health'      => $total > 0 ? round(((($total - ($fleetStats['in_workshop'] ?? 0)) / $total) * 100)) : 0,
        'compliance'  => ($fleetStats['total_vehicles'] ?? 0) > 0 ? round(((($fleetStats['total_vehicles'] ?? 0) - ($fleetStats['expiring_docs'] ?? 0)) / ($fleetStats['total_vehicles'] ?? 1)) * 100) : 0,
        'workflow'    => $fleetStats['pending_approvals'] ?? 0,
    ];

    $alerts = getAlerts($pdo);

    $timelineData = getActivityTimeline($pdo, $period);

    $maintenance = getMaintenanceIntelligence($pdo);

    $fuel = getFuelAnalytics($pdo);

    $fleetTable = getFleetSnapshot($pdo, '');

    $actionBuckets = bucketActions($timelineData['feed']);

    return [
        'fleet_stats'        => $fleetStats,
        'kpis'               => $kpis,
        'alerts'             => $alerts,
        'activity_timeline'  => $timelineData['timeline'],
        'activity_feed'      => $timelineData['feed'],
        'action_buckets'    => $actionBuckets,
        'maintenance'         => $maintenance,
        'fuel'               => $fuel,
        'fleet_table'        => $fleetTable,
    ];
}

function bucketActions(array $feed): array
{
    $buckets = ['Fuel' => 0, 'Maintenance' => 0, 'Driver' => 0, 'Vehicle' => 0, 'Compliance' => 0, 'Other' => 0];
    foreach ($feed as $a) {
        $action = strtolower($a['action'] ?? '');
        if (str_contains($action, 'fuel')) $buckets['Fuel']++;
        elseif (str_contains($action, 'maint')) $buckets['Maintenance']++;
        elseif (str_contains($action, 'driver')) $buckets['Driver']++;
        elseif (str_contains($action, 'vehicle') || str_contains($action, 'assign')) $buckets['Vehicle']++;
        elseif (str_contains($action, 'compli') || str_contains($action, 'insur') || str_contains($action, 'license')) $buckets['Compliance']++;
        else $buckets['Other']++;
    }
    $result = [];
    foreach ($buckets as $label => $count) {
        if ($count > 0) $result[$label] = $count;
    }
    return $result ?: ['No activity' => 1];
}

function getFleetStats(PDO $pdo): array
{
    $activeVehicles  = (int)$pdo->query("SELECT COUNT(*) FROM vehicles WHERE LOWER(TRIM(vehicle_status)) = 'active' AND deleted_at IS NULL")->fetchColumn();
    $totalVehicles   = (int)$pdo->query("SELECT COUNT(*) FROM vehicles WHERE deleted_at IS NULL")->fetchColumn();
    $inactiveVehicles = $totalVehicles - $activeVehicles;
    $activeDrivers   = (int)$pdo->query("SELECT COUNT(*) FROM drivers WHERE active_status = 1 AND deleted_at IS NULL")->fetchColumn();
    $inWorkshop      = (int)$pdo->query("SELECT COUNT(*) FROM vehicles WHERE LOWER(TRIM(vehicle_status)) = 'in workshop' AND deleted_at IS NULL")->fetchColumn();
    $expiringDocs    = (int)$pdo->query("SELECT COUNT(*) FROM (SELECT valid_until FROM vehicle_licenses WHERE valid_until BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND deleted_at IS NULL UNION ALL SELECT expiration_date FROM roadworthiness WHERE expiration_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND deleted_at IS NULL UNION ALL SELECT coverage_end FROM vehicle_insurance_policies WHERE coverage_end BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND deleted_at IS NULL UNION ALL SELECT valid_until FROM driver_licenses WHERE valid_until BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND deleted_at IS NULL) x")->fetchColumn();
    $pendingApprovals = (int)$pdo->query("SELECT COUNT(*) FROM maintenance_approvals WHERE LOWER(TRIM(approval_status)) = 'pending'")->fetchColumn();
    $maintenanceComplaints = (int)$pdo->query("SELECT COUNT(*) FROM maintenance_jobs WHERE (status IS NULL OR LOWER(TRIM(status)) != 'completed') AND deleted_at IS NULL")->fetchColumn();

    return [
        'active_vehicles'       => $activeVehicles,
        'total_vehicles'        => $totalVehicles,
        'inactive_vehicles'     => $inactiveVehicles,
        'active_drivers'        => $activeDrivers,
        'in_workshop'           => $inWorkshop,
        'expiring_docs'         => $expiringDocs,
        'pending_approvals'     => $pendingApprovals,
        'maintenance_complaints' => $maintenanceComplaints,
    ];
}

function getFuelTrend(PDO $pdo, int $months): array
{
    $stmt = $pdo->prepare("SELECT DATE_FORMAT(record_date, '%b %Y') AS label, SUM(COALESCE(total_amount, 0)) AS total_cost FROM vehicle_fuel_entries WHERE record_date >= DATE_SUB(CURDATE(), INTERVAL :months MONTH) GROUP BY YEAR(record_date), MONTH(record_date) ORDER BY YEAR(record_date), MONTH(record_date)");
    $stmt->bindValue(':months', $months, PDO::PARAM_INT);
    $stmt->execute();
    $labels = []; $values = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $labels[] = $row['label'];
        $values[] = (float)$row['total_cost'];
    }
    return ['labels' => $labels, 'values' => $values];
}

function getMaintenanceChart(PDO $pdo): array
{
    $stmt = $pdo->query("SELECT DATE_FORMAT(complaint_date, '%b %Y') AS label, SUM(cost_of_repair) AS total_cost FROM maintenance_jobs WHERE complaint_date >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH) AND deleted_at IS NULL GROUP BY YEAR(complaint_date), MONTH(complaint_date) ORDER BY YEAR(complaint_date), MONTH(complaint_date)");
    $labels = []; $values = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $labels[] = $row['label'];
        $values[] = (float)$row['total_cost'];
    }
    return ['labels' => $labels, 'values' => $values];
}

function getAlerts(PDO $pdo): array
{
    $sql = "SELECT title, description, days_left, due_date, severity FROM (
        SELECT CONCAT('Vehicle License: ', v.plate_number) AS title, CONCAT('Vehicle license expires on ', DATE_FORMAT(vl.valid_until, '%d-%b-%Y')) AS description, DATEDIFF(vl.valid_until, CURDATE()) AS days_left, DATE_FORMAT(vl.valid_until, '%Y-%m-%d') AS due_date,
            CASE WHEN DATEDIFF(vl.valid_until, CURDATE()) <= 3 THEN 'critical' WHEN DATEDIFF(vl.valid_until, CURDATE()) <= 10 THEN 'warning' ELSE 'info' END AS severity
        FROM vehicle_licenses vl INNER JOIN vehicles v ON v.id = vl.vehicle_id WHERE vl.valid_until BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND vl.deleted_at IS NULL
        UNION ALL
        SELECT CONCAT('Insurance: ', v.plate_number), CONCAT('Insurance expires on ', DATE_FORMAT(vi.expiration_date, '%d-%b-%Y')), DATEDIFF(vi.expiration_date, CURDATE()), DATE_FORMAT(vi.expiration_date, '%Y-%m-%d'),
            CASE WHEN DATEDIFF(vi.expiration_date, CURDATE()) <= 3 THEN 'critical' WHEN DATEDIFF(vi.expiration_date, CURDATE()) <= 10 THEN 'warning' ELSE 'info' END
        FROM vehicle_insurance vi INNER JOIN vehicles v ON v.id = vi.vehicle_id WHERE vi.expiration_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND vi.deleted_at IS NULL
        UNION ALL
        SELECT CONCAT('Driver License: ', d.full_name), CONCAT('Driver license expires on ', DATE_FORMAT(dl.valid_until, '%d-%b-%Y')), DATEDIFF(dl.valid_until, CURDATE()), DATE_FORMAT(dl.valid_until, '%Y-%m-%d'),
            CASE WHEN DATEDIFF(dl.valid_until, CURDATE()) <= 3 THEN 'critical' WHEN DATEDIFF(dl.valid_until, CURDATE()) <= 10 THEN 'warning' ELSE 'info' END
        FROM driver_licenses dl INNER JOIN drivers d ON d.id = dl.driver_id WHERE dl.valid_until BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND dl.deleted_at IS NULL
    ) q ORDER BY days_left ASC LIMIT 10";
    $stmt = $pdo->query($sql);
    $rows = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $row['days_left_text'] = ((int)$row['days_left']) . ' day(s) left';
        $rows[] = $row;
    }
    return $rows;
}

function getFleetSnapshot(PDO $pdo, string $search): array
{
    $sql = "SELECT v.id AS vehicle_id, v.plate_number, CONCAT(COALESCE(v.vehicle_model, ''), ' ', COALESCE(v.vehicle_type, '')) AS vehicle_model,
        COALESCE((SELECT d2.full_name FROM vehicle_assignments va2 INNER JOIN drivers d2 ON d2.id = va2.driver_id WHERE va2.vehicle_id = v.id AND va2.status = 'active' AND va2.deleted_at IS NULL ORDER BY va2.assignment_start DESC LIMIT 1), 'Unassigned') AS driver_name,
        CASE WHEN TRIM(LOWER(v.vehicle_status)) = 'active' THEN 'active' WHEN TRIM(LOWER(v.vehicle_status)) = 'in workshop' THEN 'workshop' WHEN TRIM(LOWER(v.vehicle_status)) = 'maintenance' THEN 'maintenance' ELSE LOWER(REPLACE(COALESCE(v.vehicle_status, 'unknown'), ' ', '_')) END AS status,
        CASE WHEN v.contract_id IS NOT NULL OR LOWER(COALESCE(v.vehicle_source, '')) LIKE '%lease%' THEN 'leased' ELSE 'owned' END AS fleet_mode,
        COALESCE((SELECT mj2.next_service_mileage_km FROM maintenance_jobs mj2 WHERE mj2.vehicle_id = v.id AND mj2.next_service_mileage_km IS NOT NULL AND mj2.deleted_at IS NULL ORDER BY mj2.created_at DESC LIMIT 1), 0) AS next_service_km,
        CASE WHEN EXISTS (SELECT 1 FROM maintenance_jobs mj3 WHERE mj3.vehicle_id = v.id AND mj3.deleted_at IS NULL ORDER BY mj3.created_at DESC LIMIT 1) THEN (SELECT CASE WHEN mj4.workflow_stage IS NULL OR TRIM(mj4.workflow_stage) = '' THEN 'pending' WHEN LOWER(TRIM(mj4.workflow_stage)) IN ('completed','closed','payment made') THEN 'completed' ELSE LOWER(REPLACE(mj4.workflow_stage, ' ', '_')) END FROM maintenance_jobs mj4 WHERE mj4.vehicle_id = v.id AND mj4.deleted_at IS NULL ORDER BY mj4.created_at DESC LIMIT 1) ELSE 'pending' END AS maintenance_status,
        CASE WHEN EXISTS (SELECT 1 FROM vehicle_licenses vl2 WHERE vl2.vehicle_id = v.id AND vl2.valid_until < CURDATE() AND vl2.deleted_at IS NULL) THEN 'expired' WHEN EXISTS (SELECT 1 FROM vehicle_licenses vl2 WHERE vl2.vehicle_id = v.id AND vl2.valid_until BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY) AND vl2.deleted_at IS NULL) THEN 'expiring' ELSE 'valid' END AS compliance_status,
        v.vehicle_type
        FROM vehicles v WHERE v.deleted_at IS NULL
        AND (v.plate_number LIKE :search OR v.vehicle_model LIKE :search OR v.vehicle_type LIKE :search OR EXISTS (SELECT 1 FROM vehicle_assignments va3 INNER JOIN drivers d3 ON d3.id = va3.driver_id WHERE va3.vehicle_id = v.id AND va3.status = 'active' AND d3.full_name LIKE :search2 AND va3.deleted_at IS NULL))
        ORDER BY v.plate_number ASC LIMIT 20";
    $stmt = $pdo->prepare($sql);
    $like = '%' . $search . '%';
    $stmt->bindValue(':search', $like, PDO::PARAM_STR);
    $stmt->bindValue(':search2', $like, PDO::PARAM_STR);
    $stmt->execute();
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

function getActivityTimeline(PDO $pdo, int $period): array
{
    $stmt = $pdo->prepare("SELECT DATE(created_at) AS date, COUNT(*) AS total FROM audit_logs WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL :days DAY) GROUP BY DATE(created_at) ORDER BY DATE(created_at)");
    $stmt->bindValue(':days', $period, PDO::PARAM_INT);
    $stmt->execute();
    $timeline = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $timeline[] = ['date' => date('M j', strtotime($row['date'])), 'count' => (int)$row['total']];
    }
    $feedStmt = $pdo->prepare("SELECT al.id, al.action, al.module, al.description, al.created_at, u.name AS user_name FROM audit_logs al LEFT JOIN users u ON u.id = al.user_id ORDER BY al.created_at DESC LIMIT 12");
    $feedStmt->execute();
    $feed = [];
    while ($row = $feedStmt->fetch(PDO::FETCH_ASSOC)) {
        $feed[] = [
            'id' => (int)$row['id'],
            'action' => $row['action'] ?? '',
            'type' => $row['action'] ?? 'activity',
            'title' => ucfirst(trim(($row['action'] ?? '') . ' ' . ($row['module'] ?? ''))),
            'description' => $row['description'] ?? ($row['action'] ?? 'Action completed'),
            'timestamp' => $row['created_at'],
        ];
    }
    return ['timeline' => $timeline, 'feed' => $feed];
}

function getMaintenanceIntelligence(PDO $pdo): array
{
    $stmt = $pdo->query("SELECT COALESCE(workflow_stage, 'Unknown') AS stage, COUNT(*) AS total FROM maintenance_jobs WHERE deleted_at IS NULL GROUP BY workflow_stage ORDER BY total DESC");
    $stages = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $stages[$row['stage']] = (int)$row['total'];
    }
    return ['stages' => $stages];
}

function getFuelAnalytics(PDO $pdo): array
{
    $stmt = $pdo->query("SELECT DATE_FORMAT(record_date, '%b %Y') AS label, SUM(COALESCE(total_amount, 0)) AS total_cost FROM vehicle_fuel_entries WHERE record_date >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH) GROUP BY YEAR(record_date), MONTH(record_date) ORDER BY YEAR(record_date), MONTH(record_date)");
    $monthly = [];
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $monthly[$row['label']] = (float)$row['total_cost'];
    }
    return ['monthly' => $monthly];
}