<?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('expense.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 'categories': handleCategories($pdo); break;
        case 'summary': handleSummary($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 handleList(PDO $pdo): void
{
    $where = ['e.deleted_at IS NULL'];
    $params = [];

    if (!empty($_GET['vehicle_id'])) {
        $where[] = 'e.vehicle_id = :vehicle_id';
        $params['vehicle_id'] = (int)$_GET['vehicle_id'];
    }
    if (!empty($_GET['category_id'])) {
        $where[] = 'e.category_id = :category_id';
        $params['category_id'] = (int)$_GET['category_id'];
    }
    if (!empty($_GET['date_from'])) {
        $where[] = 'e.expense_date >= :date_from';
        $params['date_from'] = $_GET['date_from'];
    }
    if (!empty($_GET['date_to'])) {
        $where[] = 'e.expense_date <= :date_to';
        $params['date_to'] = $_GET['date_to'];
    }

    $whereSql = implode(' AND ', $where);
    $stmt = $pdo->prepare("
        SELECT e.*, v.plate_number, ec.name AS category_name, d.full_name AS driver_name
        FROM vehicle_expenses e
        LEFT JOIN vehicles v ON v.id = e.vehicle_id
        LEFT JOIN expense_categories ec ON ec.id = e.category_id
        LEFT JOIN drivers d ON d.id = e.driver_id
        WHERE {$whereSql}
        ORDER BY e.expense_date DESC, e.id DESC
    ");
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

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

    $id = (int)($_POST['id'] ?? 0);
    $data = [
        'vehicle_id' => (int)($_POST['vehicle_id'] ?? 0),
        'category_id' => !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null,
        'expense_date' => $_POST['expense_date'] ?? '',
        'amount' => (float)($_POST['amount'] ?? 0),
        'description' => trim($_POST['description'] ?? ''),
        'driver_id' => !empty($_POST['driver_id']) ? (int)$_POST['driver_id'] : null,
        'receipt_url' => trim($_POST['receipt_url'] ?? ''),
        'reference_number' => trim($_POST['reference_number'] ?? ''),
        'notes' => trim($_POST['notes'] ?? ''),
    ];

    if (!$data['vehicle_id'] || $data['amount'] <= 0 || !$data['expense_date']) {
        respond(['status' => 'error', 'message' => 'Vehicle, amount, and expense date are required']);
    }

    if ($id > 0) {
        $data['updated_at'] = date('Y-m-d H:i:s');
        $data['id'] = $id;
        $sets = [];
        foreach ($data as $col => $val) {
            $sets[] = "{$col} = :{$col}";
        }
        $pdo->prepare("UPDATE vehicle_expenses SET " . implode(', ', $sets) . " WHERE id = :id")->execute($data);
        respond(['status' => 'success', 'message' => 'Expense updated']);
    } else {
        $data['created_by'] = (int)($_SESSION['user_id'] ?? 0);
        $cols = implode(', ', array_keys($data));
        $vals = ':' . implode(', :', array_keys($data));
        $pdo->prepare("INSERT INTO vehicle_expenses ({$cols}) VALUES ({$vals})")->execute($data);
        respond(['status' => 'success', 'message' => 'Expense created', 'id' => (int)$pdo->lastInsertId()]);
    }
}

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

function handleCategories(PDO $pdo): void
{
    $stmt = $pdo->query("SELECT * FROM expense_categories ORDER BY name ASC");
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

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

    if (!empty($_GET['date_from'])) {
        $where .= ' AND e.expense_date >= :date_from';
        $params['date_from'] = $_GET['date_from'];
    }
    if (!empty($_GET['date_to'])) {
        $where .= ' AND e.expense_date <= :date_to';
        $params['date_to'] = $_GET['date_to'];
    }
    if (!empty($_GET['vehicle_id'])) {
        $where .= ' AND e.vehicle_id = :vehicle_id';
        $params['vehicle_id'] = (int)$_GET['vehicle_id'];
    }

    $total = $pdo->prepare("SELECT COUNT(*), COALESCE(SUM(amount),0) FROM vehicle_expenses WHERE {$where}");
    $total->execute($params);

    $byCategory = $pdo->prepare("
        SELECT ec.name, COALESCE(SUM(e.amount),0) AS total, COUNT(*) AS count
        FROM vehicle_expenses e
        LEFT JOIN expense_categories ec ON ec.id = e.category_id
        WHERE e.{$where}
        GROUP BY ec.name
        ORDER BY total DESC
    ");
    $byCategory->execute($params);

    $recent = $pdo->prepare("
        SELECT e.*, v.plate_number, ec.name AS category_name
        FROM vehicle_expenses e
        LEFT JOIN vehicles v ON v.id = e.vehicle_id
        LEFT JOIN expense_categories ec ON ec.id = e.category_id
        WHERE e.{$where}
        ORDER BY e.expense_date DESC LIMIT 10
    ");
    $recent->execute($params);

    respond(['status' => 'success', 'data' => [
        'totals' => $total->fetch(),
        'by_category' => $byCategory->fetchAll(),
        'recent' => $recent->fetchAll(),
    ]]);
}
