<?php
/**
 * API Controller
 * Handle SOS requests, USSD, and WhatsApp integration
 */

namespace Controllers;

use Core\Auth;
use Core\Helpers;
use Models\Order;
use Models\Medicine;
use Models\Pharmacy;
use Models\Courier;

class ApiController extends Controller {
    
    /**
     * Create SOS request
     */
    public function createSos($params = []) {
        $input = $this->getInput();
        
        $this->validateRequired($input, [
            'medicine_name', 'client_phone', 'client_address', 'client_lat', 'client_lng'
        ]);
        
        // Validate coordinates
        if (!Helpers::validateCoordinates($input['client_lat'], $input['client_lng'])) {
            $this->error('Coordonnées géographiques invalides');
        }
        
        // Validate phone number
        if (!Helpers::validatePhone($input['client_phone'])) {
            $this->error('Numéro de téléphone invalide');
        }
        
        try {
            $orderModel = new Order();
            $medicineModel = new Medicine();
            
            // Handle file upload if present
            $prescriptionUrl = null;
            if (isset($_FILES['prescription'])) {
                $prescriptionUrl = $this->handleFileUpload('prescription');
            }
            
            // Create order
            $orderData = [
                'client_id' => Auth::check() ? Auth::user()['id'] : null,
                'medicine_name' => $this->sanitize($input['medicine_name']),
                'qty' => $input['qty'] ?? 1,
                'client_lat' => (float)$input['client_lat'],
                'client_lng' => (float)$input['client_lng'],
                'client_address' => $this->sanitize($input['client_address']),
                'client_phone' => Helpers::formatPhone($input['client_phone']),
                'prescription_url' => $prescriptionUrl
            ];
            
            $orderId = $orderModel->createSosOrder($orderData);
            
            // Find nearby pharmacies
            $pharmacies = $orderModel->findNearbyPharmacies(
                $orderData['client_lat'],
                $orderData['client_lng'],
                $orderData['medicine_name']
            );
            
            if (empty($pharmacies)) {
                $this->error('Aucune pharmacie disponible avec ce médicament dans votre zone', 404);
            }
            
            // Auto-assign closest pharmacy
            $closestPharmacy = $pharmacies[0];
            $medicine = $medicineModel->findOrCreate($orderData['medicine_name']);
            
            $orderModel->assignPharmacy($orderId, $closestPharmacy['id'], $medicine['id']);
            
            // Calculate estimated total
            $distance = $closestPharmacy['distance'];
            $pricing = Helpers::calculateOrderTotal($closestPharmacy['unit_price'] * $orderData['qty'], $distance);
            
            $this->log("SOS order created: {$orderId}");
            
            $this->success([
                'order_id' => $orderId,
                'pharmacy' => [
                    'name' => $closestPharmacy['name'],
                    'address' => $closestPharmacy['address'],
                    'distance' => round($distance, 2)
                ],
                'pricing' => $pricing
            ], 'Demande SOS créée avec succès');
            
        } catch (\Exception $e) {
            $this->log("SOS order creation failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors de la création de la demande: ' . $e->getMessage());
        }
    }
    
    /**
     * Get order details
     */
    public function getOrder($params = []) {
        if (!isset($params['id'])) {
            $this->error('ID de commande requis');
        }
        
        $orderModel = new Order();
        $order = $orderModel->getWithDetails($params['id']);
        
        if (!$order) {
            $this->error('Commande non trouvée', 404);
        }
        
        $this->success($order);
    }
    
    /**
     * Update order status
     */
    public function updateOrderStatus($params = []) {
        $userId = $this->requireAuth();
        $input = $this->getInput();
        
        if (!isset($params['id'])) {
            $this->error('ID de commande requis');
        }
        
        $this->validateRequired($input, ['status']);
        
        try {
            $orderModel = new Order();
            $order = $orderModel->findById($params['id']);
            
            if (!$order) {
                $this->error('Commande non trouvée', 404);
            }
            
            // Check permissions based on user role
            $user = Auth::user();
            $canUpdate = false;
            
            switch ($user['role']) {
                case 'admin':
                    $canUpdate = true;
                    break;
                case 'pharmacy':
                    $pharmacy = (new \Models\Pharmacy())->findByUserId($userId);
                    $canUpdate = $pharmacy && $order['pharmacy_id'] === $pharmacy['id'];
                    break;
                case 'courier':
                    $courier = (new \Models\Courier())->findByUserId($userId);
                    $canUpdate = $courier && $order['courier_id'] === $courier['id'];
                    break;
            }
            
            if (!$canUpdate) {
                $this->error('Permission refusée', 403);
            }
            
            $orderModel->updateStatus($params['id'], $input['status']);
            
            $this->log("Order status updated: {$params['id']} -> {$input['status']}");
            
            $this->success([], 'Statut mis à jour avec succès');
            
        } catch (\Exception $e) {
            $this->log("Order status update failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors de la mise à jour: ' . $e->getMessage());
        }
    }
    
    /**
     * Pharmacy response to order
     */
    public function pharmacyResponse($params = []) {
        $userId = $this->requireRole('pharmacy');
        $input = $this->getInput();
        
        if (!isset($params['id'])) {
            $this->error('ID de commande requis');
        }
        
        $this->validateRequired($input, ['action']);
        
        if (!in_array($input['action'], ['accept', 'reject'])) {
            $this->error('Action invalide');
        }
        
        try {
            $orderModel = new Order();
            $pharmacyModel = new Pharmacy();
            
            $order = $orderModel->findById($params['id']);
            if (!$order) {
                $this->error('Commande non trouvée', 404);
            }
            
            $pharmacy = $pharmacyModel->findByUserId($userId);
            if (!$pharmacy || $order['pharmacy_id'] !== $pharmacy['id']) {
                $this->error('Permission refusée', 403);
            }
            
            if ($input['action'] === 'accept') {
                if (!isset($input['unit_price']) || $input['unit_price'] <= 0) {
                    $this->error('Prix unitaire requis');
                }
                
                $orderModel->pharmacyConfirm($params['id'], (int)$input['unit_price']);
                
                // Try to find and assign courier
                $pharmacy_data = $pharmacyModel->findById($pharmacy['id']);
                $couriers = $orderModel->findNearbyCouriers($pharmacy_data['lat'], $pharmacy_data['lng']);
                
                if (!empty($couriers)) {
                    $orderModel->assignCourier($params['id'], $couriers[0]['id']);
                    $message = 'Commande acceptée et livreur assigné';
                } else {
                    $message = 'Commande acceptée, recherche de livreur en cours';
                }
                
                $this->log("Pharmacy accepted order: {$params['id']}");
                
            } else {
                $reason = $input['reason'] ?? 'Stock indisponible';
                $orderModel->pharmacyReject($params['id'], $reason);
                
                $this->log("Pharmacy rejected order: {$params['id']}");
                $message = 'Commande refusée';
            }
            
            $this->success([], $message);
            
        } catch (\Exception $e) {
            $this->log("Pharmacy response failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors du traitement: ' . $e->getMessage());
        }
    }
    
    /**
     * Courier accepts delivery
     */
    public function courierAccept($params = []) {
        $userId = $this->requireRole('courier');
        
        if (!isset($params['id'])) {
            $this->error('ID de commande requis');
        }
        
        try {
            $orderModel = new Order();
            $courierModel = new Courier();
            
            $order = $orderModel->findById($params['id']);
            if (!$order) {
                $this->error('Commande non trouvée', 404);
            }
            
            if ($order['status'] !== 'PHARMACY_CONFIRMED') {
                $this->error('Commande non disponible pour livraison');
            }
            
            $courier = $courierModel->findByUserId($userId);
            if (!$courier || !$courier['available']) {
                $this->error('Livreur non disponible');
            }
            
            $orderModel->assignCourier($params['id'], $courier['id']);
            
            $this->log("Courier accepted delivery: {$params['id']}");
            
            $this->success([], 'Livraison acceptée');
            
        } catch (\Exception $e) {
            $this->log("Courier accept failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors de l\'acceptation: ' . $e->getMessage());
        }
    }
    
    /**
     * Get available orders for courier
     */
    public function getAvailableOrders($params = []) {
        $userId = $this->requireRole('courier');
        $input = $_GET;
        
        try {
            $courierModel = new Courier();
            $orderModel = new Order();
            
            $courier = $courierModel->findByUserId($userId);
            if (!$courier) {
                $this->error('Profil livreur non trouvé');
            }
            
            $lat = $input['lat'] ?? $courier['lat'];
            $lng = $input['lng'] ?? $courier['lng'];
            
            if (!$lat || !$lng) {
                $this->error('Position requise');
            }
            
            $orders = $orderModel->getAvailableForCouriers($lat, $lng);
            
            $this->success($orders);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération: ' . $e->getMessage());
        }
    }
    
    /**
     * USSD simulation endpoint
     */
    public function ussd($params = []) {
        $input = $this->getInput();
        
        $this->validateRequired($input, ['session_id', 'text']);
        
        $sessionId = $input['session_id'];
        $text = $input['text'];
        
        // Simple USSD menu simulation
        $menuParts = explode('*', $text);
        $response = '';
        $endSession = false;
        
        try {
            if (empty($text)) {
                // Main menu
                $response = "CON Bienvenue sur MediFlash SOS+\n";
                $response .= "1. Demander un médicament\n";
                $response .= "2. Suivre ma commande\n";
                $response .= "3. Aide";
                
            } elseif ($text === '1') {
                $response = "CON Entrez le nom du médicament:";
                
            } elseif (strpos($text, '1*') === 0 && count($menuParts) === 2) {
                $medicineName = $menuParts[1];
                $response = "CON Médicament: {$medicineName}\n";
                $response .= "Entrez votre quartier:";
                
            } elseif (strpos($text, '1*') === 0 && count($menuParts) === 3) {
                $medicineName = $menuParts[1];
                $address = $menuParts[2];
                
                // Create basic SOS order (would need phone from USSD session)
                $response = "END Demande SOS créée!\n";
                $response .= "Médicament: {$medicineName}\n";
                $response .= "Quartier: {$address}\n";
                $response .= "Vous serez contacté bientôt.";
                $endSession = true;
                
            } elseif ($text === '2') {
                $response = "CON Entrez votre numéro de commande:";
                
            } elseif ($text === '3') {
                $response = "END Aide MediFlash SOS+\n";
                $response .= "Appelez: +225 XX XX XX XX\n";
                $response .= "Email: support@mediflash.ci";
                $endSession = true;
                
            } else {
                $response = "END Option invalide. Merci.";
                $endSession = true;
            }
            
            $this->log("USSD request: {$sessionId} - {$text}");
            
            $this->success([
                'session_id' => $sessionId,
                'text' => $response,
                'end_session' => $endSession
            ]);
            
        } catch (\Exception $e) {
            $this->error('Erreur USSD: ' . $e->getMessage());
        }
    }
    
    /**
     * WhatsApp webhook simulation
     */
    public function whatsapp($params = []) {
        $input = $this->getInput();
        
        $this->validateRequired($input, ['from', 'message']);
        
        try {
            $from = $input['from'];
            $message = $input['message'];
            $imageUrl = $input['image_url'] ?? null;
            
            // Simple message parsing
            if (stripos($message, 'sos') !== false || stripos($message, 'urgent') !== false) {
                // Extract medicine name (basic parsing)
                $words = explode(' ', $message);
                $medicineName = '';
                $found = false;
                
                foreach ($words as $word) {
                    if ($found) {
                        $medicineName = $word;
                        break;
                    }
                    if (stripos($word, 'sos') !== false || stripos($word, 'urgent') !== false) {
                        $found = true;
                    }
                }
                
                if (empty($medicineName)) {
                    $response = "Bonjour! Pour une demande SOS, précisez le médicament.\nExemple: 'SOS Paracétamol'";
                } else {
                    // Create basic order (would need location from user)
                    $response = "Demande SOS reçue pour: {$medicineName}\n";
                    $response .= "Envoyez votre localisation pour continuer.";
                    
                    $this->log("WhatsApp SOS request: {$from} - {$medicineName}");
                }
                
            } elseif (stripos($message, 'suivi') !== false || stripos($message, 'track') !== false) {
                $response = "Pour suivre votre commande, visitez:\n";
                $response .= APP_URL . "/track/VOTRE_ID_COMMANDE";
                
            } else {
                $response = "Bonjour! Je suis l'assistant MediFlash SOS+.\n";
                $response .= "Tapez 'SOS [médicament]' pour une urgence.\n";
                $response .= "Tapez 'SUIVI' pour suivre une commande.";
            }
            
            $this->success([
                'to' => $from,
                'response' => $response
            ]);
            
        } catch (\Exception $e) {
            $this->error('Erreur WhatsApp: ' . $e->getMessage());
        }
    }
    
    /**
     * Search medicines
     */
    public function searchMedicines($params = []) {
        $query = $_GET['q'] ?? '';
        
        if (strlen($query) < 2) {
            $this->error('Requête trop courte');
        }
        
        $medicineModel = new Medicine();
        $medicines = $medicineModel->search($query);
        
        $this->success($medicines);
    }
    
    /**
     * Get system statistics (admin only)
     */
    public function getStats($params = []) {
        $this->requireRole('admin');
        
        try {
            $orderCount = $this->db->count('orders');
            $userCount = $this->db->count('users', 'active = 1');
            $pharmacyCount = $this->db->count('pharmacies', 'verified = 1');
            $courierCount = $this->db->count('couriers', 'active = 1');
            
            $todayOrders = $this->db->count('orders', 'DATE(created_at) = CURDATE()');
            $todayRevenue = $this->db->fetchOne(
                "SELECT SUM(service_fee) as revenue FROM orders WHERE DATE(created_at) = CURDATE() AND status IN ('DELIVERED', 'CLOSED')"
            );
            
            $this->success([
                'total_orders' => $orderCount,
                'total_users' => $userCount,
                'active_pharmacies' => $pharmacyCount,
                'active_couriers' => $courierCount,
                'today_orders' => $todayOrders,
                'today_revenue' => $todayRevenue['revenue'] ?? 0
            ]);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération des statistiques: ' . $e->getMessage());
        }
    }
}
?>
