<?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('tyre.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 'retreads': handleRetreads($pdo); break;
        case 'save_retread': handleSaveRetread($pdo); break;
        case 'tyre_brands': handleTyreBrands($pdo); break;
        case 'tyre_models': handleTyreModels($pdo); break;
        case 'fit': handleFit($pdo); break;
        case 'remove': handleRemove($pdo); break;
        case 'scrap': handleScrap($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, 'tyre', $recordId ?? 0, $description, null, null);
}

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

    if (!empty($_GET['vehicle_id'])) {
        $where[] = 't.vehicle_id = :vehicle_id';
        $params['vehicle_id'] = (int)$_GET['vehicle_id'];
    }
    if (!empty($_GET['status'])) {
        $where[] = 't.status = :status';
        $params['status'] = $_GET['status'];
    }
    if (!empty($_GET['position'])) {
        $where[] = 't.position = :position';
        $params['position'] = $_GET['position'];
    }

    $whereSql = implode(' AND ', $where);
    $stmt = $pdo->prepare("
        SELECT t.*, v.plate_number,
               COALESCE(b.name, t.brand) AS brand,
               COALESCE(m.name, t.model) AS model,
               b.name AS brand_name, m.name AS model_name
        FROM tyres t
        LEFT JOIN vehicles v ON v.id = t.vehicle_id
        LEFT JOIN tyre_brands b ON b.id = t.brand_id AND b.deleted_at IS NULL
        LEFT JOIN tyre_models m ON m.id = t.model_id AND m.deleted_at IS NULL
        WHERE {$whereSql}
        ORDER BY t.purchase_date DESC, t.id DESC
    ");
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

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

    $id = (int)($_POST['id'] ?? 0);
    $brandId = !empty($_POST['brand_id']) ? (int)$_POST['brand_id'] : null;
    $modelId = !empty($_POST['model_id']) ? (int)$_POST['model_id'] : null;
    $brand = trim($_POST['brand'] ?? '');
    $model = trim($_POST['model'] ?? '');

    // Auto-fill brand from tyre_brands
    if ($brandId && !$brand) {
        $s = $pdo->prepare("SELECT name FROM tyre_brands WHERE id = :id AND deleted_at IS NULL");
        $s->execute(['id' => $brandId]);
        $r = $s->fetch();
        if ($r) $brand = $r['name'];
    }
    // Auto-fill model from tyre_models
    if ($modelId && !$model) {
        $s = $pdo->prepare("SELECT name FROM tyre_models WHERE id = :id AND deleted_at IS NULL");
        $s->execute(['id' => $modelId]);
        $r = $s->fetch();
        if ($r) $model = $r['name'];
    }

    $data = [
        'vehicle_id' => !empty($_POST['vehicle_id']) ? (int)$_POST['vehicle_id'] : null,
        'brand_id' => $brandId,
        'model_id' => $modelId,
        'brand' => $brand,
        'model' => $model,
        'size' => trim($_POST['size'] ?? ''),
        'serial_number' => trim($_POST['serial_number'] ?? ''),
        'position' => $_POST['position'] ?? null,
        'purchase_date' => $_POST['purchase_date'] ?? null,
        'purchase_cost' => !empty($_POST['purchase_cost']) ? (float)$_POST['purchase_cost'] : null,
        'status' => $_POST['status'] ?? 'in_stock',
        'notes' => trim($_POST['notes'] ?? ''),
    ];

    if (!$brand && !$data['serial_number']) {
        respond(['status' => 'error', 'message' => 'Brand or serial number is 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 tyres SET " . implode(', ', $sets) . " WHERE id = :id")->execute($data);
        doAudit($pdo, 'update', "Tyre #{$id} updated", $id);
        respond(['status' => 'success', 'message' => 'Tyre updated']);
    } else {
        $cols = implode(', ', array_keys($data));
        $vals = ':' . implode(', :', array_keys($data));
        $pdo->prepare("INSERT INTO tyres ({$cols}) VALUES ({$vals})")->execute($data);
        $newId = (int)$pdo->lastInsertId();
        doAudit($pdo, 'create', "Tyre #{$newId} created", $newId);
        respond(['status' => 'success', 'message' => 'Tyre created', 'id' => $newId]);
    }
}

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

function handleTyreBrands(PDO $pdo): void
{
    $stmt = $pdo->query("SELECT id, name, description FROM tyre_brands WHERE deleted_at IS NULL AND is_active = 1 ORDER BY name ASC");
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function handleTyreModels(PDO $pdo): void
{
    $where = ['m.deleted_at IS NULL', 'm.is_active = 1'];
    $params = [];
    if (!empty($_GET['brand_id'])) {
        $where[] = 'm.brand_id = :brand_id';
        $params['brand_id'] = (int)$_GET['brand_id'];
    }
    $stmt = $pdo->prepare("SELECT m.id, m.name, m.brand_id, b.name AS brand_name FROM tyre_models m LEFT JOIN tyre_brands b ON b.id = m.brand_id AND b.deleted_at IS NULL WHERE " . implode(' AND ', $where) . " ORDER BY m.name ASC");
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function handleFit(PDO $pdo): void
{
    if (!isAdmin() && !can('tyre.edit')) respond(['status' => 'error', 'message' => 'Unauthorized']);
    $id = (int)($_POST['id'] ?? 0);
    $vehicleId = (int)($_POST['vehicle_id'] ?? 0);
    $position = $_POST['position'] ?? null;
    $odometer = !empty($_POST['odometer_at_fitment']) ? (int)$_POST['odometer_at_fitment'] : null;

    if ($id <= 0 || $vehicleId <= 0) respond(['status' => 'error', 'message' => 'Invalid tyre or vehicle']);
    $pdo->prepare("UPDATE tyres SET vehicle_id = :vid, position = :pos, odometer_at_fitment = :odo, status = 'fitted', fit_date = CURDATE(), updated_at = NOW() WHERE id = :id")
        ->execute(['vid' => $vehicleId, 'pos' => $position, 'odo' => $odometer, 'id' => $id]);
    doAudit($pdo, 'fit', "Tyre #{$id} fitted to vehicle #{$vehicleId}", $id);
    respond(['status' => 'success', 'message' => 'Tyre fitted']);
}

function handleRemove(PDO $pdo): void
{
    if (!isAdmin() && !can('tyre.edit')) respond(['status' => 'error', 'message' => 'Unauthorized']);
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);
    $pdo->prepare("UPDATE tyres SET removed_date = CURDATE(), vehicle_id = NULL, position = NULL, status = 'in_stock', updated_at = NOW() WHERE id = :id")->execute(['id' => $id]);
    doAudit($pdo, 'remove', "Tyre #{$id} removed from vehicle", $id);
    respond(['status' => 'success', 'message' => 'Tyre removed']);
}

function handleScrap(PDO $pdo): void
{
    if (!isAdmin() && !can('tyre.edit')) respond(['status' => 'error', 'message' => 'Unauthorized']);
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);
    $pdo->prepare("UPDATE tyres SET removed_date = CURDATE(), status = 'scrapped', vehicle_id = NULL, updated_at = NOW() WHERE id = :id")->execute(['id' => $id]);
    doAudit($pdo, 'scrap', "Tyre #{$id} scrapped", $id);
    respond(['status' => 'success', 'message' => 'Tyre scrapped']);
}

function handleRetreads(PDO $pdo): void
{
    $stmt = $pdo->prepare("
        SELECT r.*, t.brand, t.serial_number, t.size, v.plate_number
        FROM tyre_retreads r
        LEFT JOIN tyres t ON t.id = r.tyre_id
        LEFT JOIN vehicles v ON v.id = t.vehicle_id
        WHERE r.tyre_id = :tyre_id
        ORDER BY r.retread_date DESC
    ");
    $stmt->execute(['tyre_id' => (int)($_GET['tyre_id'] ?? 0)]);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

function handleSaveRetread(PDO $pdo): void
{
    if (!isAdmin() && !can('tyre.edit')) respond(['status' => 'error', 'message' => 'Unauthorized']);
    $tyreId = (int)($_POST['tyre_id'] ?? 0);
    $data = [
        'tyre_id' => $tyreId,
        'retread_date' => $_POST['retread_date'] ?? date('Y-m-d'),
        'retread_cost' => !empty($_POST['retread_cost']) ? (float)$_POST['retread_cost'] : null,
        'vendor_name' => trim($_POST['vendor_name'] ?? ''),
        'notes' => trim($_POST['notes'] ?? ''),
    ];
    if ($tyreId <= 0) respond(['status' => 'error', 'message' => 'Invalid tyre']);

    $pdo->prepare("INSERT INTO tyre_retreads (tyre_id, retread_date, retread_cost, vendor_name, notes) VALUES (:tyre_id, :retread_date, :retread_cost, :vendor_name, :notes)")->execute($data);
    $pdo->prepare("UPDATE tyres SET status = 'retreaded', updated_at = NOW() WHERE id = :id")->execute(['id' => $tyreId]);
    doAudit($pdo, 'retread', "Tyre #{$tyreId} retreaded", $tyreId);
    respond(['status' => 'success', 'message' => 'Retread recorded']);
}
