<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\UserPoints;
use App\Models\PointTransaction;
use App\Models\PointReward;
use App\Models\PointRedemption;
use App\Models\Referral;
use App\Models\ReferralEarning;
use App\Models\PointSetting;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class PointsManagementController extends Controller
{
    /**
     * لوحة تحكم النقاط الرئيسية
     */
    public function dashboard()
    {
        try {
            // إحصائيات عامة
            $totalUsers = User::where('user_type', 'passenger')->count();
            $totalPoints = UserPoints::sum('points');
            $availablePoints = UserPoints::sum('available_points');
            $usedPoints = UserPoints::sum('used_points');
            
            // إحصائيات الإحالات
            $totalReferrals = Referral::count();
            $completedReferrals = Referral::where('status', 'completed')->count();
            $pendingReferrals = Referral::where('status', 'pending')->count();
            
            // إحصائيات الأرباح المالية
            $totalEarnings = ReferralEarning::sum('earnings');
            $paidEarnings = ReferralEarning::where('status', 'paid')->sum('earnings');
            $pendingEarnings = ReferralEarning::where('status', 'pending')->sum('earnings');
            
            // إحصائيات المكافآت
            $totalRewards = PointReward::count();
            $activeRewards = PointReward::where('is_active', true)->count();
            $totalRedemptions = PointRedemption::count();
            $pendingRedemptions = PointRedemption::where('status', 'pending')->count();
            
            // إحصائيات المعاملات (آخر 30 يوم)
            $recentTransactions = PointTransaction::where('created_at', '>=', Carbon::now()->subDays(30))
                ->count();
            
            $earnedPoints = PointTransaction::where('type', 'earned')
                ->where('created_at', '>=', Carbon::now()->subDays(30))
                ->sum('points');
                
            $usedPointsRecent = PointTransaction::where('type', 'used')
                ->where('created_at', '>=', Carbon::now()->subDays(30))
                ->sum('points');
            
            // أفضل المستخدمين (أكثر نقاط)
            $topUsers = UserPoints::with('user')
                ->orderBy('points', 'desc')
                ->limit(10)
                ->get();
            
            // أكثر الإحالات نجاحاً
            $topReferrers = Referral::with('referrer')
                ->where('status', 'completed')
                ->select('referrer_id', DB::raw('count(*) as total_referrals'), DB::raw('sum(points_earned) as total_points'))
                ->groupBy('referrer_id')
                ->orderBy('total_referrals', 'desc')
                ->limit(10)
                ->get();
            
            // المكافآت الأكثر طلباً
            $popularRewards = PointRedemption::with('reward')
                ->select('reward_id', DB::raw('count(*) as redemption_count'))
                ->groupBy('reward_id')
                ->orderBy('redemption_count', 'desc')
                ->limit(5)
                ->get();
            
            // معاملات حديثة
            $recentTransactionsList = PointTransaction::with('user')
                ->latest()
                ->limit(20)
                ->get();
            
            // طلبات استرداد حديثة
            $recentRedemptions = PointRedemption::with(['user', 'reward'])
                ->latest()
                ->limit(10)
                ->get();
            
            return view('admin.points.dashboard', compact(
                'totalUsers', 'totalPoints', 'availablePoints', 'usedPoints',
                'totalReferrals', 'completedReferrals', 'pendingReferrals',
                'totalEarnings', 'paidEarnings', 'pendingEarnings',
                'totalRewards', 'activeRewards', 'totalRedemptions', 'pendingRedemptions',
                'recentTransactions', 'earnedPoints', 'usedPointsRecent',
                'topUsers', 'topReferrers', 'popularRewards',
                'recentTransactionsList', 'recentRedemptions'
            ));
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في تحميل لوحة النقاط: ' . $e->getMessage());
        }
    }
    
    /**
     * إدارة النقاط
     */
    public function pointsManagement()
    {
        $users = User::where('user_type', 'passenger')
            ->with('points')
            ->paginate(20);
            
        return view('admin.points.management', compact('users'));
    }
    
    /**
     * إضافة/خصم نقاط
     */
    public function adjustPoints(Request $request)
    {
        $request->validate([
            'user_id' => 'required|exists:users,id',
            'points' => 'required|integer',
            'type' => 'required|in:add,subtract',
            'description' => 'required|string|max:255',
        ]);
        
        try {
            $user = User::findOrFail($request->user_id);
            $points = abs($request->points);
            
            if ($request->type === 'subtract') {
                $points = -$points;
            }
            
            $user->addPoints($points, $request->description, 'admin_adjustment', [
                'admin_id' => auth()->id(),
                'adjustment_type' => $request->type,
            ]);
            
            return back()->with('success', 'تم تعديل النقاط بنجاح');
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في تعديل النقاط: ' . $e->getMessage());
        }
    }
    
    /**
     * إدارة المكافآت
     */
    public function rewardsManagement()
    {
        $rewards = PointReward::latest()->paginate(20);
        return view('admin.points.rewards', compact('rewards'));
    }
    
    /**
     * إنشاء/تعديل مكافأة
     */
    public function saveReward(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'name_ar' => 'required|string|max:255',
            'description' => 'nullable|string',
            'description_ar' => 'nullable|string',
            'type' => 'required|in:discount,cash,free_service,product',
            'points_required' => 'required|integer|min:1',
            'value' => 'nullable|numeric|min:0',
            'currency' => 'required|string|max:3',
            'is_active' => 'boolean',
            'max_redemptions' => 'nullable|integer|min:1',
            'valid_from' => 'nullable|date',
            'valid_until' => 'nullable|date|after:valid_from',
        ]);
        
        try {
            $data = $request->all();
            $data['is_active'] = $request->has('is_active');
            
            if ($request->has('id')) {
                $reward = PointReward::findOrFail($request->id);
                $reward->update($data);
                $message = 'تم تحديث المكافأة بنجاح';
            } else {
                PointReward::create($data);
                $message = 'تم إنشاء المكافأة بنجاح';
            }
            
            return back()->with('success', $message);
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في حفظ المكافأة: ' . $e->getMessage());
        }
    }
    
    /**
     * إدارة طلبات الاسترداد
     */
    public function redemptionsManagement()
    {
        $redemptions = PointRedemption::with(['user', 'reward'])
            ->latest()
            ->paginate(20);
            
        return view('admin.points.redemptions', compact('redemptions'));
    }
    
    /**
     * معالجة طلب استرداد
     */
    public function processRedemption(Request $request)
    {
        $request->validate([
            'redemption_id' => 'required|exists:point_redemptions,id',
            'action' => 'required|in:approve,reject',
            'notes' => 'nullable|string|max:500',
        ]);
        
        try {
            $redemption = PointRedemption::findOrFail($request->redemption_id);
            
            if ($request->action === 'approve') {
                $redemption->approve();
                $message = 'تم الموافقة على طلب الاسترداد';
            } else {
                $redemption->update([
                    'status' => 'rejected',
                    'notes' => $request->notes,
                ]);
                
                // إرجاع النقاط للمستخدم
                $redemption->user->addPoints(
                    $redemption->points_used,
                    'استرداد مرفوض: ' . $redemption->reward->name_ar,
                    'refund',
                    ['redemption_id' => $redemption->id]
                );
                
                $message = 'تم رفض طلب الاسترداد وإرجاع النقاط';
            }
            
            return back()->with('success', $message);
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في معالجة الطلب: ' . $e->getMessage());
        }
    }
    
    /**
     * إدارة الإحالات
     */
    public function referralsManagement()
    {
        $referrals = Referral::with(['referrer', 'referred', 'earnings'])
            ->latest()
            ->paginate(20);
        
        // إحصائيات الأرباح
        $earningsStats = [
            'total_earnings' => ReferralEarning::sum('earnings'),
            'pending_earnings' => ReferralEarning::where('status', 'pending')->sum('earnings'),
            'approved_earnings' => ReferralEarning::where('status', 'approved')->sum('earnings'),
            'paid_earnings' => ReferralEarning::where('status', 'paid')->sum('earnings'),
            'today_earnings' => ReferralEarning::whereDate('created_at', today())->sum('earnings'),
            'month_earnings' => ReferralEarning::whereMonth('created_at', now()->month)
                ->whereYear('created_at', now()->year)
                ->sum('earnings'),
        ];
            
        return view('admin.points.referrals', compact('referrals', 'earningsStats'));
    }
    
    /**
     * إدارة الأرباح المالية من الإحالات
     */
    public function earningsManagement(Request $request)
    {
        $query = ReferralEarning::with(['referrer', 'referred', 'referral'])
            ->latest();
        
        // فلتر البحث بحالة الربح
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        
        // فلتر البحث بنوع الطلب
        if ($request->filled('order_type')) {
            $query->where('order_type', $request->order_type);
        }
        
        // فلتر البحث بالمستخدم (من دعا)
        if ($request->filled('referrer')) {
            $query->whereHas('referrer', function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->referrer . '%')
                  ->orWhere('phone', 'like', '%' . $request->referrer . '%');
            });
        }
        
        // فلتر البحث بنطاق التاريخ
        if ($request->filled('start_date')) {
            $query->whereDate('created_at', '>=', $request->start_date);
        }
        
        if ($request->filled('end_date')) {
            $query->whereDate('created_at', '<=', $request->end_date);
        }
        
        // فلتر البحث بالتاريخ (للتوافق مع الإصدار القديم)
        if ($request->filled('date') && !$request->filled('start_date') && !$request->filled('end_date')) {
            $query->whereDate('created_at', $request->date);
        }
        
        // تصدير Excel
        if ($request->has('export') && $request->export == 'excel') {
            $earnings = $query->get();
            return $this->exportEarningsToExcel($earnings);
        }
        
        $earnings = $query->paginate(20);
        
        // إحصائيات الأرباح
        $stats = [
            'total_earnings' => ReferralEarning::sum('earnings'),
            'pending_earnings' => ReferralEarning::where('status', 'pending')->sum('earnings'),
            'approved_earnings' => ReferralEarning::where('status', 'approved')->sum('earnings'),
            'paid_earnings' => ReferralEarning::where('status', 'paid')->sum('earnings'),
            'cancelled_earnings' => ReferralEarning::where('status', 'cancelled')->sum('earnings'),
            'today_earnings' => ReferralEarning::whereDate('created_at', today())->sum('earnings'),
            'month_earnings' => ReferralEarning::whereMonth('created_at', now()->month)
                ->whereYear('created_at', now()->year)
                ->sum('earnings'),
            'total_orders' => ReferralEarning::count(),
            'earnings_by_type' => [
                'food' => ReferralEarning::where('order_type', 'food')->sum('earnings'),
                'gas' => ReferralEarning::where('order_type', 'gas')->sum('earnings'),
                'taxi' => ReferralEarning::where('order_type', 'taxi')->sum('earnings'),
            ],
        ];
        
        return view('admin.points.earnings', compact('earnings', 'stats'));
    }
    
    /**
     * الموافقة على ربح
     */
    public function approveEarning(Request $request, $id)
    {
        try {
            $earning = ReferralEarning::findOrFail($id);
            $earning->approve();
            
            return back()->with('success', 'تم الموافقة على الربح بنجاح');
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في الموافقة: ' . $e->getMessage());
        }
    }
    
    /**
     * دفع الربح للمحفظة
     */
    public function payEarning(Request $request, $id)
    {
        try {
            $earning = ReferralEarning::findOrFail($id);
            
            if ($earning->status !== 'approved') {
                return back()->with('error', 'يجب الموافقة على الربح أولاً');
            }
            
            $earning->markAsPaid();
            
            return back()->with('success', 'تم دفع الربح للمحفظة بنجاح');
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في الدفع: ' . $e->getMessage());
        }
    }
    
    /**
     * إلغاء ربح
     */
    public function cancelEarning(Request $request, $id)
    {
        try {
            $earning = ReferralEarning::findOrFail($id);
            
            if ($earning->status == 'paid') {
                return response()->json([
                    'success' => false,
                    'message' => 'لا يمكن إلغاء ربح تم دفعه بالفعل'
                ], 400);
            }
            
            $earning->update([
                'status' => 'cancelled',
                'notes' => $request->notes ?? 'تم الإلغاء من قبل المدير'
            ]);
            
            return response()->json([
                'success' => true,
                'message' => 'تم إلغاء الربح بنجاح'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'خطأ في الإلغاء: ' . $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * عرض تفاصيل الربح
     */
    public function earningDetails($id)
    {
        try {
            $earning = ReferralEarning::with(['referrer', 'referred', 'referral'])->findOrFail($id);
            
            $html = view('admin.points.earning_details', compact('earning'))->render();
            
            return response()->json([
                'success' => true,
                'html' => $html
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'خطأ في تحميل التفاصيل: ' . $e->getMessage()
            ], 500);
        }
    }
    
    /**
     * تصدير الأرباح إلى Excel
     */
    private function exportEarningsToExcel($earnings)
    {
        $filename = 'referral_earnings_' . date('Y-m-d_His') . '.csv';
        
        $headers = [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ];
        
        $callback = function() use ($earnings) {
            $file = fopen('php://output', 'w');
            
            // BOM for UTF-8
            fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
            
            // Headers
            fputcsv($file, [
                'ID',
                'من دعا',
                'هاتف المدعو',
                'من تم دعوته',
                'هاتف المدعو إليه',
                'نوع الطلب',
                'رقم الطلبية',
                'قيمة الطلبية',
                'نسبة الربح',
                'الربح',
                'الحالة',
                'تاريخ الإنشاء',
                'تاريخ الدفع'
            ]);
            
            // Data
            foreach ($earnings as $earning) {
                fputcsv($file, [
                    $earning->id,
                    $earning->referrer->name ?? '',
                    $earning->referrer->phone ?? '',
                    $earning->referred->name ?? '',
                    $earning->referred->phone ?? '',
                    $earning->order_type,
                    $earning->order_number,
                    $earning->order_total,
                    ($earning->profit_percentage * 100) . '%',
                    $earning->earnings,
                    $this->getStatusLabel($earning->status),
                    $earning->created_at->format('Y-m-d H:i:s'),
                    $earning->paid_at ? $earning->paid_at->format('Y-m-d H:i:s') : ''
                ]);
            }
            
            fclose($file);
        };
        
        return response()->stream($callback, 200, $headers);
    }
    
    /**
     * الحصول على نص الحالة بالعربية
     */
    private function getStatusLabel($status)
    {
        $labels = [
            'pending' => 'معلق',
            'approved' => 'موافق',
            'paid' => 'مدفوع',
            'cancelled' => 'ملغي'
        ];
        
        return $labels[$status] ?? $status;
    }
    
    /**
     * إدارة المعاملات
     */
    public function transactionsManagement()
    {
        $transactions = PointTransaction::with('user')
            ->latest()
            ->paginate(50);
            
        return view('admin.points.transactions', compact('transactions'));
    }
    
    /**
     * إعدادات النقاط
     */
    public function settings()
    {
        $settings = PointSetting::all()->keyBy('key');
        return view('admin.points.settings', compact('settings'));
    }
    
    /**
     * حفظ إعدادات النقاط
     */
    public function saveSettings(Request $request)
    {
        $request->validate([
            'referral_points' => 'required|integer|min:1',
            'welcome_points' => 'required|integer|min:0',
            'points_to_money_rate' => 'required|integer|min:1',
            'max_referral_points_per_month' => 'required|integer|min:1',
        ]);
        
        try {
            foreach ($request->all() as $key => $value) {
                if (in_array($key, ['referral_points', 'welcome_points', 'points_to_money_rate', 'max_referral_points_per_month'])) {
                    PointSetting::set($key, $value);
                }
            }
            
            return back()->with('success', 'تم حفظ الإعدادات بنجاح');
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في حفظ الإعدادات: ' . $e->getMessage());
        }
    }
    
    /**
     * تقارير النقاط
     */
    public function reports(Request $request)
    {
        $startDate = $request->get('start_date', Carbon::now()->subMonth()->format('Y-m-d'));
        $endDate = $request->get('end_date', Carbon::now()->format('Y-m-d'));
        
        // إحصائيات الفترة
        $periodStats = [
            'total_earned' => PointTransaction::where('type', 'earned')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->sum('points'),
            'total_used' => abs(PointTransaction::where('type', 'used')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->sum('points')),
            'total_referrals' => Referral::whereBetween('created_at', [$startDate, $endDate])
                ->count(),
            'completed_referrals' => Referral::where('status', 'completed')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->count(),
            'total_redemptions' => PointRedemption::whereBetween('created_at', [$startDate, $endDate])
                ->count(),
        ];
        
        // معاملات يومية
        $dailyTransactions = PointTransaction::select(
                DB::raw('DATE(created_at) as date'),
                DB::raw('SUM(CASE WHEN type = "earned" THEN points ELSE 0 END) as earned'),
                DB::raw('SUM(CASE WHEN type = "used" THEN ABS(points) ELSE 0 END) as used')
            )
            ->whereBetween('created_at', [$startDate, $endDate])
            ->groupBy('date')
            ->orderBy('date')
            ->get();
        
        return view('admin.points.reports', compact(
            'startDate', 'endDate', 'periodStats', 'dailyTransactions'
        ));
    }
    
    /**
     * تقرير مفصل لمستخدم معين
     */
    public function userReport(Request $request, $userId)
    {
        try {
            $user = User::with(['referrals.referred', 'referralEarnings.referred'])->findOrFail($userId);
            
            // تحديد الفترة الزمنية
            $period = $request->get('period', 'month'); // week, month, year
            $startDate = $request->get('start_date');
            $endDate = $request->get('end_date');
            
            if (!$startDate || !$endDate) {
                if ($period == 'week') {
                    $startDate = Carbon::now()->startOfWeek()->format('Y-m-d');
                    $endDate = Carbon::now()->endOfWeek()->format('Y-m-d');
                } elseif ($period == 'month') {
                    $startDate = Carbon::now()->startOfMonth()->format('Y-m-d');
                    $endDate = Carbon::now()->endOfMonth()->format('Y-m-d');
                } else {
                    $startDate = Carbon::now()->startOfYear()->format('Y-m-d');
                    $endDate = Carbon::now()->endOfYear()->format('Y-m-d');
                }
            }
            
            // إحصائيات الأرباح في الفترة
            $earningsInPeriod = $user->referralEarnings()
                ->whereBetween('created_at', [$startDate, $endDate])
                ->get();
            
            $totalEarnings = $earningsInPeriod->sum('earnings');
            $pendingEarnings = $earningsInPeriod->where('status', 'pending')->sum('earnings');
            $approvedEarnings = $earningsInPeriod->where('status', 'approved')->sum('earnings');
            $paidEarnings = $earningsInPeriod->where('status', 'paid')->sum('earnings');
            
            // الأشخاص الذين دعاهم في هذه الفترة
            $referralsInPeriod = $user->referrals()
                ->whereBetween('created_at', [$startDate, $endDate])
                ->with('referred')
                ->get();
            
            // إحصائيات النمو
            $previousPeriodStart = Carbon::parse($startDate)->subDays(Carbon::parse($endDate)->diffInDays(Carbon::parse($startDate)))->format('Y-m-d');
            $previousPeriodEnd = Carbon::parse($startDate)->subDay()->format('Y-m-d');
            
            $previousEarnings = $user->referralEarnings()
                ->whereBetween('created_at', [$previousPeriodStart, $previousPeriodEnd])
                ->sum('earnings');
            
            $previousReferrals = $user->referrals()
                ->whereBetween('created_at', [$previousPeriodStart, $previousPeriodEnd])
                ->count();
            
            $earningsGrowth = $previousEarnings > 0 
                ? (($totalEarnings - $previousEarnings) / $previousEarnings) * 100 
                : ($totalEarnings > 0 ? 100 : 0);
            
            $referralsGrowth = $previousReferrals > 0 
                ? (($referralsInPeriod->count() - $previousReferrals) / $previousReferrals) * 100 
                : ($referralsInPeriod->count() > 0 ? 100 : 0);
            
            // توزيع الأرباح حسب نوع الطلب
            $earningsByType = [
                'food' => $earningsInPeriod->where('order_type', 'food')->sum('earnings'),
                'gas' => $earningsInPeriod->where('order_type', 'gas')->sum('earnings'),
                'taxi' => $earningsInPeriod->where('order_type', 'taxi')->sum('earnings'),
            ];
            
            // الأرباح اليومية في الفترة
            $dailyEarnings = $user->referralEarnings()
                ->whereBetween('created_at', [$startDate, $endDate])
                ->select(
                    DB::raw('DATE(created_at) as date'),
                    DB::raw('SUM(earnings) as total_earnings'),
                    DB::raw('COUNT(*) as orders_count')
                )
                ->groupBy('date')
                ->orderBy('date')
                ->get();
            
            // أفضل الأشخاص المدعوين (حسب الأرباح)
            $topReferred = $user->referralEarnings()
                ->whereBetween('created_at', [$startDate, $endDate])
                ->with('referred')
                ->select('referred_id', DB::raw('SUM(earnings) as total_earnings'), DB::raw('COUNT(*) as orders_count'))
                ->groupBy('referred_id')
                ->orderBy('total_earnings', 'desc')
                ->limit(10)
                ->get();
            
            // إحصائيات عامة
            $totalReferrals = $user->referrals()->count();
            $totalEarningsAllTime = $user->referralEarnings()->sum('earnings');
            $totalPaidEarnings = $user->referralEarnings()->where('status', 'paid')->sum('earnings');
            
            return view('admin.points.user_report', compact(
                'user',
                'period',
                'startDate',
                'endDate',
                'totalEarnings',
                'pendingEarnings',
                'approvedEarnings',
                'paidEarnings',
                'referralsInPeriod',
                'earningsGrowth',
                'referralsGrowth',
                'earningsByType',
                'dailyEarnings',
                'topReferred',
                'totalReferrals',
                'totalEarningsAllTime',
                'totalPaidEarnings',
                'earningsInPeriod'
            ));
            
        } catch (\Exception $e) {
            return back()->with('error', 'خطأ في تحميل التقرير: ' . $e->getMessage());
        }
    }
}
