<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\License;
use App\Models\LicenseAnalytics;
use App\Models\Product;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * AI License Analytics Service
 * 
 * Provides AI-powered analytics and insights for license management
 * including predictive analytics, customer behavior analysis, and
 * intelligent recommendations.
 */
class AILicenseAnalyticsService
{
    private const CACHE_TTL = 3600; // 1 hour
    private const PREDICTION_MODEL_VERSION = '1.0';

    /**
     * Get comprehensive license analytics dashboard data
     */
    public function getDashboardAnalytics(int $days = 30): array
    {
        $cacheKey = "ai_analytics_dashboard_{$days}";
        
        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($days) {
            return [
                'overview' => $this->getOverviewStats($days),
                'trends' => $this->getTrendAnalysis($days),
                'predictions' => $this->getPredictiveInsights($days),
                'customer_insights' => $this->getCustomerInsights($days),
                'product_performance' => $this->getProductPerformance($days),
                'geographic_distribution' => $this->getGeographicDistribution($days),
                'anomaly_detection' => $this->detectAnomalies($days),
            ];
        });
    }

    /**
     * Get overview statistics with AI-enhanced insights
     */
    private function getOverviewStats(int $days): array
    {
        $startDate = now()->subDays($days);
        
        $stats = [
            'total_licenses' => License::count(),
            'active_licenses' => License::where('status', 'active')->count(),
            'expired_licenses' => License::where('status', 'expired')->count(),
            'suspended_licenses' => License::where('status', 'suspended')->count(),
            'total_customers' => User::where('role', 'customer')->count(),
            'total_products' => Product::count(),
            'revenue' => $this->calculateRevenue($startDate),
            'growth_rate' => $this->calculateGrowthRate($days),
            'churn_rate' => $this->calculateChurnRate($days),
            'customer_lifetime_value' => $this->calculateCustomerLifetimeValue(),
        ];

        // Add AI insights
        $stats['ai_insights'] = [
            'health_score' => $this->calculateHealthScore($stats),
            'risk_level' => $this->assessRiskLevel($stats),
            'recommendations' => $this->generateRecommendations($stats),
        ];

        return $stats;
    }

    /**
     * Get trend analysis with predictive elements
     */
    private function getTrendAnalysis(int $days): array
    {
        $startDate = now()->subDays($days);
        
        // Get daily license creation trends
        $licenseTrends = License::selectRaw('DATE(created_at) as date, COUNT(*) as count')
            ->where('created_at', '>=', $startDate)
            ->groupBy('date')
            ->orderBy('date')
            ->get()
            ->pluck('count', 'date')
            ->toArray();

        // Get daily revenue trends
        $revenueTrends = $this->getRevenueTrends($startDate);

        // Get customer acquisition trends
        $customerTrends = User::selectRaw('DATE(created_at) as date, COUNT(*) as count')
            ->where('role', 'customer')
            ->where('created_at', '>=', $startDate)
            ->groupBy('date')
            ->orderBy('date')
            ->get()
            ->pluck('count', 'date')
            ->toArray();

        // Apply AI smoothing and prediction
        $smoothedTrends = $this->applyAISmoothing($licenseTrends);
        $predictions = $this->predictFutureTrends($smoothedTrends, 7); // Predict next 7 days

        return [
            'license_creation' => [
                'historical' => $licenseTrends,
                'smoothed' => $smoothedTrends,
                'predicted' => $predictions,
            ],
            'revenue' => $revenueTrends,
            'customer_acquisition' => $customerTrends,
            'trend_direction' => $this->analyzeTrendDirection($smoothedTrends),
            'seasonality' => $this->detectSeasonality($licenseTrends),
        ];
    }

    /**
     * Get predictive insights using machine learning algorithms
     */
    private function getPredictiveInsights(int $days): array
    {
        $insights = [];

        // License expiration predictions
        $insights['license_expirations'] = $this->predictLicenseExpirations();

        // Revenue forecasting
        $insights['revenue_forecast'] = $this->forecastRevenue($days);

        // Customer churn prediction
        $insights['churn_prediction'] = $this->predictCustomerChurn();

        // Product performance prediction
        $insights['product_performance'] = $this->predictProductPerformance();

        // Market demand prediction
        $insights['market_demand'] = $this->predictMarketDemand();

        return $insights;
    }

    /**
     * Get customer insights with behavioral analysis
     */
    private function getCustomerInsights(int $days): array
    {
        $startDate = now()->subDays($days);

        // Customer segmentation
        $segments = $this->performCustomerSegmentation();

        // Customer behavior analysis
        $behaviorAnalysis = $this->analyzeCustomerBehavior($startDate);

        // Customer lifetime value analysis
        $ltvAnalysis = $this->analyzeCustomerLifetimeValue();

        // Customer satisfaction prediction
        $satisfactionPrediction = $this->predictCustomerSatisfaction();

        return [
            'segmentation' => $segments,
            'behavior_analysis' => $behaviorAnalysis,
            'lifetime_value' => $ltvAnalysis,
            'satisfaction_prediction' => $satisfactionPrediction,
            'recommendations' => $this->generateCustomerRecommendations($segments),
        ];
    }

    /**
     * Get product performance with AI analysis
     */
    private function getProductPerformance(int $days): array
    {
        $startDate = now()->subDays($days);

        $products = Product::withCount(['licenses' => function ($query) use ($startDate) {
            $query->where('created_at', '>=', $startDate);
        }])->get();

        $performance = [];
        foreach ($products as $product) {
            $performance[] = [
                'product_id' => $product->id,
                'name' => $product->name,
                'license_count' => $product->licenses_count,
                'revenue' => $this->calculateProductRevenue($product, $startDate),
                'growth_rate' => $this->calculateProductGrowthRate($product, $days),
                'market_share' => $this->calculateMarketShare($product),
                'customer_satisfaction' => $this->calculateProductSatisfaction($product),
                'ai_score' => $this->calculateProductAIScore($product),
                'recommendations' => $this->generateProductRecommendations($product),
            ];
        }

        // Sort by AI score
        usort($performance, fn($a, $b) => $b['ai_score'] <=> $a['ai_score']);

        return $performance;
    }

    /**
     * Get geographic distribution with heatmap data
     */
    private function getGeographicDistribution(int $days): array
    {
        $startDate = now()->subDays($days);

        // Get license distribution by country
        $distribution = License::selectRaw('country, COUNT(*) as count')
            ->where('created_at', '>=', $startDate)
            ->whereNotNull('country')
            ->groupBy('country')
            ->orderByDesc('count')
            ->get()
            ->toArray();

        // Get revenue by country
        $revenueByCountry = $this->getRevenueByCountry($startDate);

        // Calculate market penetration
        $marketPenetration = $this->calculateMarketPenetration($distribution);

        return [
            'distribution' => $distribution,
            'revenue_by_country' => $revenueByCountry,
            'market_penetration' => $marketPenetration,
            'growth_opportunities' => $this->identifyGrowthOpportunities($distribution),
        ];
    }

    /**
     * Detect anomalies in license patterns
     */
    private function detectAnomalies(int $days): array
    {
        $startDate = now()->subDays($days);
        $anomalies = [];

        // Detect unusual license creation patterns
        $licenseAnomalies = $this->detectLicenseCreationAnomalies($startDate);
        if (!empty($licenseAnomalies)) {
            $anomalies['license_creation'] = $licenseAnomalies;
        }

        // Detect suspicious activity
        $suspiciousActivity = $this->detectSuspiciousActivity($startDate);
        if (!empty($suspiciousActivity)) {
            $anomalies['suspicious_activity'] = $suspiciousActivity;
        }

        // Detect revenue anomalies
        $revenueAnomalies = $this->detectRevenueAnomalies($startDate);
        if (!empty($revenueAnomalies)) {
            $anomalies['revenue'] = $revenueAnomalies;
        }

        return $anomalies;
    }

    /**
     * Predict license expirations with confidence scores
     */
    private function predictLicenseExpirations(): array
    {
        $expiringSoon = License::where('license_expires_at', '<=', now()->addDays(30))
            ->where('status', 'active')
            ->get();

        $predictions = [];
        foreach ($expiringSoon as $license) {
            $renewalProbability = $this->calculateRenewalProbability($license);
            $predictions[] = [
                'license_id' => $license->id,
                'expires_at' => $license->license_expires_at,
                'days_until_expiry' => now()->diffInDays($license->license_expires_at),
                'renewal_probability' => $renewalProbability,
                'confidence_score' => $this->calculateConfidenceScore($license),
                'recommended_action' => $this->getRecommendedAction($renewalProbability),
            ];
        }

        // Sort by renewal probability (lowest first - highest risk)
        usort($predictions, fn($a, $b) => $a['renewal_probability'] <=> $b['renewal_probability']);

        return $predictions;
    }

    /**
     * Forecast revenue using time series analysis
     */
    private function forecastRevenue(int $days): array
    {
        $startDate = now()->subDays($days);
        $historicalRevenue = $this->getHistoricalRevenue($startDate);

        // Apply time series forecasting (simplified version)
        $forecast = $this->applyTimeSeriesForecasting($historicalRevenue, 30); // Forecast next 30 days

        return [
            'historical' => $historicalRevenue,
            'forecast' => $forecast,
            'confidence_interval' => $this->calculateConfidenceInterval($forecast),
            'trend' => $this->analyzeRevenueTrend($historicalRevenue),
        ];
    }

    /**
     * Predict customer churn using behavioral patterns
     */
    private function predictCustomerChurn(): array
    {
        $customers = User::where('role', 'customer')->with(['licenses'])->get();
        $churnPredictions = [];

        foreach ($customers as $customer) {
            $churnScore = $this->calculateChurnScore($customer);
            $churnPredictions[] = [
                'customer_id' => $customer->id,
                'name' => $customer->name,
                'email' => $customer->email,
                'churn_score' => $churnScore,
                'risk_level' => $this->getRiskLevel($churnScore),
                'last_activity' => $this->getLastActivity($customer),
                'recommended_actions' => $this->getChurnPreventionActions($churnScore),
            ];
        }

        // Sort by churn score (highest first - highest risk)
        usort($churnPredictions, fn($a, $b) => $b['churn_score'] <=> $a['churn_score']);

        return array_slice($churnPredictions, 0, 20); // Top 20 at risk
    }

    /**
     * Calculate renewal probability based on customer behavior
     */
    private function calculateRenewalProbability(License $license): float
    {
        $factors = [];

        // Customer history factor
        $customerHistory = $this->getCustomerHistory($license->user_id);
        $factors['customer_history'] = $customerHistory;

        // License usage factor
        $usageFactor = $this->getLicenseUsageFactor($license);
        $factors['usage'] = $usageFactor;

        // Payment history factor
        $paymentHistory = $this->getPaymentHistory($license->user_id);
        $factors['payment_history'] = $paymentHistory;

        // Time since last activity
        $activityFactor = $this->getActivityFactor($license);
        $factors['activity'] = $activityFactor;

        // Calculate weighted probability
        $weights = [
            'customer_history' => 0.3,
            'usage' => 0.25,
            'payment_history' => 0.25,
            'activity' => 0.2,
        ];

        $probability = 0;
        foreach ($factors as $factor => $value) {
            $probability += $value * $weights[$factor];
        }

        return min(1.0, max(0.0, $probability));
    }

    /**
     * Apply AI smoothing to trend data
     */
    private function applyAISmoothing(array $data): array
    {
        if (count($data) < 3) {
            return $data;
        }

        $smoothed = [];
        $values = array_values($data);
        $keys = array_keys($data);

        for ($i = 0; $i < count($values); $i++) {
            if ($i === 0 || $i === count($values) - 1) {
                $smoothed[$keys[$i]] = $values[$i];
            } else {
                // Simple moving average with AI weighting
                $weighted = ($values[$i-1] * 0.25) + ($values[$i] * 0.5) + ($values[$i+1] * 0.25);
                $smoothed[$keys[$i]] = round($weighted, 2);
            }
        }

        return $smoothed;
    }

    /**
     * Predict future trends using linear regression
     */
    private function predictFutureTrends(array $data, int $days): array
    {
        if (count($data) < 2) {
            return [];
        }

        $values = array_values($data);
        $n = count($values);

        // Calculate linear regression
        $sumX = 0;
        $sumY = 0;
        $sumXY = 0;
        $sumXX = 0;

        for ($i = 0; $i < $n; $i++) {
            $x = $i;
            $y = $values[$i];
            $sumX += $x;
            $sumY += $y;
            $sumXY += $x * $y;
            $sumXX += $x * $x;
        }

        $slope = ($n * $sumXY - $sumX * $sumY) / ($n * $sumXX - $sumX * $sumX);
        $intercept = ($sumY - $slope * $sumX) / $n;

        // Generate predictions
        $predictions = [];
        $lastDate = array_key_last($data);
        $baseDate = \Carbon\Carbon::parse($lastDate);

        for ($i = 1; $i <= $days; $i++) {
            $predictedValue = $intercept + $slope * ($n + $i - 1);
            $predictedDate = $baseDate->copy()->addDays($i)->format('Y-m-d');
            $predictions[$predictedDate] = max(0, round($predictedValue, 2));
        }

        return $predictions;
    }

    /**
     * Calculate health score for the business
     */
    private function calculateHealthScore(array $stats): float
    {
        $factors = [
            'growth_rate' => min(1.0, max(0.0, $stats['growth_rate'] / 100)),
            'churn_rate' => max(0.0, 1.0 - ($stats['churn_rate'] / 100)),
            'active_licenses' => min(1.0, $stats['active_licenses'] / 1000),
            'customer_satisfaction' => 0.8, // Placeholder - would come from surveys
        ];

        $weights = [
            'growth_rate' => 0.3,
            'churn_rate' => 0.3,
            'active_licenses' => 0.2,
            'customer_satisfaction' => 0.2,
        ];

        $score = 0;
        foreach ($factors as $factor => $value) {
            $score += $value * $weights[$factor];
        }

        return round($score * 100, 1);
    }

    /**
     * Generate intelligent recommendations
     */
    private function generateRecommendations(array $stats): array
    {
        $recommendations = [];

        if ($stats['churn_rate'] > 10) {
            $recommendations[] = [
                'type' => 'churn_prevention',
                'priority' => 'high',
                'title' => 'High Churn Rate Detected',
                'description' => 'Customer churn rate is above 10%. Consider implementing retention strategies.',
                'action' => 'Review customer feedback and implement retention programs.',
            ];
        }

        if ($stats['growth_rate'] < 5) {
            $recommendations[] = [
                'type' => 'growth',
                'priority' => 'medium',
                'title' => 'Low Growth Rate',
                'description' => 'Growth rate is below 5%. Consider marketing initiatives.',
                'action' => 'Increase marketing efforts and improve product features.',
            ];
        }

        if ($stats['active_licenses'] > 1000) {
            $recommendations[] = [
                'type' => 'scaling',
                'priority' => 'low',
                'title' => 'Consider Scaling Infrastructure',
                'description' => 'High number of active licenses. Ensure infrastructure can handle load.',
                'action' => 'Review server capacity and consider load balancing.',
            ];
        }

        return $recommendations;
    }

    /**
     * Log analytics event for tracking
     */
    public function logAnalyticsEvent(string $eventType, array $eventData = []): void
    {
        LicenseAnalytics::logEvent(
            licenseId: 0, // System event
            eventType: $eventType,
            eventData: $eventData,
            ipAddress: request()->ip(),
            userAgent: request()->userAgent()
        );
    }

    /**
     * Get real-time analytics updates
     */
    public function getRealTimeUpdates(): array
    {
        $cacheKey = 'realtime_analytics_' . now()->format('Y-m-d-H');
        
        return Cache::remember($cacheKey, 300, function () { // 5 minutes cache
            return [
                'active_licenses_now' => License::where('status', 'active')->count(),
                'licenses_created_today' => License::whereDate('created_at', today())->count(),
                'revenue_today' => $this->calculateTodayRevenue(),
                'api_calls_last_hour' => $this->getApiCallsLastHour(),
                'system_health' => $this->getSystemHealthMetrics(),
            ];
        });
    }

    // Helper methods for calculations
    private function calculateRevenue(\Carbon\Carbon $startDate): float
    {
        // Implementation would calculate revenue from invoices/payments
        return 0.0; // Placeholder
    }

    private function calculateGrowthRate(int $days): float
    {
        $currentPeriod = License::where('created_at', '>=', now()->subDays($days))->count();
        $previousPeriod = License::whereBetween('created_at', [
            now()->subDays($days * 2),
            now()->subDays($days)
        ])->count();

        if ($previousPeriod === 0) {
            return $currentPeriod > 0 ? 100.0 : 0.0;
        }

        return (($currentPeriod - $previousPeriod) / $previousPeriod) * 100;
    }

    private function calculateChurnRate(int $days): float
    {
        $totalCustomers = User::where('role', 'customer')->count();
        $churnedCustomers = User::where('role', 'customer')
            ->where('last_login_at', '<', now()->subDays($days))
            ->count();

        return $totalCustomers > 0 ? ($churnedCustomers / $totalCustomers) * 100 : 0.0;
    }

    private function calculateCustomerLifetimeValue(): float
    {
        // Implementation would calculate CLV based on historical data
        return 0.0; // Placeholder
    }

    // Additional helper methods would be implemented here...
    // (calculateHealthScore, assessRiskLevel, generateRecommendations, etc.)
}
