<?php
namespace App\classes;

use mysqli;

/**
 * External API Pricing Manager
 * Manages pricing for external API orders using range-based pricing (like agent_pricing_rules)
 * Only handles MTN network
 */
class ExternalAPIPricingManager
{
    private $conn;

    public function __construct(mysqli $conn)
    {
        $this->conn = $conn;
    }

    /**
     * Get external API price for a package (from other website) - uses ranges
     */
    public function getExternalPrice($packageSize, $networkType = 'mtn')
    {
        $packageSizeGb = $this->normalizePackageSize($packageSize);

        $stmt = $this->conn->prepare("
            SELECT price_per_gb 
            FROM external_api_pricing_ranges 
            WHERE network_type = ? 
            AND min_size_gb <= ? 
            AND max_size_gb >= ?
            AND is_active = 1
            ORDER BY min_size_gb DESC
            LIMIT 1
        ");
        
        $stmt->bind_param("sdd", $networkType, $packageSizeGb, $packageSizeGb);
        $stmt->execute();
        $result = $stmt->get_result();
        $row = $result->fetch_assoc();
        $stmt->close();

        if ($row) {
            // Calculate price: price_per_gb * package_size_gb
            return (float)$row['price_per_gb'] * $packageSizeGb;
        }

        return null;
    }

    /**
     * Get admin price for external API orders - fetches from agent_pricing_rules (same as admin pricing for agents)
     */
    public function getAdminPrice($packageSize, $networkType = 'mtn')
    {
        $packageSizeGb = $this->normalizePackageSize($packageSize);

        $stmt = $this->conn->prepare("
            SELECT price_per_gb 
            FROM agent_pricing_rules 
            WHERE network_type = ? 
            AND role = 'agent'
            AND min_size_gb <= ? 
            AND max_size_gb >= ?
            AND is_active = 1
            ORDER BY min_size_gb DESC
            LIMIT 1
        ");
        
        $stmt->bind_param("sdd", $networkType, $packageSizeGb, $packageSizeGb);
        $stmt->execute();
        $result = $stmt->get_result();
        $row = $result->fetch_assoc();
        $stmt->close();

        if ($row) {
            // Calculate price: price_per_gb * package_size_gb
            return (float)$row['price_per_gb'] * $packageSizeGb;
        }

        return null;
    }

    /**
     * Set external API price range (from other website)
     */
    public function setExternalPriceRange($networkType, $minSizeGb, $maxSizeGb, $pricePerGb, $isActive = 1, $updatedBy = 'admin')
    {
        // Validate range
        if ($minSizeGb <= 0 || $maxSizeGb <= 0 || $pricePerGb <= 0) {
            return false;
        }

        if ($minSizeGb >= $maxSizeGb) {
            return false;
        }

        // Check for overlapping ranges
        $checkStmt = $this->conn->prepare("
            SELECT id FROM external_api_pricing_ranges 
            WHERE network_type = ? 
            AND ? < max_size_gb 
            AND ? > min_size_gb
        ");
        $checkStmt->bind_param("sdd", $networkType, $minSizeGb, $maxSizeGb);
        $checkStmt->execute();
        $checkResult = $checkStmt->get_result();
        
        if ($checkResult->num_rows > 0) {
            $checkStmt->close();
            return false; // Overlapping range exists
        }
        $checkStmt->close();

        $stmt = $this->conn->prepare("
            INSERT INTO external_api_pricing_ranges 
            (network_type, min_size_gb, max_size_gb, price_per_gb, is_active, updated_by)
            VALUES (?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE 
                price_per_gb = VALUES(price_per_gb),
                is_active = VALUES(is_active),
                last_updated = NOW(),
                updated_by = VALUES(updated_by)
        ");
        
        $stmt->bind_param("sdddis", $networkType, $minSizeGb, $maxSizeGb, $pricePerGb, $isActive, $updatedBy);
        $result = $stmt->execute();
        $stmt->close();

        return $result;
    }

    /**
     * Get all admin pricing ranges from agent_pricing_rules (same as admin pricing for agents)
     */
    public function getAllAdminPricing($networkType = 'mtn')
    {
        $stmt = $this->conn->prepare("
            SELECT id, network_type, min_size_gb, max_size_gb, price_per_gb as admin_price_per_gb, 
                   is_active, created_at, updated_at
            FROM agent_pricing_rules
            WHERE network_type = ? AND role = 'agent'
            ORDER BY min_size_gb ASC
        ");
        
        $stmt->bind_param("s", $networkType);
        $stmt->execute();
        $result = $stmt->get_result();
        $pricing = [];
        
        while ($row = $result->fetch_assoc()) {
            $pricing[] = $row;
        }
        
        $stmt->close();
        return $pricing;
    }

    /**
     * Get all external API pricing ranges
     */
    public function getAllExternalPricing($networkType = 'mtn')
    {
        $stmt = $this->conn->prepare("
            SELECT id, network_type, min_size_gb, max_size_gb, price_per_gb, is_active, 
                   last_updated, updated_by
            FROM external_api_pricing_ranges
            WHERE network_type = ?
            ORDER BY min_size_gb ASC
        ");
        
        $stmt->bind_param("s", $networkType);
        $stmt->execute();
        $result = $stmt->get_result();
        $pricing = [];
        
        while ($row = $result->fetch_assoc()) {
            $pricing[] = $row;
        }
        
        $stmt->close();
        return $pricing;
    }


    /**
     * Update external API pricing range
     */
    public function updateExternalPriceRange($id, $networkType, $minSizeGb, $maxSizeGb, $pricePerGb, $isActive = 1)
    {
        // Validate range
        if ($minSizeGb <= 0 || $maxSizeGb <= 0 || $pricePerGb <= 0) {
            return false;
        }

        if ($minSizeGb >= $maxSizeGb) {
            return false;
        }

        // Check for overlapping ranges (excluding current)
        $checkStmt = $this->conn->prepare("
            SELECT id FROM external_api_pricing_ranges 
            WHERE network_type = ? 
            AND ? < max_size_gb 
            AND ? > min_size_gb
            AND id != ?
        ");
        $checkStmt->bind_param("sddi", $networkType, $minSizeGb, $maxSizeGb, $id);
        $checkStmt->execute();
        $checkResult = $checkStmt->get_result();
        
        if ($checkResult->num_rows > 0) {
            $checkStmt->close();
            return false; // Overlapping range exists
        }
        $checkStmt->close();

        $stmt = $this->conn->prepare("
            UPDATE external_api_pricing_ranges 
            SET network_type = ?, min_size_gb = ?, max_size_gb = ?, 
                price_per_gb = ?, is_active = ?, last_updated = NOW()
            WHERE id = ?
        ");
        
        $stmt->bind_param("sdddii", $networkType, $minSizeGb, $maxSizeGb, $pricePerGb, $isActive, $id);
        $result = $stmt->execute();
        $stmt->close();

        return $result;
    }

    /**
     * Delete external API pricing range
     */
    public function deleteExternalPriceRange($id)
    {
        $stmt = $this->conn->prepare("DELETE FROM external_api_pricing_ranges WHERE id = ?");
        $stmt->bind_param("i", $id);
        $result = $stmt->execute();
        $stmt->close();
        return $result;
    }

    /**
     * Normalize package size to GB
     */
    public function normalizePackageSize($packageSize)
    {
        $packageSize = trim((string)$packageSize);
        
        if (preg_match('/(\d+(?:\.\d+)?)\s*GB/i', $packageSize, $matches)) {
            return (float)$matches[1];
        }
        
        if (preg_match('/(\d+(?:\.\d+)?)\s*MB/i', $packageSize, $matches)) {
            return round(((float)$matches[1]) / 1024, 4);
        }
        
        // If just a number, assume GB
        $num = floatval(preg_replace('/[^0-9.]/', '', $packageSize));
        return $num > 0 ? $num : 0;
    }

    /**
     * Format package label
     */
    private function formatPackageLabel($sizeGb)
    {
        if ($sizeGb < 1) {
            return round($sizeGb * 1024, 0) . 'MB';
        }
        return $sizeGb . 'GB';
    }

    /**
     * Calculate profit for an order
     */
    public function calculateProfit($packageSize, $networkType = 'mtn')
    {
        $adminPrice = $this->getAdminPrice($packageSize, $networkType);
        $externalPrice = $this->getExternalPrice($packageSize, $networkType);

        if ($adminPrice === null || $externalPrice === null) {
            return null;
        }

        return $adminPrice - $externalPrice;
    }
}
