<?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('insurance.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 'claims': handleClaims($pdo); break;
        case 'save_claim': handleSaveClaim($pdo); break;
        case 'delete_claim': handleDeleteClaim($pdo); break;
        case 'insurers': handleInsurers($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, 'insurance', $recordId ?? 0, $description, null, null);
}

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

    if (!empty($_GET['vehicle_id'])) {
        $where[] = 'p.vehicle_id = :vehicle_id';
        $params['vehicle_id'] = (int)$_GET['vehicle_id'];
    }
    if (!empty($_GET['status'])) {
        $where[] = 'p.is_active = :status';
        $params['status'] = $_GET['status'] === 'active' ? 1 : 0;
    }
    if (!empty($_GET['expiring_soon'])) {
        $where[] = 'p.coverage_end BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY)';
    }
    if (!empty($_GET['expired'])) {
        $where[] = 'p.coverage_end < CURDATE()';
    }

    $whereSql = implode(' AND ', $where);
    $stmt = $pdo->prepare("
        SELECT p.id, p.vehicle_id, p.insurer_id, p.policy_number, p.policy_type, p.coverage_start, p.coverage_end, p.premium_amount, p.is_active, p.notes, p.created_at, p.updated_at, p.deleted_at,
               v.plate_number, v.vehicle_model,
               COALESCE(i.name, p.insurer_name) AS insurer_name,
               DATEDIFF(p.coverage_end, CURDATE()) AS days_remaining,
               (SELECT COUNT(*) FROM insurance_claims WHERE policy_id = p.id) AS claim_count
        FROM vehicle_insurance_policies p
        LEFT JOIN vehicles v ON v.id = p.vehicle_id
        LEFT JOIN insurers i ON i.id = p.insurer_id
        WHERE {$whereSql}
        ORDER BY p.coverage_end ASC, p.id DESC
    ");
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

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

    $id = (int)($_POST['id'] ?? 0);
    $data = [
        'vehicle_id' => (int)($_POST['vehicle_id'] ?? 0),
        'insurer_id' => !empty($_POST['insurer_id']) ? (int)$_POST['insurer_id'] : null,
        'policy_number' => trim($_POST['policy_number'] ?? ''),
        'insurer_name' => trim($_POST['insurer_name'] ?? ''),
        'policy_type' => $_POST['policy_type'] ?? 'comprehensive',
        'coverage_start' => $_POST['coverage_start'] ?? '',
        'coverage_end' => $_POST['coverage_end'] ?? '',
        'premium_amount' => !empty($_POST['premium_amount']) ? (float)$_POST['premium_amount'] : null,
        'is_active' => (int)($_POST['is_active'] ?? 1),
        'notes' => trim($_POST['notes'] ?? ''),
    ];

    // Auto-populate insurer_name from insurers table if insurer_id provided
    if ($data['insurer_id']) {
        $stmt = $pdo->prepare("SELECT name FROM insurers WHERE id = :id");
        $stmt->execute(['id' => $data['insurer_id']]);
        $insurerName = $stmt->fetchColumn();
        if ($insurerName) $data['insurer_name'] = $insurerName;
    }

    if (!$data['vehicle_id'] || !$data['policy_number'] || !$data['insurer_name'] || !$data['coverage_start'] || !$data['coverage_end']) {
        respond(['status' => 'error', 'message' => 'Vehicle, policy number, insurer, coverage start, and coverage end 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_insurance_policies SET " . implode(', ', $sets) . " WHERE id = :id")->execute($data);
        doAudit($pdo, 'update', "Policy #{$id} updated", $id);
        respond(['status' => 'success', 'message' => 'Policy 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_insurance_policies ({$cols}) VALUES ({$vals})")->execute($data);
        $newId = (int)$pdo->lastInsertId();
        doAudit($pdo, 'create', "Policy created for vehicle #{$data['vehicle_id']}", $newId);
        respond(['status' => 'success', 'message' => 'Policy created', 'id' => $newId]);
    }
}

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

function handleClaims(PDO $pdo): void
{
    $where = ['1=1'];
    $params = [];

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

    $whereSql = implode(' AND ', $where);
    $stmt = $pdo->prepare("
        SELECT c.*, p.policy_number, p.insurer_name, v.plate_number
        FROM insurance_claims c
        LEFT JOIN vehicle_insurance_policies p ON p.id = c.policy_id
        LEFT JOIN vehicles v ON v.id = p.vehicle_id
        WHERE {$whereSql}
        ORDER BY c.incident_date DESC, c.id DESC
    ");
    $stmt->execute($params);
    respond(['status' => 'success', 'data' => $stmt->fetchAll()]);
}

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

    $id = (int)($_POST['id'] ?? 0);
    $data = [
        'policy_id' => (int)($_POST['policy_id'] ?? 0),
        'claim_number' => trim($_POST['claim_number'] ?? ''),
        'incident_date' => $_POST['incident_date'] ?? null,
        'claim_amount' => !empty($_POST['claim_amount']) ? (float)$_POST['claim_amount'] : null,
        'settlement_amount' => !empty($_POST['settlement_amount']) ? (float)$_POST['settlement_amount'] : null,
        'payment_date' => $_POST['payment_date'] ?? null,
        'status' => $_POST['status'] ?? 'filed',
        'description' => trim($_POST['description'] ?? ''),
    ];

    if (!$data['policy_id']) {
        respond(['status' => 'error', 'message' => 'Policy 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 insurance_claims SET " . implode(', ', $sets) . " WHERE id = :id")->execute($data);
        doAudit($pdo, 'update', "Claim #{$id} updated", $id);
        respond(['status' => 'success', 'message' => 'Claim updated']);
    } else {
        $cols = implode(', ', array_keys($data));
        $vals = ':' . implode(', :', array_keys($data));
        $pdo->prepare("INSERT INTO insurance_claims ({$cols}) VALUES ({$vals})")->execute($data);
        $newId = (int)$pdo->lastInsertId();
        doAudit($pdo, 'create', "Claim created for policy #{$data['policy_id']}", $newId);
        respond(['status' => 'success', 'message' => 'Claim created', 'id' => $newId]);
    }
}

function handleDeleteClaim(PDO $pdo): void
{
    if (!isAdmin() && !can('insurance.delete')) {
        respond(['status' => 'error', 'message' => 'Unauthorized']);
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) respond(['status' => 'error', 'message' => 'Invalid ID']);
    $pdo->prepare("DELETE FROM insurance_claims WHERE id = :id")->execute(['id' => $id]);
    doAudit($pdo, 'delete', "Claim #{$id} deleted", $id);
    respond(['status' => 'success', 'message' => 'Claim deleted']);
}

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