<?php

namespace App\Controllers\Api;

use App\Libraries\JwtAuth;
use App\Models\DriverLocationModel;

class AdminController extends BaseApiController
{
    /**
     * GET api/admin/drivers - list all drivers with online status and last location (God view).
     */
    public function drivers()
    {
        $err = $this->ensureAdmin();
        if ($err !== null) {
            return $err;
        }
        $db = \Config\Database::connect();
        $users = $db->table('users')->where('role', 'driver')->get()->getResult();
        $locModel = model(DriverLocationModel::class);
        $data = [];
        foreach ($users as $u) {
            $loc = $locModel->where('user_id', $u->id)->first();
            $data[] = [
                'id'       => (int) $u->id,
                'phone'    => $u->phone,
                'username' => $u->username,
                'online'   => $loc !== null,
                'latitude' => $loc ? (float) $loc->latitude : null,
                'longitude'=> $loc ? (float) $loc->longitude : null,
                'updated_at' => $loc ? $loc->updated_at : null,
            ];
        }
        return $this->success($data);
    }

    /**
     * GET api/admin/suggest-drivers?latitude=0&longitude=0 - 3 nearest drivers (Haversine).
     */
    public function suggestDrivers()
    {
        $err = $this->ensureAdmin();
        if ($err !== null) {
            return $err;
        }
        $lat = (float) ($this->request->getGet('latitude') ?? 0);
        $lng = (float) ($this->request->getGet('longitude') ?? 0);
        $db = \Config\Database::connect();
        $driverIds = $db->table('users')->where('role', 'driver')->where('jambo_status', 'active')->select('id')->get()->getResult();
        $ids = array_map(static fn ($r) => $r->id, $driverIds);
        if ($ids === []) {
            return $this->success([]);
        }
        $locs = $db->table('driver_locations')->whereIn('user_id', $ids)->get()->getResult();
        $distances = [];
        foreach ($locs as $loc) {
            $dist = $this->haversineKm($lat, $lng, (float) $loc->latitude, (float) $loc->longitude);
            $distances[] = ['user_id' => $loc->user_id, 'distance_km' => $dist, 'latitude' => (float) $loc->latitude, 'longitude' => (float) $loc->longitude];
        }
        usort($distances, static fn ($a, $b) => $a['distance_km'] <=> $b['distance_km']);
        $top3 = array_slice($distances, 0, 3);
        $userIds = array_column($top3, 'user_id');
        $users = $db->table('users')->whereIn('id', $userIds)->get()->getResult();
        $byId = [];
        foreach ($users as $u) {
            $byId[$u->id] = ['id' => (int) $u->id, 'phone' => $u->phone, 'username' => $u->username];
        }
        $result = [];
        foreach ($top3 as $t) {
            $result[] = array_merge($byId[$t['user_id']] ?? [], ['distance_km' => round($t['distance_km'], 2)]);
        }
        return $this->success($result);
    }

    /**
     * @return \CodeIgniter\HTTP\ResponseInterface|null null if admin, else response to send
     */
    private function ensureAdmin()
    {
        $user = JwtAuth::user();
        if (! $user) {
            return $this->error('Unauthorized', 401);
        }
        $db  = \Config\Database::connect();
        $row = $db->table('users')->where('id', $user->id)->get()->getRow();
        if (! $row || ($row->role ?? '') !== 'admin') {
            return $this->error('Forbidden', 403);
        }
        return null;
    }

    private function haversineKm(float $lat1, float $lon1, float $lat2, float $lon2): float
    {
        $R = 6371; // km
        $dLat = deg2rad($lat2 - $lat1);
        $dLon = deg2rad($lon2 - $lon1);
        $a = sin($dLat / 2) ** 2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) ** 2;
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        return $R * $c;
    }
}
