<?php
declare(strict_types=1);

namespace App\Controller\Admin;

use App\Controller\AppController;
use Cake\I18n\FrozenTime;

class BookingManagementController extends AppController
{
    protected $Bookings;

    public function initialize(): void
    {
        parent::initialize();

        $this->viewBuilder()
            ->setLayout('admin')
            ->setLayoutPath('Admin');

        $this->Bookings = $this->fetchTable('Bookings');
        $this->loadComponent('Flash');
        if (!$this->isAdminOrStaff()) {
            throw new \Cake\Http\Exception\ForbiddenException('Staffs only.');
        }
    }
    private function isAdminOrStaff(): bool
    {
        $id = $this->request->getAttribute('identity');
        return (bool)($id && in_array($id->get('role'), ['admin', 'staff'], true));
    }
    public function index()
{
    $search = trim((string)$this->request->getQuery('q', ''));
    $selectedStatus = trim((string)$this->request->getQuery('status', ''));
    $selectedPickupDate = trim((string)$this->request->getQuery('pickup_date', ''));
    $status = $this->request->getQuery('status','');
    $bookingsQuery = $this->Bookings->find()
        ->orderBy(['created' => 'DESC']);
        if (strtolower($status) === 'archived') {
            $bookingsQuery->where(['archived' => 1]);
        } else {
            $bookingsQuery->where(['archived' => 0]);
        }
    if ($search !== '') {
        $bookingsQuery->where([
            'OR' => [
                'booking_reference LIKE' => '%' . $search . '%',
                'shipper_name LIKE' => '%' . $search . '%',
                'receiver_name LIKE' => '%' . $search . '%',
                'shipper_address LIKE' => '%' . $search . '%',
                'delivery_address LIKE' => '%' . $search . '%',
                'shipper_phone LIKE' => '%' . $search . '%',
                'receiver_phone LIKE' => '%' . $search . '%',
            ]
        ]);
    }

    if ($selectedStatus !== '') {
        $bookingsQuery->where(['status' => $selectedStatus]);
    }

    if ($selectedPickupDate !== '') {
        $bookingsQuery->where(['pickup_date' => $selectedPickupDate]);
    }

    $bookings = $bookingsQuery->all();

    $statusOptions = [
        'Pending',
        'Confirmed',
        'Picked Up',
        'Collected at Depot',
        'In Transit',
        'Out for Delivery',
        'Delivered',
        'Delivery Failed',
        'Returned',
        'Cancelled',
        'On Hold',
        'Archived',
    ];

    $this->set(compact(
        'bookings',
        'statusOptions',
        'selectedStatus',
        'selectedPickupDate',
        'search'
    ));
}

    public function view($id = null)
    {
        $booking = $this->Bookings->find()
            ->where([
                'id' => $id,
            ])
            ->firstOrFail();

        $statusOptions = [
            'Pending',
            'Confirmed',
            'Picked Up',
            'Collected at Depot',
            'In Transit',
            'Out for Delivery',
            'Delivered',
            'Delivery Failed',
            'Returned',
            'Cancelled',
            'On Hold',
            'Archived',
        ];

        if ($this->request->is(['patch', 'post', 'put'])) {
            $data = $this->request->getData();

            if (!empty($data['status'])) {
                $data['last_status_update'] = FrozenTime::now();
            }

            $booking = $this->Bookings->patchEntity($booking, $data);

            if ($this->Bookings->save($booking)) {
                $this->Flash->success('Booking updated successfully.');
                return $this->redirect([
                    'prefix' => 'Admin',
                    'controller' => 'BookingManagement',
                    'action' => 'view',
                    $booking->id
                ]);
            }

            $this->Flash->error('Unable to update booking.');
        }

        $this->set(compact('booking', 'statusOptions'));
    }

    public function archive($id = null)
    {
        $this->request->allowMethod(['post']);

        $booking = $this->Bookings->get($id);
        $booking->archived = 1;
        $booking->last_status_update = FrozenTime::now();
        $booking->status = 'Archived';
        if ($this->Bookings->save($booking)) {
            $this->Flash->success('Booking archived successfully.');
        } else {
            $this->Flash->error('Could not archive booking.');
        }

        return $this->redirect([
            'prefix' => 'Admin',
            'controller' => 'BookingManagement',
            'action' => 'index'
        ]);
    }

    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);

        $booking = $this->Bookings->get($id);

        if ($this->Bookings->delete($booking)) {
            $this->Flash->success('Booking deleted successfully.');
        } else {
            $this->Flash->error('Could not delete booking.');
        }

        return $this->redirect([
            'prefix' => 'Admin',
            'controller' => 'BookingManagement',
            'action' => 'index'
        ]);
    }
}
