<?php
class TripsController extends Controller
{
    /* =========================================================
     *  Read
     * ========================================================= */
    public function indexAction($page = 1)
    {
        $page    = max(1, (int)$page);
        $perPage = defined('ROWS_PER_PAGE') ? ROWS_PER_PAGE : 20;

        $filters = [
            'q'           => trim((string)($_GET['q']           ?? '')),
            'status'      => trim((string)($_GET['status']      ?? '')),
            'driver_id'   => (int)($_GET['driver_id']           ?? 0),
            'truck_id'    => (int)($_GET['truck_id']            ?? 0),
            'customer_id' => (int)($_GET['customer_id']         ?? 0),
        ];

        $m      = new Trips();
        $result = $m->listPaginated($page, $perPage, $filters);

        $qs      = http_build_query(array_filter($filters, fn($v) => $v !== '' && $v !== 0));
        $baseUrl = PROOT . 'Trips/index/';
        $pg      = Pagination::paginate($result['total'], $perPage, $page, $baseUrl);
        $pgHtml  = $pg['html'];
        if ($qs && $pgHtml) {
            $pgHtml = preg_replace('~href=\'([^\']+)\'~', "href='$1?" . htmlspecialchars($qs) . "'", $pgHtml);
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Trips/index', [
            'page_title' => 'Trips',
            'rows'       => $result['rows'],
            'total'      => $result['total'],
            'page'       => $page,
            'filters'    => $filters,
            'pg_html'    => $pgHtml,
        ]);
    }

    public function viewAction($id = 0)
    {
        $m = new Trips();
        $t = $m->byId((int)$id);
        if (!$t) { $this->notFound('Trip'); return; }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Trips/view', [
            'page_title'  => $t['trip_no'] . ' · Trip',
            't'           => $t,
            'history'     => $m->statusHistory((int)$id),
            'stops'       => (new TripStops())->forTrip((int)$id),
            'gps'         => (new GpsDevices())->latestPositionForTruck((int)$t['truck_id']),
            'attachments' => (new TripAttachments())->forTrip((int)$id),
        ]);
    }

    /* ---- Execution-side stop actions on a Trip ---- */
    public function addStopAction($trip_id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$trip_id); return; }
        $r = (new TripStops())->create(0, (int)$trip_id, $_POST, $this->currentUserId());
        $_SESSION['flash_tenant_msg']  = $r['msg'];
        $_SESSION['flash_tenant_type'] = $r['ok'] ? 'success' : 'danger';
        Router::redirect('Trips/view/' . (int)$trip_id);
    }

    public function deleteStopAction($stop_id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips'); return; }
        $stop = (new TripStops())->byId((int)$stop_id);
        (new TripStops())->softDelete((int)$stop_id, $this->currentUserId());
        $_SESSION['flash_tenant_msg']  = 'Stop removed.';
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('Trips/view/' . (int)($stop['trip_id'] ?? 0));
    }

    public function arriveStopAction($stop_id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips'); return; }
        $stop = (new TripStops())->byId((int)$stop_id);
        $odo  = isset($_POST['odometer']) && $_POST['odometer'] !== '' ? (int)preg_replace('/[^0-9]/', '', (string)$_POST['odometer']) : null;
        (new TripStops())->markArrived((int)$stop_id, $this->currentUserId(), $odo);
        $_SESSION['flash_tenant_msg']  = 'Arrival at stop marked.';
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('Trips/view/' . (int)($stop['trip_id'] ?? 0));
    }

    public function departStopAction($stop_id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips'); return; }
        $stop = (new TripStops())->byId((int)$stop_id);
        $odo  = isset($_POST['odometer']) && $_POST['odometer'] !== '' ? (int)preg_replace('/[^0-9]/', '', (string)$_POST['odometer']) : null;
        (new TripStops())->markDeparted((int)$stop_id, $this->currentUserId(), $odo);
        $_SESSION['flash_tenant_msg']  = 'Departure from stop marked.';
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('Trips/view/' . (int)($stop['trip_id'] ?? 0));
    }

    /* =========================================================
     *  Vue 3 Dispatch Board
     * ========================================================= */
    public function boardAction()
    {
        $data = (new Trips())->boardData();
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Trips/dispatchBoard', [
            'page_title' => 'Dispatch Board',
            'board'      => $data,
            // Also pass truck/driver lists for the dispatch modal
            'drivers'    => $this->availableDrivers(),
            'trucks'     => $this->activeTrucks(),
        ]);
    }

    /** JSON endpoint the Vue 3 board polls after each action. */
    public function boardDataAjAction()
    {
        $this->jsonResponse([
            'ok'      => true,
            'board'   => (new Trips())->boardData(),
            'drivers' => $this->availableDrivers(),
            'trucks'  => $this->activeTrucks(),
        ]);
    }

    /* =========================================================
     *  Lifecycle transitions
     * ========================================================= */

    /** Create a trip from an approved TripRequest. */
    public function dispatchAction($request_id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('TripRequests/view/' . (int)$request_id); return; }

        $m = new Trips();
        $r = $m->dispatchFromRequest((int)$request_id, $_POST, $this->currentUserId());

        if ($this->wantsJson()) { $this->jsonResponse($r); return; }
        $_SESSION['flash_tenant_msg']  = $r['msg'];
        $_SESSION['flash_tenant_type'] = $r['ok'] ? 'success' : 'danger';
        if ($r['ok']) { Router::redirect('Trips/view/' . (int)$r['id']); return; }
        Router::redirect('TripRequests/view/' . (int)$request_id);
    }

    public function startAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$id); return; }
        $r = (new Trips())->start((int)$id, $_POST, $this->currentUserId());
        if ($this->wantsJson()) { $this->jsonResponse($r); return; }
        $this->flashAndRedirect($r, 'Trips/view/' . (int)$id);
    }

    public function deliverAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$id); return; }
        $r = (new Trips())->markDelivered((int)$id, $this->currentUserId());
        if ($this->wantsJson()) { $this->jsonResponse($r); return; }
        $this->flashAndRedirect($r, 'Trips/view/' . (int)$id);
    }

    public function closeAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$id); return; }
        $r = (new Trips())->close((int)$id, $_POST, $this->currentUserId());
        if ($this->wantsJson()) { $this->jsonResponse($r); return; }
        $this->flashAndRedirect($r, 'Trips/view/' . (int)$id);
    }

    public function cancelAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$id); return; }
        $reason = trim((string)($_POST['cancel_reason'] ?? ''));
        $r = (new Trips())->cancel((int)$id, $reason, $this->currentUserId());
        if ($this->wantsJson()) { $this->jsonResponse($r); return; }
        $this->flashAndRedirect($r, 'Trips/view/' . (int)$id);
    }

    public function deleteAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('Trips/view/' . (int)$id); return; }
        (new Trips())->softDelete((int)$id, $this->currentUserId());
        $_SESSION['flash_tenant_msg']  = 'Trip removed.';
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('Trips');
    }

    /* =========================================================
     *  Helpers
     * ========================================================= */
    private function availableDrivers(): array
    {
        return (new DB())->mySelect(
            "SELECT c0d, full_name, employee_no, phone_1, licence_no
               FROM drivers WHERE deleted = 0 AND status IN ('available','on_trip')
           ORDER BY status = 'available' DESC, full_name ASC", []
        ) ?: [];
    }

    private function activeTrucks(): array
    {
        return (new DB())->mySelect(
            "SELECT c0d, reg_no, make, model, capacity_kg, current_odometer, status
               FROM trucks WHERE deleted = 0 AND status IN ('active','maintenance')
           ORDER BY status = 'active' DESC, reg_no ASC", []
        ) ?: [];
    }

    private function wantsJson(): bool
    {
        // Board actions come from Vue via fetch() with Accept: application/json
        $a = $_SERVER['HTTP_ACCEPT'] ?? '';
        return strpos($a, 'application/json') !== false || !empty($_POST['as_json']);
    }

    private function flashAndRedirect(array $r, string $to): void
    {
        $_SESSION['flash_tenant_msg']  = $r['msg'] ?? '';
        $_SESSION['flash_tenant_type'] = ($r['ok'] ?? false) ? 'success' : 'danger';
        Router::redirect($to);
    }

    private function notFound(string $what): void
    {
        $this->view->setLayout($this->roleLayout());
        $this->view->render('generals/fb_page', [
            'page_title' => 'Not found',
            'fb_msg'     => '<div class="alert alert-danger">' . htmlspecialchars($what) . ' not found.</div>',
        ]);
    }
}
