<?php
/**
 * Pharmacy Controller
 * Handle pharmacy dashboard and operations
 */

namespace Controllers;

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

class PharmacyController extends Controller {
    
    /**
     * Pharmacy dashboard
     */
    public function dashboard($params = []) {
        $userId = $this->requireRole('pharmacy');
        
        if (Helpers::isAjax()) {
            // Return JSON data for AJAX requests
            $this->getDashboardData($userId);
        } else {
            // Return HTML view
            $this->view('pharmacy/dashboard', [
                'title' => 'Tableau de bord Pharmacie - ' . APP_NAME,
                'user' => Auth::user()
            ]);
        }
    }
    
    /**
     * Get dashboard data
     */
    private function getDashboardData($userId) {
        try {
            $pharmacyModel = new Pharmacy();
            $orderModel = new Order();
            
            $pharmacy = $pharmacyModel->findByUserId($userId);
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            // Get pending orders
            $pendingOrders = $orderModel->getByPharmacy($pharmacy['id'], 'CREATED');
            
            // Get pharmacy statistics
            $stats = $pharmacyModel->getStats($pharmacy['id']);
            
            // Get low stock items
            $lowStock = $pharmacyModel->getLowStock($pharmacy['id']);
            
            $this->success([
                'pharmacy' => $pharmacy,
                'pending_orders' => $pendingOrders,
                'stats' => $stats,
                'low_stock' => $lowStock
            ]);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération des données: ' . $e->getMessage());
        }
    }
    
    /**
     * Get pharmacy orders
     */
    public function orders($params = []) {
        $userId = $this->requireRole('pharmacy');
        
        try {
            $pharmacyModel = new Pharmacy();
            $orderModel = new Order();
            
            $pharmacy = $pharmacyModel->findByUserId($userId);
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $status = $_GET['status'] ?? null;
            $orders = $orderModel->getByPharmacy($pharmacy['id'], $status);
            
            $this->success($orders);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération des commandes: ' . $e->getMessage());
        }
    }
    
    /**
     * Respond to order (accept/reject)
     */
    public function respondToOrder($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 {
            $pharmacyModel = new Pharmacy();
            $orderModel = new Order();
            
            $pharmacy = $pharmacyModel->findByUserId($userId);
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $order = $orderModel->findById($params['id']);
            if (!$order) {
                $this->error('Commande non trouvée', 404);
            }
            
            if ($order['pharmacy_id'] !== $pharmacy['id']) {
                $this->error('Permission refusée', 403);
            }
            
            if ($order['status'] !== 'CREATED') {
                $this->error('Commande ne peut plus être modifiée');
            }
            
            if ($input['action'] === 'accept') {
                if (!isset($input['unit_price']) || $input['unit_price'] <= 0) {
                    $this->error('Prix unitaire requis');
                }
                
                // Check stock availability
                $hasStock = $pharmacyModel->hasStock($pharmacy['id'], $order['medicine_name'], $order['qty']);
                if (!$hasStock) {
                    $this->error('Stock insuffisant');
                }
                
                $orderModel->pharmacyConfirm($params['id'], (int)$input['unit_price']);
                
                // Try to 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);
                
                // Find next pharmacy
                $nextPharmacies = $orderModel->findNearbyPharmacies(
                    $order['client_lat'],
                    $order['client_lng'],
                    $order['medicine_name'],
                    [$pharmacy['id']]
                );
                
                if (!empty($nextPharmacies)) {
                    $medicine = (new Medicine())->findOrCreate($order['medicine_name']);
                    $orderModel->assignPharmacy($params['id'], $nextPharmacies[0]['id'], $medicine['id']);
                }
                
                $this->log("Pharmacy rejected order: {$params['id']}");
                $message = 'Commande refusée et transférée';
            }
            
            $this->success([], $message);
            
        } catch (\Exception $e) {
            $this->log("Pharmacy response failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors du traitement: ' . $e->getMessage());
        }
    }
    
    /**
     * Get pharmacy stock
     */
    public function stock($params = []) {
        $userId = $this->requireRole('pharmacy');
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $stock = $pharmacyModel->getStock($pharmacy['id']);
            
            $this->success($stock);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération du stock: ' . $e->getMessage());
        }
    }
    
    /**
     * Update stock item
     */
    public function updateStock($params = []) {
        $userId = $this->requireRole('pharmacy');
        $input = $this->getInput();
        
        $this->validateRequired($input, ['medicine_id', 'quantity']);
        
        if ($input['quantity'] < 0) {
            $this->error('La quantité ne peut pas être négative');
        }
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $unitPrice = isset($input['unit_price']) ? (int)$input['unit_price'] : null;
            
            $pharmacyModel->updateStock(
                $pharmacy['id'],
                $input['medicine_id'],
                (int)$input['quantity'],
                $unitPrice
            );
            
            $this->log("Stock updated: pharmacy {$pharmacy['id']}, medicine {$input['medicine_id']}");
            
            $this->success([], 'Stock mis à jour avec succès');
            
        } catch (\Exception $e) {
            $this->log("Stock update failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors de la mise à jour du stock: ' . $e->getMessage());
        }
    }
    
    /**
     * Get pharmacy statistics
     */
    public function stats($params = []) {
        $userId = $this->requireRole('pharmacy');
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $stats = $pharmacyModel->getStats($pharmacy['id']);
            $lowStock = $pharmacyModel->getLowStock($pharmacy['id']);
            
            $this->success([
                'stats' => $stats,
                'low_stock_count' => count($lowStock),
                'wallet_balance' => $pharmacy['wallet_balance'] ?? 0
            ]);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération des statistiques: ' . $e->getMessage());
        }
    }
    
    /**
     * Get transaction history
     */
    public function transactions($params = []) {
        $userId = $this->requireRole('pharmacy');
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $limit = $_GET['limit'] ?? 50;
            $transactions = $pharmacyModel->getTransactionHistory($pharmacy['id'], $limit);
            
            $this->success($transactions);
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la récupération de l\'historique: ' . $e->getMessage());
        }
    }
    
    /**
     * Request payout
     */
    public function requestPayout($params = []) {
        $userId = $this->requireRole('pharmacy');
        $input = $this->getInput();
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $balance = $pharmacyModel->getWalletBalance($pharmacy['id']);
            $requestedAmount = $input['amount'] ?? $balance;
            
            if ($requestedAmount <= 0 || $requestedAmount > $balance) {
                $this->error('Montant invalide');
            }
            
            // In a real system, this would create a payout request
            // For now, just log it
            $this->log("Payout requested: pharmacy {$pharmacy['id']}, amount {$requestedAmount}");
            
            $this->success([
                'requested_amount' => $requestedAmount,
                'status' => 'pending'
            ], 'Demande de paiement soumise');
            
        } catch (\Exception $e) {
            $this->error('Erreur lors de la demande de paiement: ' . $e->getMessage());
        }
    }
    
    /**
     * Update pharmacy profile
     */
    public function updateProfile($params = []) {
        $userId = $this->requireRole('pharmacy');
        $input = $this->getInput();
        
        try {
            $pharmacyModel = new Pharmacy();
            $pharmacy = $pharmacyModel->findByUserId($userId);
            
            if (!$pharmacy) {
                $this->error('Profil pharmacie non trouvé');
            }
            
            $updateData = [];
            $allowedFields = ['name', 'address', 'lat', 'lng'];
            
            foreach ($allowedFields as $field) {
                if (isset($input[$field])) {
                    $updateData[$field] = $this->sanitize($input[$field]);
                }
            }
            
            if (isset($updateData['lat']) && isset($updateData['lng'])) {
                if (!Helpers::validateCoordinates($updateData['lat'], $updateData['lng'])) {
                    $this->error('Coordonnées géographiques invalides');
                }
            }
            
            if (!empty($updateData)) {
                $this->db->update('pharmacies', $updateData, 'id = ?', [$pharmacy['id']]);
                $this->log("Pharmacy profile updated: {$pharmacy['id']}");
            }
            
            $this->success([], 'Profil mis à jour avec succès');
            
        } catch (\Exception $e) {
            $this->log("Pharmacy profile update failed: " . $e->getMessage(), 'error');
            $this->error('Erreur lors de la mise à jour: ' . $e->getMessage());
        }
    }
}
?>
