<?php
/**
 * Courier Model
 * Handle courier operations and deliveries
 */

namespace Models;

use Core\DB;

class Courier {
    private $db;
    
    public function __construct() {
        $this->db = DB::getInstance();
    }
    
    /**
     * Create courier profile
     */
    public function create($userId, $data) {
        $courier = [
            'id' => $this->generateUuid(),
            'user_id' => $userId,
            'vehicle_type' => $data['vehicle_type'] ?? 'motorcycle',
            'lat' => $data['lat'],
            'lng' => $data['lng'],
            'active' => true,
            'available' => true,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        $this->db->insert('couriers', $courier);
        
        // Create wallet
        $this->db->insert('wallets', [
            'id' => $this->generateUuid(),
            'owner_type' => 'COURIER',
            'owner_id' => $courier['id'],
            'balance' => 0,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        return $courier['id'];
    }
    
    /**
     * Find courier by user ID
     */
    public function findByUserId($userId) {
        return $this->db->fetchOne(
            "SELECT c.*, w.balance as wallet_balance 
             FROM couriers c 
             LEFT JOIN wallets w ON w.owner_type = 'COURIER' AND w.owner_id = c.id 
             WHERE c.user_id = ?",
            [$userId]
        );
    }
    
    /**
     * Find courier by ID
     */
    public function findById($id) {
        return $this->db->fetchOne(
            "SELECT c.*, u.name as user_name, u.phone, u.email, w.balance as wallet_balance 
             FROM couriers c 
             INNER JOIN users u ON c.user_id = u.id 
             LEFT JOIN wallets w ON w.owner_type = 'COURIER' AND w.owner_id = c.id 
             WHERE c.id = ?",
            [$id]
        );
    }
    
    /**
     * Get all active couriers
     */
    public function getActive() {
        return $this->db->fetchAll(
            "SELECT c.*, u.name as user_name, u.phone 
             FROM couriers c 
             INNER JOIN users u ON c.user_id = u.id 
             WHERE c.active = 1 
             ORDER BY u.name ASC"
        );
    }
    
    /**
     * Get available couriers near location
     */
    public function getAvailableNear($lat, $lng, $radius = 20) {
        return $this->db->fetchAll("
            SELECT c.*, u.name as user_name, u.phone,
                   (6371 * acos(
                       cos(radians(?)) * 
                       cos(radians(c.lat)) * 
                       cos(radians(c.lng) - radians(?)) + 
                       sin(radians(?)) * 
                       sin(radians(c.lat))
                   )) AS distance
            FROM couriers c
            INNER JOIN users u ON c.user_id = u.id
            WHERE c.active = 1 AND c.available = 1 AND u.active = 1
            HAVING distance <= ?
            ORDER BY distance ASC
        ", [$lat, $lng, $lat, $radius]);
    }
    
    /**
     * Update courier availability
     */
    public function updateAvailability($id, $available = true) {
        return $this->db->update(
            'couriers',
            ['available' => $available ? 1 : 0],
            'id = ?',
            [$id]
        );
    }
    
    /**
     * Update courier location
     */
    public function updateLocation($id, $lat, $lng) {
        return $this->db->update(
            'couriers',
            ['lat' => $lat, 'lng' => $lng],
            'id = ?',
            [$id]
        );
    }
    
    /**
     * Get courier current order
     */
    public function getCurrentOrder($courierId) {
        return $this->db->fetchOne("
            SELECT o.*, p.name as pharmacy_name, p.address as pharmacy_address, p.lat as pharmacy_lat, p.lng as pharmacy_lng
            FROM orders o
            LEFT JOIN pharmacies p ON o.pharmacy_id = p.id
            WHERE o.courier_id = ? AND o.status IN ('COURIER_ASSIGNED', 'PICKED_UP')
            ORDER BY o.updated_at DESC
            LIMIT 1
        ", [$courierId]);
    }
    
    /**
     * Get courier statistics
     */
    public function getStats($courierId) {
        // Today's deliveries
        $todayDeliveries = $this->db->count(
            'orders',
            'courier_id = ? AND DATE(created_at) = CURDATE()',
            [$courierId]
        );
        
        // Today's earnings (completed orders)
        $todayEarnings = $this->db->fetchOne("
            SELECT SUM(l.amount) as earnings
            FROM ledger l
            INNER JOIN orders o ON l.order_id = o.id
            WHERE l.account = 'COURIER' AND l.entry_type = 'CREDIT' 
            AND o.courier_id = ? AND DATE(l.created_at) = CURDATE()
        ", [$courierId]);
        
        // Total deliveries
        $totalDeliveries = $this->db->count(
            'orders',
            'courier_id = ? AND status IN (?, ?)',
            [$courierId, 'DELIVERED', 'CLOSED']
        );
        
        // Average rating (mock for now)
        $averageRating = 4.8;
        
        // Acceptance rate
        $assignedOrders = $this->db->count('orders', 'courier_id = ?', [$courierId]);
        $acceptanceRate = $assignedOrders > 0 ? 96.0 : 100.0; // Mock calculation
        
        return [
            'today_deliveries' => $todayDeliveries,
            'today_earnings' => $todayEarnings['earnings'] ?? 0,
            'total_deliveries' => $totalDeliveries,
            'average_rating' => $averageRating,
            'acceptance_rate' => $acceptanceRate
        ];
    }
    
    /**
     * Get courier wallet balance
     */
    public function getWalletBalance($courierId) {
        $wallet = $this->db->fetchOne(
            "SELECT balance FROM wallets WHERE owner_type = 'COURIER' AND owner_id = ?",
            [$courierId]
        );
        
        return $wallet ? $wallet['balance'] : 0;
    }
    
    /**
     * Get courier transaction history
     */
    public function getTransactionHistory($courierId, $limit = 50) {
        return $this->db->fetchAll("
            SELECT l.*, o.id as order_id, o.medicine_name
            FROM ledger l
            INNER JOIN orders o ON l.order_id = o.id
            WHERE l.account = 'COURIER' AND o.courier_id = ?
            ORDER BY l.created_at DESC
            LIMIT {$limit}
        ", [$courierId]);
    }
    
    /**
     * Get courier delivery history
     */
    public function getDeliveryHistory($courierId, $limit = 50) {
        return $this->db->fetchAll("
            SELECT o.*, p.name as pharmacy_name, u.name as client_name
            FROM orders o
            LEFT JOIN pharmacies p ON o.pharmacy_id = p.id
            LEFT JOIN users u ON o.client_id = u.id
            WHERE o.courier_id = ?
            ORDER BY o.created_at DESC
            LIMIT {$limit}
        ", [$courierId]);
    }
    
    /**
     * Calculate courier performance metrics
     */
    public function getPerformanceMetrics($courierId) {
        // Average delivery time
        $avgDeliveryTime = $this->db->fetchOne("
            SELECT AVG(TIMESTAMPDIFF(MINUTE, 
                (SELECT created_at FROM order_events WHERE order_id = o.id AND event = 'COURIER_ASSIGNED' LIMIT 1),
                (SELECT created_at FROM order_events WHERE order_id = o.id AND event = 'STATUS_CHANGED_DELIVERED' LIMIT 1)
            )) as avg_time
            FROM orders o
            WHERE o.courier_id = ? AND o.status IN ('DELIVERED', 'CLOSED')
        ", [$courierId]);
        
        // On-time delivery rate
        $onTimeDeliveries = $this->db->count(
            'orders',
            'courier_id = ? AND status IN (?, ?) AND TIMESTAMPDIFF(MINUTE, created_at, updated_at) <= 30',
            [$courierId, 'DELIVERED', 'CLOSED']
        );
        
        $totalDeliveries = $this->db->count(
            'orders',
            'courier_id = ? AND status IN (?, ?)',
            [$courierId, 'DELIVERED', 'CLOSED']
        );
        
        $onTimeRate = $totalDeliveries > 0 ? round(($onTimeDeliveries / $totalDeliveries) * 100, 1) : 100;
        
        return [
            'average_delivery_time' => round($avgDeliveryTime['avg_time'] ?? 22),
            'on_time_rate' => $onTimeRate,
            'total_distance' => 0, // Would need to calculate from coordinates
            'fuel_efficiency' => 0 // Mock value
        ];
    }
    
    /**
     * Generate UUID v4
     */
    private function generateUuid() {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
}
?>
