<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Helpers\ActivityLogger;
use App\Models\OrderModel;
use Core\Auth;
use Core\Request;

final class OrderController extends BaseController
{
    private OrderModel $model;

    public function __construct()
    {
        parent::__construct();
        $this->model = new OrderModel();
    }

    public function index(): void
    {
        $this->requirePermission('order.view');
        $filters = [
            'status'    => Request::str('status'),
            'search'    => Request::str('search'),
            'date_from' => Request::str('date_from'),
            'date_to'   => Request::str('date_to'),
        ];
        $page     = max(1, (int) Request::str('page', '1'));
        $orders   = $this->model->all($page, ITEMS_PER_PAGE, $filters);
        $total    = $this->model->count($filters);
        $statuses = ['pending','confirmed','cooking','ready','picked_up','on_the_way','delivered','cancelled'];
        $this->view('orders/index', compact('orders','total','page','filters','statuses') + ['title' => 'Orders']);
    }

    public function live(): void
    {
        $this->requirePermission('order.view');
        $orders  = $this->model->activeOrders();
        $columns = [
            'pending'    => ['label'=>'Pending',   'icon'=>'clock',        'color'=>'warning','orders'=>[]],
            'confirmed'  => ['label'=>'Confirmed', 'icon'=>'check-circle', 'color'=>'info',   'orders'=>[]],
            'cooking'    => ['label'=>'Cooking',   'icon'=>'fire',         'color'=>'danger', 'orders'=>[]],
            'ready'      => ['label'=>'Ready',     'icon'=>'bag-check',    'color'=>'success','orders'=>[]],
            'picked_up'  => ['label'=>'Picked Up', 'icon'=>'bicycle',      'color'=>'primary','orders'=>[]],
            'on_the_way' => ['label'=>'On the Way','icon'=>'truck',        'color'=>'accent', 'orders'=>[]],
        ];
        foreach ($orders as $o) {
            if (isset($columns[$o['status']])) $columns[$o['status']]['orders'][] = $o;
        }
        $this->view('orders/live', [
            'title'   => 'Live Order Board',
            'columns' => $columns,
            'riders'  => $this->model->riders(),
        ]);
    }

    public function show(array $params = []): void
    {
        $this->requirePermission('order.view');
        $id    = (int)($params['id'] ?? 0);
        $order = $this->model->find($id);
        if (!$order) { $this->flash('error', 'Order not found.'); $this->redirect('/orders'); }
        $this->view('orders/show', [
            'title'       => 'Order #' . $order['order_number'],
            'order'       => $order,
            'items'       => $this->model->getItems($id),
            'statusLog'   => $this->model->getStatusLog($id),
            'riders'      => $this->model->riders(),
            'allStatuses' => ['pending','confirmed','cooking','ready','picked_up','on_the_way','delivered','cancelled'],
        ]);
    }

    public function updateStatus(array $params = []): void
    {
        $this->requirePermission('order.manage');
        Request::verifyCsrf();
        $id    = (int)($params['id'] ?? 0);
        $order = $this->model->find($id);
        if (!$order) { $this->flash('error', 'Order not found.'); $this->redirect('/orders'); }
        $newStatus = Request::str('status');
        $allowed   = ['pending','confirmed','cooking','ready','picked_up','on_the_way','delivered','cancelled'];
        if (!in_array($newStatus, $allowed, true)) {
            $this->flash('error', 'Invalid status.'); $this->redirect('/orders/' . $id);
        }
        if (in_array($order['status'], ['delivered','cancelled'], true)) {
            $this->flash('error', 'Cannot change a closed order.'); $this->redirect('/orders/' . $id);
        }
        $note = Request::str('note') ?: null;
        $this->model->updateStatus($id, $newStatus, (int) Auth::user()['id'], $note);
        if ($newStatus === 'picked_up') {
            $riderId = Request::int('rider_id') ?: null;
            if ($riderId) \Core\Database::getInstance()->update('orders', ['rider_id' => $riderId], ['id' => $id]);
        }
        ActivityLogger::statusChanged('Order', $id, $order['order_number'], $order['status'], $newStatus);

        $isAjax = ($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '') === 'XMLHttpRequest'
               || Request::str('_ajax') === '1';
        if ($isAjax) {
            $this->json(['ok' => true, 'status' => $newStatus]);
            return;
        }
        $this->flash('success', 'Status updated to ' . ucfirst(str_replace('_', ' ', $newStatus)) . '.');
        $this->redirect('/orders/' . $id);
    }

    public function cancel(array $params = []): void
    {
        $this->requirePermission('order.manage');
        Request::verifyCsrf();
        $id    = (int)($params['id'] ?? 0);
        $order = $this->model->find($id);
        if (!$order) { $this->flash('error', 'Order not found.'); $this->redirect('/orders'); }
        if (in_array($order['status'], ['delivered','cancelled'], true)) {
            $this->flash('error', 'Order already closed.'); $this->redirect('/orders/' . $id);
        }
        $reason = trim(Request::str('cancel_reason', 'Cancelled by admin'));
        $this->model->cancel($id, $reason, Auth::user()['id']);
        ActivityLogger::log('cancel', 'Order', $id, $order['order_number'], "Reason: {$reason}");
        $this->flash('success', 'Order cancelled.');
        $this->redirect('/orders/' . $id);
    }

    public function invoice(array $params = []): void
    {
        $this->requirePermission('order.view');
        $id    = (int)($params['id'] ?? 0);
        $order = $this->model->find($id);
        if (!$order) { $this->flash('error', 'Order not found.'); $this->redirect('/orders'); }
        $invoiceNumber = $this->model->createInvoice($id);
        $settings      = \Core\Database::getInstance()->fetchOne("SELECT * FROM settings LIMIT 1") ?? [];
        $this->view('orders/invoice', [
            'title'         => 'Invoice ' . $invoiceNumber,
            'order'         => $order,
            'items'         => $this->model->getItems($id),
            'invoiceNumber' => $invoiceNumber,
            'settings'      => $settings,
            'layout'        => 'print',
        ]);
    }

    public function kot(array $params = []): void
    {
        $this->requirePermission('order.view');
        $id    = (int)($params['id'] ?? 0);
        $order = $this->model->find($id);
        if (!$order) { $this->flash('error', 'Order not found.'); $this->redirect('/orders'); }
        $this->view('orders/kot', [
            'title'  => 'KOT #' . $order['order_number'],
            'order'  => $order,
            'items'  => $this->model->getItems($id),
            'layout' => 'print',
        ]);
    }

    public function pendingCount(): void
    {
        $this->requireAuth();
        $this->json(['count' => $this->model->pendingCount()]);
    }

    public function liveData(): void
    {
        $this->requirePermission('order.view');
        $this->json(['orders' => $this->model->activeOrders(), 'ts' => time()]);
    }
}
