<?php
declare(strict_types=1);

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

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

requireApiLogin();
enforceCsrfForUnsafeRequest();

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

try {
    switch ($action) {
        case 'list':
            handleList($pdo);
            break;
        case 'save':
            handleSave($pdo);
            break;
        case 'get':
            handleGet($pdo);
            break;
        case 'delete':
            handleDelete($pdo);
            break;
        case 'restore':
            handleRestore($pdo);
            break;
        case 'cities':
            handleCities($pdo);
            break;
        default:
            respond(['status' => 'error', 'message' => 'Invalid action']);
    }
} catch (Throwable $e) {
    respond(['status' => 'error', 'message' => $e->getMessage()]);
}

function handleList(PDO $pdo): void {
    $id = normalizeNullableInt($_GET['id'] ?? null);
    $search = trim($_GET['search'] ?? '');
    $status = trim($_GET['status'] ?? '');

    $where = ['w.deleted_at IS NULL', '(w.status = "active" OR w.status = "inactive")'];
    $params = [];

    if ($id) {
        $where[] = 'w.id = :id';
        $params['id'] = $id;
    }
    if ($status && $status !== 'all') {
        $where[] = 'w.status = :status';
        $params['status'] = $status;
    }
    if ($search) {
        $where[] = '(w.name LIKE :search OR w.contact_person LIKE :search OR w.phone LIKE :search OR w.email LIKE :search OR w.city LIKE :search OR w.vendor_type LIKE :search)';
        $params['search'] = '%' . $search . '%';
    }

    $whereSql = 'WHERE ' . implode(' AND ', $where);
    
    $stmt = $pdo->prepare("
        SELECT w.*, 
               CASE WHEN w.status = 'active' THEN '<span class=\"badge bg-success\">Active</span>' 
                    ELSE '<span class=\"badge bg-secondary\">Inactive</span>' END as status_badge
        FROM workshops w
        {$whereSql}
        ORDER BY w.name ASC
    ");
    $stmt->execute($params);
    $workshops = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $workshops = attachWorkshopQuoteStatus($pdo, $workshops);

    respond([
        'status' => 'success',
        'data' => $workshops
    ]);
}

function attachWorkshopQuoteStatus(PDO $pdo, array $workshops): array {
    $workshopIds = [];
    foreach ($workshops as $index => $workshop) {
        $workshops[$index]['quote_summary'] = emptyWorkshopQuoteSummary();
        $workshops[$index]['quote_activity'] = [];
        $workshopId = (int)($workshop['id'] ?? 0);
        if ($workshopId > 0) {
            $workshopIds[] = $workshopId;
        }
    }

    $workshopIds = array_values(array_unique($workshopIds));
    if (!$workshopIds) {
        return $workshops;
    }

    ensureWorkshopQuoteLineItemsTable($pdo);
    $placeholders = implode(',', array_fill(0, count($workshopIds), '?'));
    $stmt = $pdo->prepare("
        SELECT
            r.workshop_id,
            r.id AS rfq_id,
            r.rfq_number,
            r.rfq_sent_date,
            r.status AS rfq_status,
            mj.id AS job_id,
            mj.workflow_stage,
            COALESCE(mj.complaint_title, mj.nature_of_fault, '') AS job_title,
            v.plate_number,
            q.id AS quote_id,
            q.quote_amount,
            q.quote_received_date,
            q.status AS quote_status,
            COALESCE(qli.line_count, 0) AS quote_line_count
        FROM maintenance_rfqs r
        LEFT JOIN maintenance_jobs mj ON mj.id = r.maintenance_job_id AND mj.deleted_at IS NULL
        LEFT JOIN vehicles v ON v.id = mj.vehicle_id AND v.deleted_at IS NULL
        LEFT JOIN (
            SELECT qq.*
            FROM workshop_quotes qq
            INNER JOIN (
                SELECT rfq_id, MAX(id) AS latest_id
                FROM workshop_quotes
                GROUP BY rfq_id
            ) latest ON latest.latest_id = qq.id
        ) q ON q.rfq_id = r.id
        LEFT JOIN (
            SELECT quote_id, COUNT(*) AS line_count
            FROM workshop_quote_line_items
            GROUP BY quote_id
        ) qli ON qli.quote_id = q.id
        WHERE r.workshop_id IN ($placeholders) AND r.deleted_at IS NULL
        ORDER BY COALESCE(q.quote_received_date, r.rfq_sent_date) DESC, r.id DESC
    ");
    $stmt->execute($workshopIds);

    $activityRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $quoteLineItemsByQuote = fetchWorkshopQuoteLineItemsForRows($pdo, $activityRows);

    $byWorkshop = [];
    foreach ($activityRows as $row) {
        $workshopId = (int)($row['workshop_id'] ?? 0);
        if ($workshopId <= 0) {
            continue;
        }

        $quoteStatus = resolveQuoteStatus($row);
        $quoteAmount = (float)($row['quote_amount'] ?? 0);
        $quoteDate = $row['quote_received_date'] ?: ($row['rfq_sent_date'] ?? null);

        if (!isset($byWorkshop[$workshopId])) {
            $byWorkshop[$workshopId] = [
                'summary' => emptyWorkshopQuoteSummary(),
                'activity' => []
            ];
        }

        $summary = &$byWorkshop[$workshopId]['summary'];
        $summary['rfqs_total']++;
        if ($quoteAmount > 0) {
            $summary['total_quote_amount'] += $quoteAmount;
        }
        if ($quoteAmount > 0 && $quoteDate && (!$summary['latest_quote_date'] || strcmp((string)$quoteDate, (string)$summary['latest_quote_date']) > 0)) {
            $summary['latest_quote_date'] = $quoteDate;
            $summary['latest_quote_amount'] = $quoteAmount;
        } elseif ($quoteAmount > 0 && !$summary['latest_quote_amount']) {
            $summary['latest_quote_amount'] = $quoteAmount;
        }

        switch ($quoteStatus) {
            case 'selected':
                $summary['selected_quotes']++;
                break;
            case 'rejected':
                $summary['rejected_quotes']++;
                break;
            case 'submitted':
                $summary['submitted_quotes']++;
                break;
            default:
                $summary['pending_quotes']++;
                break;
        }
        unset($summary);

        $byWorkshop[$workshopId]['activity'][] = [
            'quote_id' => $row['quote_id'] ? (int)$row['quote_id'] : null,
            'rfq_id' => (int)$row['rfq_id'],
            'rfq_number' => $row['rfq_number'],
            'job_id' => $row['job_id'] ? (int)$row['job_id'] : null,
            'plate_number' => $row['plate_number'],
            'job_title' => $row['job_title'],
            'workflow_stage' => $row['workflow_stage'],
            'quote_status' => $quoteStatus,
            'quote_amount' => $quoteAmount > 0 ? $quoteAmount : null,
            'quote_received_date' => $row['quote_received_date'],
            'rfq_sent_date' => $row['rfq_sent_date'],
            'quote_line_count' => (int)($row['quote_line_count'] ?? 0),
            'quote_line_items' => $quoteLineItemsByQuote[(int)($row['quote_id'] ?? 0)] ?? []
        ];
    }

    foreach ($workshops as $index => $workshop) {
        $workshopId = (int)($workshop['id'] ?? 0);
        if (isset($byWorkshop[$workshopId])) {
            $workshops[$index]['quote_summary'] = $byWorkshop[$workshopId]['summary'];
            $workshops[$index]['quote_activity'] = $byWorkshop[$workshopId]['activity'];
        }
    }

    return $workshops;
}

function fetchWorkshopQuoteLineItemsForRows(PDO $pdo, array $rows): array {
    $quoteIds = [];
    foreach ($rows as $row) {
        $quoteId = (int)($row['quote_id'] ?? 0);
        if ($quoteId > 0) {
            $quoteIds[] = $quoteId;
        }
    }

    $quoteIds = array_values(array_unique($quoteIds));
    if (!$quoteIds) {
        return [];
    }

    $placeholders = implode(',', array_fill(0, count($quoteIds), '?'));
    $stmt = $pdo->prepare("
        SELECT
            quote_id,
            maintenance_line_item_id,
            item_description AS description,
            quoted_cost AS cost
        FROM workshop_quote_line_items
        WHERE quote_id IN ($placeholders)
        ORDER BY quote_id ASC, sort_order ASC, id ASC
    ");
    $stmt->execute($quoteIds);

    $grouped = [];
    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $item) {
        $grouped[(int)$item['quote_id']][] = [
            'maintenance_line_item_id' => $item['maintenance_line_item_id'] ? (int)$item['maintenance_line_item_id'] : null,
            'description' => $item['description'],
            'cost' => (float)$item['cost']
        ];
    }

    return $grouped;
}

function emptyWorkshopQuoteSummary(): array {
    return [
        'rfqs_total' => 0,
        'pending_quotes' => 0,
        'submitted_quotes' => 0,
        'selected_quotes' => 0,
        'rejected_quotes' => 0,
        'total_quote_amount' => 0,
        'latest_quote_amount' => null,
        'latest_quote_date' => null
    ];
}

function resolveQuoteStatus(array $row): string {
    $rfqStatus = strtolower(trim((string)($row['rfq_status'] ?? '')));
    $quoteStatus = strtolower(trim((string)($row['quote_status'] ?? '')));
    $amount = (float)($row['quote_amount'] ?? 0);

    if ($rfqStatus === 'selected') {
        return 'selected';
    }
    if ($rfqStatus === 'rejected') {
        return 'rejected';
    }
    if ($amount > 0 || in_array($quoteStatus, ['submitted', 'quoted'], true) || $rfqStatus === 'quoted') {
        return 'submitted';
    }
    return 'pending';
}

function ensureWorkshopQuoteLineItemsTable(PDO $pdo): void {
    // Schema is managed by database/migrations/2026_05_28_move_runtime_ddl_to_migrations.sql.
}

function handleSave(PDO $pdo): void {
    if (!can('workshop.manage') && !isAdmin()) {
        respond(['status' => 'error', 'message' => 'Insufficient permissions']);
    }

    $id = normalizeNullableInt($_POST['id'] ?? null);
    $payload = [
        'name' => normalizeString($_POST['name']),
        'contact_person' => normalizeNullableString($_POST['contact_person']),
        'phone' => normalizeNullableString($_POST['phone']),
        'email' => normalizeNullableString($_POST['email']),
        'address' => normalizeNullableString($_POST['address']),
        'city' => normalizeNullableString($_POST['city']),
        'vendor_type' => normalizeNullableString($_POST['vendor_type'] ?? 'Workshop'),
        'status' => normalizeString($_POST['status'] ?? 'active'),
    ];

    if ($payload['status'] === 'inactive') {
        $payload['inactive_reason'] = normalizeNullableString($_POST['inactive_reason']);
    } else {
        $payload['inactive_reason'] = null;
    }

    if ($id) {
        $before = fetchWorkshop($pdo, $id);
        if (!$before) {
            respond(['status' => 'error', 'message' => 'Workshop not found']);
        }

        $payload['id'] = $id;
        $set = [];
        foreach (array_keys($payload) as $k) {
            $set[] = $k . ' = :' . $k;
        }

        $stmt = $pdo->prepare('UPDATE workshops SET ' . implode(', ', $set) . ' WHERE id = :id');
        $stmt->execute($payload);

        audit($pdo, (int)$_SESSION['user_id'], 'update', 'workshop', (int)$id, 'Workshop updated');
    } else {
        $columns = implode(', ', array_keys($payload));
        $placeholders = ':' . implode(', :', array_keys($payload));
        $stmt = $pdo->prepare('INSERT INTO workshops (' . $columns . ') VALUES (' . $placeholders . ')');
        $stmt->execute($payload);
        $id = $pdo->lastInsertId();

        audit($pdo, (int)$_SESSION['user_id'], 'create', 'workshop', (int)$id, 'Workshop created');
    }

    respond(['status' => 'success', 'data' => ['id' => $id]]);
}

function fetchWorkshop(PDO $pdo, int $id): ?array {
    $stmt = $pdo->prepare('SELECT * FROM workshops WHERE id = ? AND deleted_at IS NULL');
    $stmt->execute([$id]);
    return $stmt->fetch() ?: null;
}

function normalizeString(mixed $value): string {
    return trim((string)$value) ?: '';
}

function normalizeNullableString(mixed $value): ?string {
    $val = trim((string)$value);
    return $val === '' ? null : $val;
}

function normalizeNullableInt(mixed $value): ?int {
    $val = trim((string)$value);
    return $val === '' ? null : (int)$val;
}

function handleGet(PDO $pdo): void {
    $id = normalizeNullableInt($_GET['id'] ?? null);
    if (!$id) {
        respond(['status' => 'error', 'message' => 'ID required']);
        return;
    }
    $workshop = fetchWorkshop($pdo, $id);
    if (!$workshop) {
        respond(['status' => 'error', 'message' => 'Workshop not found']);
    }
    respond(['status' => 'success', 'data' => [$workshop]]);
}

function handleDelete(PDO $pdo): void
{
    if (!isAdmin()) {
        respond(['status' => 'error', 'message' => 'Insufficient permissions']);
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) {
        respond(['status' => 'error', 'message' => 'Invalid workshop ID']);
    }
    $before = fetchWorkshop($pdo, $id);
    if (!$before) {
        respond(['status' => 'error', 'message' => 'Workshop not found']);
    }
    softDelete($pdo, 'workshops', $id);
    audit($pdo, (int)$_SESSION['user_id'], 'delete', 'workshop', $id, 'Workshop deleted', $before, null);
    respond(['status' => 'success']);
}

function handleRestore(PDO $pdo): void
{
    if (!isAdmin()) {
        respond(['status' => 'error', 'message' => 'Insufficient permissions']);
    }
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) {
        respond(['status' => 'error', 'message' => 'Invalid workshop ID']);
    }
    restoreRecord($pdo, 'workshops', $id);
    audit($pdo, (int)$_SESSION['user_id'], 'restore', 'workshop', $id, 'Workshop restored', null, null);
    respond(['status' => 'success']);
}

function handleCities(PDO $pdo): void {
    $stmt = $pdo->query('SELECT id, name FROM cities ORDER BY name');
    respond(['status' => 'success', 'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
}

function respond(array $data): void { apiRespond($data); }
?>

