<?php

namespace App\Services;

use App\Models\AdminActivityLog;
use App\Models\AdminSession;
use App\Models\User;
use Illuminate\Support\Facades\Cache;

class AnalyticsService
{
    /**
     * Get comprehensive dashboard analytics
     */
    public static function getDashboardAnalytics()
    {
        return Cache::remember('dashboard_analytics', 300, function () {
            return [
                'overview' => static::getOverviewStats(),
                'activity_trends' => static::getActivityTrends(),
                'user_analytics' => static::getUserAnalytics(),
                'admin_performance' => static::getAdminPerformance(),
                'security_metrics' => static::getSecurityMetrics(),
                'system_health' => static::getSystemHealth(),
            ];
        });
    }

    /**
     * Get overview statistics
     */
    public static function getOverviewStats()
    {
        return [
            'total_users' => User::count(),
            'active_users' => User::where('status', 'active')->count(),
            'suspended_users' => User::where('status', 'suspended')->count(),
            'new_today' => User::whereDate('created_at', today())->count(),
            'new_this_week' => User::where('created_at', '>=', now()->subDays(7))->count(),
            'new_this_month' => User::whereMonth('created_at', now()->month)->count(),
            'active_sessions' => AdminSession::active()->count(),
            'total_activities' => AdminActivityLog::count(),
        ];
    }

    /**
     * Get activity trends for last 30 days
     */
    public static function getActivityTrends()
    {
        $trends = [];

        for ($i = 29; $i >= 0; $i--) {
            $date = now()->subDays($i);
            $count = AdminActivityLog::whereDate('created_at', $date)->count();
            $trends[] = [
                'date' => $date->format('Y-m-d'),
                'display_date' => $date->format('M d'),
                'count' => $count,
                'successful' => AdminActivityLog::whereDate('created_at', $date)
                    ->where('status', 'success')->count(),
                'failed' => AdminActivityLog::whereDate('created_at', $date)
                    ->where('status', 'failed')->count(),
            ];
        }

        return $trends;
    }

    /**
     * Get user analytics
     */
    public static function getUserAnalytics()
    {
        $usersByStatus = User::selectRaw('status, count(*) as count')
            ->groupBy('status')
            ->pluck('count', 'status')
            ->toArray();

        $userGrowth = [];
        for ($i = 11; $i >= 0; $i--) {
            $date = now()->startOfMonth()->subMonths($i);
            $count = User::where('created_at', '<', $date->endOfMonth())->count();
            $userGrowth[] = [
                'month' => $date->format('M Y'),
                'total' => $count,
            ];
        }

        return [
            'by_status' => $usersByStatus,
            'growth_by_month' => $userGrowth,
            'total' => User::count(),
            'active' => User::where('status', 'active')->count(),
            'inactive' => User::where('status', 'inactive')->count(),
            'suspended' => User::where('status', 'suspended')->count(),
        ];
    }

    /**
     * Get admin performance metrics
     */
    public static function getAdminPerformance()
    {
        $admins = AdminActivityLog::selectRaw('admin_user_id, COUNT(*) as total_actions, SUM(CASE WHEN status = "success" THEN 1 ELSE 0 END) as successful_actions, SUM(CASE WHEN status = "failed" THEN 1 ELSE 0 END) as failed_actions')
            ->where('created_at', '>=', now()->subDays(30))
            ->groupBy('admin_user_id')
            ->with('adminUser')
            ->orderBy('total_actions', 'desc')
            ->limit(10)
            ->get();

        $performance = [];
        foreach ($admins as $admin) {
            if ($admin->adminUser) {
                $successRate = $admin->total_actions > 0
                    ? round(($admin->successful_actions / $admin->total_actions) * 100, 2)
                    : 0;

                $performance[] = [
                    'admin_id' => $admin->admin_user_id,
                    'admin_name' => $admin->adminUser->first_name . ' ' . $admin->adminUser->last_name,
                    'admin_email' => $admin->adminUser->email,
                    'total_actions' => $admin->total_actions,
                    'successful_actions' => $admin->successful_actions,
                    'failed_actions' => $admin->failed_actions,
                    'success_rate' => $successRate,
                ];
            }
        }

        return [
            'top_admins' => $performance,
            'average_success_rate' => static::calculateAverageSuccessRate(),
        ];
    }

    /**
     * Get security metrics
     */
    public static function getSecurityMetrics()
    {
        $sensitiveActivities = AdminActivityLog::where('is_sensitive', true)
            ->where('created_at', '>=', now()->subDays(7))
            ->selectRaw('action, count(*) as count')
            ->groupBy('action')
            ->get();

        $failedActivities = AdminActivityLog::where('status', 'failed')
            ->where('created_at', '>=', now()->subDays(7))
            ->selectRaw('action, count(*) as count')
            ->groupBy('action')
            ->get();

        return [
            'total_alerts' => AdminActivityLog::where('is_sensitive', true)
                ->where('created_at', '>=', now()->subDays(30))->count(),
            'alerts_today' => AdminActivityLog::where('is_sensitive', true)
                ->whereDate('created_at', today())->count(),
            'alerts_this_week' => AdminActivityLog::where('is_sensitive', true)
                ->where('created_at', '>=', now()->subDays(7))->count(),
            'failed_actions_today' => AdminActivityLog::where('status', 'failed')
                ->whereDate('created_at', today())->count(),
            'failed_actions_this_week' => AdminActivityLog::where('status', 'failed')
                ->where('created_at', '>=', now()->subDays(7))->count(),
            'sensitive_by_action' => $sensitiveActivities,
            'failed_by_action' => $failedActivities,
        ];
    }

    /**
     * Get system health metrics
     */
    public static function getSystemHealth()
    {
        $totalActivities = AdminActivityLog::whereDate('created_at', today())->count();
        $successfulActivities = AdminActivityLog::whereDate('created_at', today())
            ->where('status', 'success')->count();
        $successRate = $totalActivities > 0
            ? round(($successfulActivities / $totalActivities) * 100, 2)
            : 100;

        $activeAdmins = AdminSession::where('is_active', true)->count();
        $activeSessions = AdminSession::where('is_active', true)->count();

        return [
            'success_rate' => $successRate,
            'total_activities_today' => $totalActivities,
            'successful_activities' => $successfulActivities,
            'failed_activities' => $totalActivities - $successfulActivities,
            'active_admins' => $activeAdmins,
            'active_sessions' => $activeSessions,
            'uptime_status' => 'Online',
            'db_status' => 'Connected',
            'cache_status' => 'Active',
        ];
    }

    /**
     * Get activity breakdown by type
     */
    public static function getActivityBreakdown($days = 7)
    {
        return AdminActivityLog::where('created_at', '>=', now()->subDays($days))
            ->selectRaw('action, count(*) as count')
            ->groupBy('action')
            ->orderBy('count', 'desc')
            ->get();
    }

    /**
     * Get hourly activity pattern
     */
    public static function getHourlyActivityPattern()
    {
        $pattern = [];

        for ($hour = 0; $hour < 24; $hour++) {
            $start = now()->copy()->startOfDay()->addHours($hour);
            $end = $start->copy()->addHour();

            $count = AdminActivityLog::whereBetween('created_at', [$start, $end])
                ->where('created_at', '>=', now()->subDays(7))
                ->count();

            $pattern[] = [
                'hour' => $hour . ':00',
                'count' => $count,
            ];
        }

        return $pattern;
    }

    /**
     * Get user retention metrics
     */
    public static function getUserRetention()
    {
        $retention = [];

        for ($i = 11; $i >= 0; $i--) {
            $startDate = now()->startOfMonth()->subMonths($i);
            $endDate = $startDate->copy()->endOfMonth();

            $newUsers = User::whereBetween('created_at', [$startDate, $endDate])->count();

            $retention[] = [
                'month' => $startDate->format('M Y'),
                'new_users' => $newUsers,
            ];
        }

        return $retention;
    }

    /**
     * Calculate average success rate
     */
    private static function calculateAverageSuccessRate()
    {
        $total = AdminActivityLog::where('created_at', '>=', now()->subDays(30))->count();
        $successful = AdminActivityLog::where('created_at', '>=', now()->subDays(30))
            ->where('status', 'success')->count();

        return $total > 0 ? round(($successful / $total) * 100, 2) : 0;
    }

    /**
     * Clear analytics cache
     */
    public static function clearCache()
    {
        Cache::forget('dashboard_analytics');
    }

    /**
     * Export analytics to array
     */
    public static function export()
    {
        return static::getDashboardAnalytics();
    }
}

