<?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';

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

requireApiLogin();
enforceCsrfForUnsafeRequest();

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

$type = $_POST['type'] ?? ($_GET['type'] ?? '');
$action = $_GET['action'] ?? 'import';

try {
    if ($action === 'preview') {
        handlePreview($type);
    } else {
        handleImport($pdo, $type);
    }
} 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, 'import', $recordId ?? 0, $description, null, null);
}

function parseCsvUpload(): array
{
    if (empty($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
        throw new RuntimeException('File upload failed');
    }
    $handle = fopen($_FILES['file']['tmp_name'], 'r');
    if (!$handle) throw new RuntimeException('Cannot read file');

    $headers = fgetcsv($handle);
    if (!$headers) { fclose($handle); throw new RuntimeException('Empty or invalid CSV'); }

    $headers = array_map(function ($h) { return trim(str_replace("\t", '', $h)); }, $headers);
    $rows = [];
    while (($line = fgetcsv($handle)) !== false) {
        $row = [];
        foreach ($headers as $i => $h) {
            $row[$h] = $line[$i] ?? '';
        }
        $rows[] = $row;
    }
    fclose($handle);
    return ['headers' => $headers, 'rows' => $rows];
}

function sanitizeRow(array $row, array $fields): array
{
    $out = [];
    foreach ($fields as $f) {
        $out[$f] = $row[$f] ?? null;
    }
    return $out;
}

function handlePreview(string $type): void
{
    $parsed = parseCsvUpload();
    respond(['status' => 'success', 'headers' => $parsed['headers'], 'rows' => array_slice($parsed['rows'], 0, 20), 'total' => count($parsed['rows'])]);
}

function handleImport(PDO $pdo, string $type): void
{
    $parsed = parseCsvUpload();
    $rows = $parsed['rows'];
    $imported = 0;
    $errors = [];

    $pdo->beginTransaction();
    try {
        switch ($type) {
            case 'vehicles':
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['plate_number','vehicle_model','vehicle_type','year_of_manufacturing','vehicle_status']);
                    if (empty($r['plate_number'])) { $errors[] = "Row ".($i+1).": plate_number required"; continue; }
                    $pdo->prepare("INSERT INTO vehicles (plate_number, vehicle_model, vehicle_type, year_of_manufacturing, vehicle_status) VALUES (:plate_number, :vehicle_model, :vehicle_type, :year_of_manufacturing, :vehicle_status)")->execute($r);
                    $imported++;
                }
                break;
            case 'drivers':
                $batch = date('Ymd') . '-' . substr((string)microtime(true), -4);
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['surname','first_name','other_name','full_name','phone','date_of_birth','driver_id_code','driver_status']);
                    if (empty($r['surname']) || empty($r['first_name'])) { $errors[] = "Row ".($i+1).": surname and first_name required"; continue; }
                    if (empty($r['full_name'])) $r['full_name'] = trim(($r['surname'] ?? '') . ' ' . ($r['first_name'] ?? '') . ' ' . ($r['other_name'] ?? ''));
                    $r['driver_status'] = $r['driver_status'] ?? 'Active';
                    if (empty($r['driver_id_code'])) $r['driver_id_code'] = 'IMP-' . $batch . '-' . str_pad((string)($i + 1), 4, '0', STR_PAD_LEFT);
                    $pdo->prepare("INSERT INTO drivers (surname, first_name, other_name, full_name, phone, date_of_birth, driver_status, driver_id_code) VALUES (:surname, :first_name, :other_name, :full_name, :phone, :date_of_birth, :driver_status, :driver_id_code)")->execute($r);
                    $imported++;
                }
                break;
            case 'trips':
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['vehicle_id','driver_id','start_date','end_date','start_odometer','end_odometer','start_location','end_location','purpose','status','notes']);
                    if (empty($r['vehicle_id']) || empty($r['start_date'])) { $errors[] = "Row ".($i+1).": vehicle_id and start_date required"; continue; }
                    $r['created_by'] = (int)($_SESSION['user_id'] ?? 0);
                    $pdo->prepare("INSERT INTO trips (vehicle_id, driver_id, start_date, end_date, start_odometer, end_odometer, start_location, end_location, purpose, status, notes, created_by) VALUES (:vehicle_id, :driver_id, :start_date, :end_date, :start_odometer, :end_odometer, :start_location, :end_location, :purpose, :status, :notes, :created_by)")->execute($r);
                    $imported++;
                }
                break;
            case 'parts':
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['name','part_number','category_id','quantity_in_stock','reorder_level','unit_cost','supplier_name','bin_location']);
                    if (empty($r['name'])) { $errors[] = "Row ".($i+1).": name required"; continue; }
                    $pdo->prepare("INSERT INTO parts (name, part_number, category_id, quantity_in_stock, reorder_level, unit_cost, supplier_name, bin_location) VALUES (:name, :part_number, :category_id, :quantity_in_stock, :reorder_level, :unit_cost, :supplier_name, :bin_location)")->execute($r);
                    $imported++;
                }
                break;
            case 'tyres':
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['brand','size','serial_number','position','purchase_date','purchase_cost','status']);
                    if (empty($r['brand']) && empty($r['serial_number'])) { $errors[] = "Row ".($i+1).": brand or serial_number required"; continue; }
                    $pdo->prepare("INSERT INTO tyres (brand, size, serial_number, position, purchase_date, purchase_cost, status) VALUES (:brand, :size, :serial_number, :position, :purchase_date, :purchase_cost, :status)")->execute($r);
                    $imported++;
                }
                break;
            case 'expenses':
                foreach ($rows as $i => $row) {
                    $r = sanitizeRow($row, ['vehicle_id','category_id','expense_date','amount','description','driver_id']);
                    if (empty($r['vehicle_id']) || empty($r['amount'])) { $errors[] = "Row ".($i+1).": vehicle_id and amount required"; continue; }
                    $r['created_by'] = (int)($_SESSION['user_id'] ?? 0);
                    $pdo->prepare("INSERT INTO vehicle_expenses (vehicle_id, category_id, expense_date, amount, description, driver_id, created_by) VALUES (:vehicle_id, :category_id, :expense_date, :amount, :description, :driver_id, :created_by)")->execute($r);
                    $imported++;
                }
                break;
            default:
                respond(['status' => 'error', 'message' => 'Unknown import type']);
        }

        $pdo->commit();
        doAudit($pdo, 'import', "Imported {$imported} {$type}");
        respond(['status' => 'success', 'message' => "Imported {$imported} records", 'imported' => $imported, 'errors' => $errors]);
    } catch (Exception $e) {
        $pdo->rollBack();
        respond(['status' => 'error', 'message' => $e->getMessage()]);
    }
}
