<?php

namespace App\Services;

use App\Models\User;
use App\Models\Order;
use App\Models\Product;
use App\Models\Commission;
use App\Models\Transaction;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

/**
 * Service Dashboard - Statistiques et KPIs
 */
class DashboardService
{
    /**
     * Obtenir les statistiques globales pour l'admin
     */
    public function getAdminStats(): array
    {
        return Cache::remember('admin_dashboard_stats', 300, function () {
            $now = Carbon::now();
            $startOfMonth = $now->copy()->startOfMonth();
            $lastMonth = $now->copy()->subMonth();

            return [
                'users' => $this->getUsersStats($startOfMonth, $lastMonth),
                'orders' => $this->getOrdersStats($startOfMonth, $lastMonth),
                'revenue' => $this->getRevenueStats($startOfMonth, $lastMonth),
                'commissions' => $this->getCommissionsStats($startOfMonth, $lastMonth),
            ];
        });
    }

    /**
     * Statistiques utilisateurs
     */
    protected function getUsersStats(Carbon $startOfMonth, Carbon $lastMonth): array
    {
        $currentMonthUsers = User::where('created_at', '>=', $startOfMonth)->count();
        $lastMonthUsers = User::whereBetween('created_at', [
            $lastMonth->copy()->startOfMonth(),
            $lastMonth->copy()->endOfMonth()
        ])->count();

        $change = $lastMonthUsers > 0 
            ? round((($currentMonthUsers - $lastMonthUsers) / $lastMonthUsers) * 100, 1)
            : 100;

        return [
            'total' => User::count(),
            'this_month' => $currentMonthUsers,
            'change' => $change,
            'active' => User::where('last_activity_at', '>=', now()->subDays(7))->count(),
            'sellers' => User::where('is_seller', true)->count(),
        ];
    }

    /**
     * Statistiques commandes
     */
    protected function getOrdersStats(Carbon $startOfMonth, Carbon $lastMonth): array
    {
        $currentMonthOrders = Order::where('created_at', '>=', $startOfMonth)->count();
        $lastMonthOrders = Order::whereBetween('created_at', [
            $lastMonth->copy()->startOfMonth(),
            $lastMonth->copy()->endOfMonth()
        ])->count();

        $change = $lastMonthOrders > 0 
            ? round((($currentMonthOrders - $lastMonthOrders) / $lastMonthOrders) * 100, 1)
            : 100;

        return [
            'total' => Order::count(),
            'this_month' => $currentMonthOrders,
            'change' => $change,
            'pending' => Order::where('status', 'pending')->count(),
            'completed' => Order::where('status', 'completed')->count(),
        ];
    }

    /**
     * Statistiques revenus
     */
    protected function getRevenueStats(Carbon $startOfMonth, Carbon $lastMonth): array
    {
        $currentMonthRevenue = Order::where('created_at', '>=', $startOfMonth)
            ->where('status', 'completed')
            ->sum('total');

        $lastMonthRevenue = Order::whereBetween('created_at', [
            $lastMonth->copy()->startOfMonth(),
            $lastMonth->copy()->endOfMonth()
        ])->where('status', 'completed')->sum('total');

        $change = $lastMonthRevenue > 0 
            ? round((($currentMonthRevenue - $lastMonthRevenue) / $lastMonthRevenue) * 100, 1)
            : 100;

        return [
            'total' => Order::where('status', 'completed')->sum('total'),
            'this_month' => $currentMonthRevenue,
            'change' => $change,
            'average_order' => Order::where('status', 'completed')->avg('total') ?? 0,
        ];
    }

    /**
     * Statistiques commissions
     */
    protected function getCommissionsStats(Carbon $startOfMonth, Carbon $lastMonth): array
    {
        $currentMonthCommissions = Commission::where('created_at', '>=', $startOfMonth)->sum('amount');
        $lastMonthCommissions = Commission::whereBetween('created_at', [
            $lastMonth->copy()->startOfMonth(),
            $lastMonth->copy()->endOfMonth()
        ])->sum('amount');

        $change = $lastMonthCommissions > 0 
            ? round((($currentMonthCommissions - $lastMonthCommissions) / $lastMonthCommissions) * 100, 1)
            : 100;

        return [
            'total' => Commission::sum('amount'),
            'this_month' => $currentMonthCommissions,
            'change' => $change,
            'pending' => Commission::where('status', 'pending')->sum('amount'),
        ];
    }

    /**
     * Données pour le graphique des revenus (12 derniers mois)
     */
    public function getRevenueChartData(): array
    {
        return Cache::remember('revenue_chart_data', 600, function () {
            $data = [];
            $labels = [];

            for ($i = 11; $i >= 0; $i--) {
                $date = Carbon::now()->subMonths($i);
                $labels[] = $date->translatedFormat('M Y');
                
                $revenue = Order::whereYear('created_at', $date->year)
                    ->whereMonth('created_at', $date->month)
                    ->where('status', 'completed')
                    ->sum('total');
                
                $data[] = $revenue;
            }

            return [
                'labels' => $labels,
                'datasets' => [
                    [
                        'label' => 'Revenus (FCFA)',
                        'data' => $data,
                        'borderColor' => '#3b82f6',
                        'backgroundColor' => 'rgba(59, 130, 246, 0.1)',
                        'fill' => true,
                        'tension' => 0.4,
                    ]
                ]
            ];
        });
    }

    /**
     * Données pour le graphique des commandes par statut
     */
    public function getOrdersStatusChartData(): array
    {
        return Cache::remember('orders_status_chart', 300, function () {
            $statuses = Order::select('status', DB::raw('count(*) as count'))
                ->groupBy('status')
                ->pluck('count', 'status')
                ->toArray();

            $statusLabels = [
                'pending' => 'En attente',
                'processing' => 'En cours',
                'shipped' => 'Expédiée',
                'completed' => 'Terminée',
                'cancelled' => 'Annulée',
            ];

            $colors = [
                'pending' => '#fbbf24',
                'processing' => '#3b82f6',
                'shipped' => '#8b5cf6',
                'completed' => '#10b981',
                'cancelled' => '#ef4444',
            ];

            return [
                'labels' => array_map(fn($s) => $statusLabels[$s] ?? $s, array_keys($statuses)),
                'datasets' => [
                    [
                        'data' => array_values($statuses),
                        'backgroundColor' => array_map(fn($s) => $colors[$s] ?? '#6b7280', array_keys($statuses)),
                    ]
                ]
            ];
        });
    }

    /**
     * Top produits vendus
     */
    public function getTopProducts(int $limit = 5): array
    {
        return Cache::remember('top_products', 600, function () use ($limit) {
            // Cette requête dépend de votre structure de tables
            return Product::withCount('orderItems')
                ->withSum('orderItems', 'quantity')
                ->orderByDesc('order_items_sum_quantity')
                ->take($limit)
                ->get()
                ->map(fn($p) => [
                    'name' => $p->name,
                    'image' => $p->image_url ?? null,
                    'value' => $p->order_items_sum_quantity ?? 0,
                    'subtitle' => $p->category->name ?? '',
                ])
                ->toArray();
        });
    }

    /**
     * Top vendeurs
     */
    public function getTopSellers(int $limit = 5): array
    {
        return Cache::remember('top_sellers', 600, function () use ($limit) {
            return User::where('is_seller', true)
                ->withSum(['orders as total_sales' => function ($q) {
                    $q->where('status', 'completed');
                }], 'total')
                ->orderByDesc('total_sales')
                ->take($limit)
                ->get()
                ->map(fn($u) => [
                    'name' => $u->name,
                    'image' => $u->avatar_url ?? null,
                    'value' => $u->total_sales ?? 0,
                    'subtitle' => 'Vendeur',
                ])
                ->toArray();
        });
    }

    /**
     * Activités récentes
     */
    public function getRecentActivities(int $limit = 10): array
    {
        $activities = [];

        // Nouvelles commandes
        $orders = Order::with('user')
            ->latest()
            ->take(5)
            ->get();

        foreach ($orders as $order) {
            $activities[] = [
                'type' => 'order',
                'user' => $order->user->name ?? 'Utilisateur',
                'description' => 'a passé une commande',
                'amount' => $order->total,
                'time' => $order->created_at->diffForHumans(),
                'timestamp' => $order->created_at,
            ];
        }

        // Nouveaux utilisateurs
        $users = User::latest()
            ->take(5)
            ->get();

        foreach ($users as $user) {
            $activities[] = [
                'type' => 'user',
                'user' => $user->name,
                'description' => 's\'est inscrit',
                'time' => $user->created_at->diffForHumans(),
                'timestamp' => $user->created_at,
            ];
        }

        // Commissions
        $commissions = Commission::with('user')
            ->latest()
            ->take(5)
            ->get();

        foreach ($commissions as $commission) {
            $activities[] = [
                'type' => 'commission',
                'user' => $commission->user->name ?? 'Membre',
                'description' => 'a reçu une commission',
                'amount' => $commission->amount,
                'time' => $commission->created_at->diffForHumans(),
                'timestamp' => $commission->created_at,
            ];
        }

        // Trier par timestamp et limiter
        usort($activities, fn($a, $b) => $b['timestamp'] <=> $a['timestamp']);

        return array_slice($activities, 0, $limit);
    }

    /**
     * Statistiques du membre connecté
     */
    public function getMemberStats(User $user): array
    {
        $cacheKey = "member_stats_{$user->id}";

        return Cache::remember($cacheKey, 300, function () use ($user) {
            $startOfMonth = Carbon::now()->startOfMonth();

            return [
                'wallet_balance' => $user->wallet_balance ?? 0,
                'total_commissions' => Commission::where('user_id', $user->id)->sum('amount'),
                'this_month_commissions' => Commission::where('user_id', $user->id)
                    ->where('created_at', '>=', $startOfMonth)
                    ->sum('amount'),
                'referrals_count' => User::where('referrer_id', $user->id)->count(),
                'this_month_referrals' => User::where('referrer_id', $user->id)
                    ->where('created_at', '>=', $startOfMonth)
                    ->count(),
                'orders_count' => Order::where('user_id', $user->id)->count(),
                'amm_status' => $this->getAmmStatus($user),
                'rank' => $user->rank ?? 'Bronze',
            ];
        });
    }

    /**
     * Obtenir le statut AMM de l'utilisateur
     */
    protected function getAmmStatus(User $user): array
    {
        $startOfMonth = Carbon::now()->startOfMonth();
        $endOfMonth = Carbon::now()->endOfMonth();

        $ammPurchase = Order::where('user_id', $user->id)
            ->where('is_amm', true)
            ->whereBetween('created_at', [$startOfMonth, $endOfMonth])
            ->exists();

        return [
            'completed' => $ammPurchase,
            'deadline' => $endOfMonth->format('d/m/Y'),
            'days_remaining' => Carbon::now()->diffInDays($endOfMonth),
        ];
    }

    /**
     * Invalider le cache dashboard
     */
    public function clearCache(?int $userId = null): void
    {
        Cache::forget('admin_dashboard_stats');
        Cache::forget('revenue_chart_data');
        Cache::forget('orders_status_chart');
        Cache::forget('top_products');
        Cache::forget('top_sellers');

        if ($userId) {
            Cache::forget("member_stats_{$userId}");
        }
    }
}
