<?php
/**
 * Pharmacy Model
 * Handle pharmacy operations and stock management
 */

namespace Models;

use Core\DB;

class Pharmacy {
    private $db;
    
    public function __construct() {
        $this->db = DB::getInstance();
    }
    
    /**
     * Create pharmacy profile
     */
    public function create($userId, $data) {
        $pharmacy = [
            'id' => $this->generateUuid(),
            'user_id' => $userId,
            'name' => $data['name'],
            'lat' => $data['lat'],
            'lng' => $data['lng'],
            'address' => $data['address'],
            'verified' => false,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        $this->db->insert('pharmacies', $pharmacy);
        
        // Create wallet
        $this->db->insert('wallets', [
            'id' => $this->generateUuid(),
            'owner_type' => 'PHARMACY',
            'owner_id' => $pharmacy['id'],
            'balance' => 0,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        return $pharmacy['id'];
    }
    
    /**
     * Find pharmacy by user ID
     */
    public function findByUserId($userId) {
        return $this->db->fetchOne(
            "SELECT p.*, w.balance as wallet_balance 
             FROM pharmacies p 
             LEFT JOIN wallets w ON w.owner_type = 'PHARMACY' AND w.owner_id = p.id 
             WHERE p.user_id = ?",
            [$userId]
        );
    }
    
    /**
     * Find pharmacy by ID
     */
    public function findById($id) {
        return $this->db->fetchOne(
            "SELECT p.*, u.name as user_name, u.phone, u.email, w.balance as wallet_balance 
             FROM pharmacies p 
             INNER JOIN users u ON p.user_id = u.id 
             LEFT JOIN wallets w ON w.owner_type = 'PHARMACY' AND w.owner_id = p.id 
             WHERE p.id = ?",
            [$id]
        );
    }
    
    /**
     * Get all verified pharmacies
     */
    public function getVerified() {
        return $this->db->fetchAll(
            "SELECT p.*, u.name as user_name, u.phone 
             FROM pharmacies p 
             INNER JOIN users u ON p.user_id = u.id 
             WHERE p.verified = 1 
             ORDER BY p.name ASC"
        );
    }
    
    /**
     * Update pharmacy verification status
     */
    public function updateVerification($id, $verified = true) {
        return $this->db->update(
            'pharmacies',
            ['verified' => $verified ? 1 : 0],
            'id = ?',
            [$id]
        );
    }
    
    /**
     * Get pharmacy stock
     */
    public function getStock($pharmacyId, $medicineId = null) {
        $where = "ps.pharmacy_id = ?";
        $params = [$pharmacyId];
        
        if ($medicineId) {
            $where .= " AND ps.medicine_id = ?";
            $params[] = $medicineId;
        }
        
        return $this->db->fetchAll("
            SELECT ps.*, m.name as medicine_name, m.atc_code
            FROM pharmacy_stock ps
            INNER JOIN medicines m ON ps.medicine_id = m.id
            WHERE {$where}
            ORDER BY m.name ASC
        ", $params);
    }
    
    /**
     * Update stock quantity
     */
    public function updateStock($pharmacyId, $medicineId, $quantity, $unitPrice = null) {
        $updateData = ['stock' => $quantity];
        
        if ($unitPrice !== null) {
            $updateData['unit_price'] = $unitPrice;
        }
        
        $existing = $this->db->fetchOne(
            "SELECT * FROM pharmacy_stock WHERE pharmacy_id = ? AND medicine_id = ?",
            [$pharmacyId, $medicineId]
        );
        
        if ($existing) {
            return $this->db->update(
                'pharmacy_stock',
                $updateData,
                'pharmacy_id = ? AND medicine_id = ?',
                [$pharmacyId, $medicineId]
            );
        } else {
            $updateData['id'] = $this->generateUuid();
            $updateData['pharmacy_id'] = $pharmacyId;
            $updateData['medicine_id'] = $medicineId;
            
            if ($unitPrice === null) {
                $updateData['unit_price'] = 0;
            }
            
            return $this->db->insert('pharmacy_stock', $updateData);
        }
    }
    
    /**
     * Decrease stock (when order is confirmed)
     */
    public function decreaseStock($pharmacyId, $medicineId, $quantity) {
        $current = $this->db->fetchOne(
            "SELECT stock FROM pharmacy_stock WHERE pharmacy_id = ? AND medicine_id = ?",
            [$pharmacyId, $medicineId]
        );
        
        if (!$current || $current['stock'] < $quantity) {
            throw new \Exception('Stock insuffisant');
        }
        
        return $this->db->update(
            'pharmacy_stock',
            ['stock' => $current['stock'] - $quantity],
            'pharmacy_id = ? AND medicine_id = ?',
            [$pharmacyId, $medicineId]
        );
    }
    
    /**
     * Check if pharmacy has medicine in stock
     */
    public function hasStock($pharmacyId, $medicineName, $quantity = 1) {
        $stock = $this->db->fetchOne("
            SELECT ps.stock, ps.unit_price
            FROM pharmacy_stock ps
            INNER JOIN medicines m ON ps.medicine_id = m.id
            WHERE ps.pharmacy_id = ? AND m.name LIKE ? AND ps.stock >= ?
        ", [$pharmacyId, "%{$medicineName}%", $quantity]);
        
        return $stock ? $stock : false;
    }
    
    /**
     * Get low stock items
     */
    public function getLowStock($pharmacyId, $threshold = 5) {
        return $this->db->fetchAll("
            SELECT ps.*, m.name as medicine_name
            FROM pharmacy_stock ps
            INNER JOIN medicines m ON ps.medicine_id = m.id
            WHERE ps.pharmacy_id = ? AND ps.stock <= ?
            ORDER BY ps.stock ASC, m.name ASC
        ", [$pharmacyId, $threshold]);
    }
    
    /**
     * Get pharmacy statistics
     */
    public function getStats($pharmacyId) {
        // Today's orders
        $todayOrders = $this->db->count(
            'orders',
            'pharmacy_id = ? AND DATE(created_at) = CURDATE()',
            [$pharmacyId]
        );
        
        // Today's revenue (completed orders)
        $todayRevenue = $this->db->fetchOne("
            SELECT SUM(med_price_total) as revenue
            FROM orders
            WHERE pharmacy_id = ? AND DATE(created_at) = CURDATE() AND status IN ('DELIVERED', 'CLOSED')
        ", [$pharmacyId]);
        
        // Total orders
        $totalOrders = $this->db->count('orders', 'pharmacy_id = ?', [$pharmacyId]);
        
        // Pending orders
        $pendingOrders = $this->db->count(
            'orders',
            'pharmacy_id = ? AND status = ?',
            [$pharmacyId, 'CREATED']
        );
        
        // Acceptance rate
        $acceptedOrders = $this->db->count(
            'orders',
            'pharmacy_id = ? AND status IN (?, ?, ?, ?, ?)',
            [$pharmacyId, 'PHARMACY_CONFIRMED', 'COURIER_ASSIGNED', 'PICKED_UP', 'DELIVERED', 'CLOSED']
        );
        
        $acceptanceRate = $totalOrders > 0 ? round(($acceptedOrders / $totalOrders) * 100, 1) : 0;
        
        return [
            'today_orders' => $todayOrders,
            'today_revenue' => $todayRevenue['revenue'] ?? 0,
            'total_orders' => $totalOrders,
            'pending_orders' => $pendingOrders,
            'acceptance_rate' => $acceptanceRate
        ];
    }
    
    /**
     * Get pharmacy wallet balance
     */
    public function getWalletBalance($pharmacyId) {
        $wallet = $this->db->fetchOne(
            "SELECT balance FROM wallets WHERE owner_type = 'PHARMACY' AND owner_id = ?",
            [$pharmacyId]
        );
        
        return $wallet ? $wallet['balance'] : 0;
    }
    
    /**
     * Get pharmacy transaction history
     */
    public function getTransactionHistory($pharmacyId, $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 = 'PHARMACY' AND o.pharmacy_id = ?
            ORDER BY l.created_at DESC
            LIMIT {$limit}
        ", [$pharmacyId]);
    }
    
    /**
     * 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)
        );
    }
}
?>
