<?php

declare(strict_types=1);

namespace App\Controllers;

use Core\Database;
use Core\Request;
use Core\Session;

final class RiderPortalController extends BaseController
{
    protected Database $db;

    public function __construct()
    {
        parent::__construct();
        $this->db = Database::getInstance();
    }

    // ── Auth ─────────────────────────────────────────────────────────────────────

    public function loginForm(): void
    {
        if ($this->riderSession()) {
            $this->redirect('/rider/dashboard');
        }
        $this->view('rider_portal.login', ['error' => null], 'rider');
    }

    public function login(): void
    {
        Request::verifyCsrf();

        $email    = trim(Request::str('email'));
        $password = Request::str('password');

        $user = $this->db->fetchOne(
            "SELECT u.* FROM users u
               JOIN roles r ON r.id = u.role_id
              WHERE u.email = ? AND r.name = 'rider'",
            [$email]
        );

        if (!$user || !password_verify($password, $user['password_hash'])) {
            $this->view('rider_portal.login', ['error' => 'Invalid email or password.'], 'rider');
            return;
        }

        if (!$user['is_active']) {
            $this->view('rider_portal.login', ['error' => 'Your account is inactive. Contact admin.'], 'rider');
            return;
        }

        Session::set('rider_id',   $user['id']);
        Session::set('rider_name', $user['name']);
        Session::set('rider_phone',$user['phone']);

        $this->redirect('/rider/dashboard');
    }

    public function logout(): void
    {
        Session::remove('rider_id');
        Session::remove('rider_name');
        Session::remove('rider_phone');
        $this->redirect('/rider/login');
    }

    // ── Dashboard ─────────────────────────────────────────────────────────────────

    public function dashboard(): void
    {
        $rider = $this->requireRider();

        $activeOrders = $this->db->fetchAll(
            "SELECT o.*,
                    COALESCE(u.name, o.guest_name, 'Guest') AS customer_name,
                    COALESCE(u.phone, o.guest_phone) AS customer_phone
               FROM orders o
               LEFT JOIN customers c ON c.id = o.customer_id
               LEFT JOIN users u     ON u.id = c.user_id
              WHERE o.rider_id = ? AND o.status IN ('picked_up','on_the_way')
              ORDER BY o.placed_at DESC",
            [$rider['id']]
        );

        $readyOrders = $this->db->fetchAll(
            "SELECT o.*,
                    COALESCE(u.name, o.guest_name, 'Guest') AS customer_name,
                    COALESCE(u.phone, o.guest_phone) AS customer_phone
               FROM orders o
               LEFT JOIN customers c ON c.id = o.customer_id
               LEFT JOIN users u     ON u.id = c.user_id
              WHERE o.rider_id = ? AND o.status = 'ready'
              ORDER BY o.placed_at ASC",
            [$rider['id']]
        );

        $todayDeliveries = (int) $this->db->fetchValue(
            "SELECT COUNT(*) FROM orders
              WHERE rider_id = ? AND status = 'delivered'
                AND DATE(updated_at) = CURDATE()",
            [$rider['id']]
        );

        $totalDeliveries = (int) $this->db->fetchValue(
            "SELECT COUNT(*) FROM orders WHERE rider_id = ? AND status = 'delivered'",
            [$rider['id']]
        );

        $this->view('rider_portal.dashboard', [
            'rider'           => $rider,
            'activeOrders'    => $activeOrders,
            'readyOrders'     => $readyOrders,
            'todayDeliveries' => $todayDeliveries,
            'totalDeliveries' => $totalDeliveries,
        ], 'rider');
    }

    // ── Order detail ──────────────────────────────────────────────────────────────

    public function showOrder(array $params): void
    {
        $rider   = $this->requireRider();
        $orderId = (int) $params['id'];

        $order = $this->db->fetchOne(
            "SELECT o.*,
                    COALESCE(u.name, o.guest_name, 'Guest') AS customer_name,
                    COALESCE(u.phone, o.guest_phone)         AS customer_phone,
                    COALESCE(u.email, o.guest_email)         AS customer_email
               FROM orders o
               LEFT JOIN customers c ON c.id = o.customer_id
               LEFT JOIN users u     ON u.id = c.user_id
              WHERE o.id = ? AND o.rider_id = ?",
            [$orderId, $rider['id']]
        );

        if (!$order) {
            $this->flash('error', 'Order not found.');
            $this->redirect('/rider/dashboard');
        }

        $items = $this->db->fetchAll(
            "SELECT oi.* FROM order_items oi WHERE oi.order_id = ?",
            [$orderId]
        );

        $this->view('rider_portal.order_detail', [
            'rider' => $rider,
            'order' => $order,
            'items' => $items,
        ], 'rider');
    }

    // ── Update order status ───────────────────────────────────────────────────────

    public function updateStatus(array $params): void
    {
        $rider = $this->requireRider();
        Request::verifyCsrf();

        $orderId   = (int) $params['id'];
        $newStatus = Request::str('status');

        $allowed = ['picked_up', 'on_the_way', 'delivered'];
        if (!in_array($newStatus, $allowed, true)) {
            $this->flash('error', 'Invalid status.');
            $this->redirect('/rider/dashboard');
        }

        // Verify this order belongs to this rider
        $order = $this->db->fetchOne(
            "SELECT * FROM orders WHERE id = ? AND rider_id = ?",
            [$orderId, $rider['id']]
        );

        if (!$order) {
            $this->flash('error', 'Order not found.');
            $this->redirect('/rider/dashboard');
        }

        $this->db->update('orders', ['status' => $newStatus], ['id' => $orderId]);
        $this->db->insert('order_status_log', [
            'order_id'   => $orderId,
            'status'     => $newStatus,
            'changed_by' => $rider['id'],
            'note'       => 'Updated by rider',
            'changed_at' => date('Y-m-d H:i:s'),
        ]);

        $this->flash('success', 'Order marked as ' . ucwords(str_replace('_', ' ', $newStatus)) . '.');
        $this->redirect('/rider/dashboard');
    }

    // ── Update rider GPS location (AJAX) ─────────────────────────────────────────

    public function updateLocation(): void
    {
        $rider = $this->requireRider();

        $lat = (float) Request::str('lat');
        $lng = (float) Request::str('lng');

        if (!is_numeric(Request::str('lat')) || !is_numeric(Request::str('lng'))
            || $lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
            $this->json(['success' => false, 'message' => 'Invalid coordinates']);
        }

        $this->db->update('users',
            ['current_lat' => $lat, 'current_lng' => $lng, 'location_at' => date('Y-m-d H:i:s')],
            ['id' => $rider['id']]
        );

        $this->json(['success' => true]);
    }

    // ── Customer polls rider location ─────────────────────────────────────────────

    public function riderLocation(array $params): void
    {
        $orderId = (int) $params['id'];

        // Verify order exists and has a rider
        $order = $this->db->fetchOne(
            "SELECT o.rider_id, o.status, o.customer_id, o.guest_name,
                    u.current_lat, u.current_lng, u.location_at, u.name AS rider_name, u.phone AS rider_phone
               FROM orders o
               LEFT JOIN users u ON u.id = o.rider_id
              WHERE o.id = ?",
            [$orderId]
        );

        if (!$order || !$order['rider_id']) {
            $this->json(['success' => false, 'message' => 'No rider assigned']);
        }

        // Only share location when order is active delivery
        if (!in_array($order['status'], ['picked_up', 'on_the_way'], true)) {
            $this->json(['success' => false, 'message' => 'Rider not en route']);
        }

        $this->json([
            'success'      => true,
            'lat'          => $order['current_lat'],
            'lng'          => $order['current_lng'],
            'location_at'  => $order['location_at'],
            'rider_name'   => $order['rider_name'],
            'rider_phone'  => $order['rider_phone'],
            'status'       => $order['status'],
        ]);
    }

    // ── Helpers ───────────────────────────────────────────────────────────────────

    private function requireRider(): array
    {
        $id = Session::get('rider_id');
        if (!$id) {
            $this->redirect('/rider/login');
        }
        return [
            'id'    => (int) $id,
            'name'  => Session::get('rider_name'),
            'phone' => Session::get('rider_phone'),
        ];
    }

    private function riderSession(): bool
    {
        return (bool) Session::get('rider_id');
    }
}
