<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Payment;
use App\Models\Trip;
use App\Models\FoodOrder;
use App\Models\GasOrder;
use App\Models\AppSetting;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Schema;

class PaymentController extends Controller
{
    /**
     * إنشاء دفعة جديدة
     */
    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'paymentable_type' => 'required|in:trip,food_order,gas_order',
            'paymentable_id' => 'required|integer',
            'amount' => 'required|numeric|min:0.01',
            'payment_method' => 'required|in:cash,card,online,wallet',
            'transaction_id' => 'nullable|string|max:255',
            'notes' => 'nullable|string|max:1000',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'بيانات غير صحيحة',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            DB::beginTransaction();

            $user = Auth::user();
            $paymentable = $this->getPaymentable($request->paymentable_type, $request->paymentable_id);

            if (!$paymentable) {
                return response()->json([
                    'success' => false,
                    'message' => 'العنصر المطلوب الدفع له غير موجود'
                ], 404);
            }

            // التحقق من أن المستخدم يملك العنصر
            if (!$this->userOwnsPaymentable($user, $paymentable, $request->paymentable_type)) {
                return response()->json([
                    'success' => false,
                    'message' => 'غير مصرح لك بالدفع لهذا العنصر'
                ], 403);
            }

            // التحقق من أن العنصر لم يتم الدفع له مسبقاً
            if ($this->isAlreadyPaid($paymentable, $request->paymentable_type)) {
                return response()->json([
                    'success' => false,
                    'message' => 'تم الدفع لهذا العنصر مسبقاً'
                ], 400);
            }

            // حساب رسوم الاشتراك
            $subscriptionFee = $this->calculateSubscriptionFee($request->paymentable_type, $request->amount);
            $totalAmount = $request->amount + $subscriptionFee;

            // إنشاء الدفعة
            $payment = Payment::create([
                'user_id' => $user->id,
                'paymentable_type' => 'App\\Models\\' . $this->getModelClass($request->paymentable_type),
                'paymentable_id' => $paymentable->id,
                'amount' => $request->amount,
                'subscription_fee' => $subscriptionFee,
                'total_amount' => $totalAmount,
                'payment_method' => $request->payment_method,
                'transaction_id' => $request->transaction_id,
                'status' => 'pending',
                'notes' => $request->notes,
            ]);

            // تحديث حالة العنصر
            $this->updatePaymentableStatus($paymentable, $request->paymentable_type, 'paid');

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'تم إنشاء الدفعة بنجاح',
                'data' => [
                    'payment' => $payment->load('paymentable'),
                    'subscription_fee' => $subscriptionFee,
                    'total_amount' => $totalAmount
                ]
            ], 201);

        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء إنشاء الدفعة',
                'error' => config('app.debug') ? $e->getMessage() : 'خطأ داخلي'
            ], 500);
        }
    }

    /**
     * تأكيد الدفعة
     */
    public function confirm(Payment $payment): JsonResponse
    {
        if ($payment->user_id !== Auth::id()) {
            return response()->json([
                'success' => false,
                'message' => 'غير مصرح لك بتأكيد هذه الدفعة'
            ], 403);
        }

        if ($payment->status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'لا يمكن تأكيد الدفعة في هذه المرحلة'
            ], 400);
        }

        try {
            $payment->markAsCompleted();

            return response()->json([
                'success' => true,
                'message' => 'تم تأكيد الدفعة بنجاح',
                'data' => $payment->load('paymentable')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء تأكيد الدفعة',
                'error' => config('app.debug') ? $e->getMessage() : 'خطأ داخلي'
            ], 500);
        }
    }

    /**
     * إلغاء الدفعة
     */
    public function cancel(Payment $payment): JsonResponse
    {
        if ($payment->user_id !== Auth::id()) {
            return response()->json([
                'success' => false,
                'message' => 'غير مصرح لك بإلغاء هذه الدفعة'
            ], 403);
        }

        if (!$payment->canBeCancelled()) {
            return response()->json([
                'success' => false,
                'message' => 'لا يمكن إلغاء الدفعة في هذه المرحلة'
            ], 400);
        }

        try {
            DB::beginTransaction();

            $payment->markAsCancelled();

            // إعادة حالة العنصر
            $this->updatePaymentableStatus($payment->paymentable, $this->getPaymentableType($payment), 'pending');

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'تم إلغاء الدفعة بنجاح',
                'data' => $payment->load('paymentable')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء إلغاء الدفعة',
                'error' => config('app.debug') ? $e->getMessage() : 'خطأ داخلي'
            ], 500);
        }
    }

    /**
     * عرض سجل المدفوعات للمستخدم
     */
    public function myPayments(Request $request): JsonResponse
    {
        $user = Auth::user();

        $query = $user->userPayments()->with('paymentable');

        // فلترة حسب الحالة
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        // فلترة حسب نوع الخدمة
        if ($request->has('service_type')) {
            $query->where('paymentable_type', 'App\\Models\\' . $this->getModelClass($request->service_type));
        }

        // فلترة حسب التاريخ
        if ($request->has('date_from')) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }

        if ($request->has('date_to')) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        $payments = $query->orderBy('created_at', 'desc')->paginate($request->get('per_page', 20));

        return response()->json([
            'success' => true,
            'data' => $payments,
            'message' => 'تم جلب سجل المدفوعات بنجاح'
        ]);
    }

    /**
     * عرض تفاصيل دفعة معينة
     */
    public function show(Payment $payment): JsonResponse
    {
        if ($payment->user_id !== Auth::id()) {
            return response()->json([
                'success' => false,
                'message' => 'غير مصرح لك بعرض هذه الدفعة'
            ], 403);
        }

        $payment->load('paymentable');

        return response()->json([
            'success' => true,
            'data' => $payment,
            'message' => 'تم جلب تفاصيل الدفعة بنجاح'
        ]);
    }

    /**
     * استرداد المال
     */
    public function refund(Request $request, Payment $payment): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'reason' => 'required|string|max:500',
            'amount' => 'nullable|numeric|min:0.01|max:' . $payment->total_amount,
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'بيانات غير صحيحة',
                'errors' => $validator->errors()
            ], 422);
        }

        if ($payment->user_id !== Auth::id()) {
            return response()->json([
                'success' => false,
                'message' => 'غير مصرح لك بطلب استرداد هذه الدفعة'
            ], 403);
        }

        if (!$payment->canBeRefunded()) {
            return response()->json([
                'success' => false,
                'message' => 'لا يمكن طلب استرداد الدفعة إلا إذا كانت مكتملة'
            ], 400);
        }

        try {
            $refundAmount = $request->amount ?? $payment->total_amount;
            $payment->requestRefund($request->reason, $refundAmount);

            return response()->json([
                'success' => true,
                'message' => 'تم طلب استرداد المال بنجاح',
                'data' => [
                    'payment_id' => $payment->id,
                    'refund_amount' => $refundAmount,
                    'refund_reason' => $request->reason
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء طلب الاسترداد',
                'error' => config('app.debug') ? $e->getMessage() : 'خطأ داخلي'
            ], 500);
        }
    }

    /**
     * الحصول على العنصر المطلوب الدفع له
     */
    private function getPaymentable(string $type, int $id)
    {
        switch ($type) {
            case 'trip':
                return Trip::find($id);
            case 'food_order':
                return FoodOrder::find($id);
            case 'gas_order':
                return GasOrder::find($id);
            default:
                return null;
        }
    }

    /**
     * الحصول على اسم الكلاس
     */
    private function getModelClass(string $type): string
    {
        $classes = [
            'trip' => 'Trip',
            'food_order' => 'FoodOrder',
            'gas_order' => 'GasOrder'
        ];

        return $classes[$type] ?? $type;
    }

    /**
     * التحقق من أن المستخدم يملك العنصر
     */
    private function userOwnsPaymentable($user, $paymentable, string $type): bool
    {
        switch ($type) {
            case 'trip':
                return $paymentable->passenger?->id === $user->passenger?->id ||
                       $paymentable->driver?->id === $user->driver?->id;
            case 'food_order':
                return $paymentable->customer_id === $user->id;
            case 'gas_order':
                return $paymentable->customer_id === $user->id;
            default:
                return false;
        }
    }

    /**
     * التحقق من أن العنصر تم الدفع له مسبقاً
     */
    private function isAlreadyPaid($paymentable, string $type): bool
    {
        return Payment::where('paymentable_type', 'App\\Models\\' . $this->getModelClass($type))
            ->where('paymentable_id', $paymentable->id)
            ->where('status', 'completed')
            ->exists();
    }

    /**
     * حساب رسوم الاشتراك
     */
    private function calculateSubscriptionFee(string $type, float $amount): float
    {
        $settings = AppSetting::first();
        if (!$settings) return 0;

        $subscriptionField = $type . '_subscription_';
        $subscriptionType = $subscriptionField . 'type';
        $subscriptionValue = $subscriptionField . 'value';
        $subscriptionEnabled = $subscriptionField . 'enabled';

        if (!$settings->$subscriptionEnabled) return 0;

        if ($settings->$subscriptionType === 'percentage') {
            return ($amount * $settings->$subscriptionValue) / 100;
        } else {
            return $settings->$subscriptionValue;
        }
    }

    /**
     * تحديث حالة العنصر
     */
    private function updatePaymentableStatus($paymentable, string $type, string $status): void
    {
        switch ($type) {
            case 'trip':
                if (Schema::hasColumn('trips', 'payment_status')) {
                    $paymentable->update(['payment_status' => $status]);
                }
                break;
            case 'food_order':
                if (Schema::hasColumn('food_orders', 'payment_status')) {
                    $paymentable->update(['payment_status' => $status]);
                }
                break;
            case 'gas_order':
                if (Schema::hasColumn('gas_orders', 'payment_status')) {
                    $paymentable->update(['payment_status' => $status]);
                }
                break;
        }
    }

    /**
     * الحصول على نوع العنصر
     */
    private function getPaymentableType(Payment $payment): string
    {
        $type = class_basename($payment->paymentable_type);
        return strtolower($type);
    }

    /**
     * إحصائيات المدفوعات
     */
    public function statistics(Request $request): JsonResponse
    {
        $user = Auth::user();

        $query = $user->userPayments()->where('status', 'completed');

        // فلترة حسب التاريخ
        if ($request->has('period')) {
            switch ($request->period) {
                case 'today':
                    $query->whereDate('created_at', today());
                    break;
                case 'week':
                    $query->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]);
                    break;
                case 'month':
                    $query->whereMonth('created_at', now()->month);
                    break;
                case 'year':
                    $query->whereYear('created_at', now()->year);
                    break;
            }
        }

        $totalPaid = $query->sum('total_amount');
        $totalSubscriptionFees = $query->sum('subscription_fee');

        $paymentMethods = $user->userPayments()
            ->where('status', 'completed')
            ->selectRaw('payment_method, COUNT(*) as count, SUM(total_amount) as total')
            ->groupBy('payment_method')
            ->get();

        $serviceTypes = $user->userPayments()
            ->where('status', 'completed')
            ->selectRaw('paymentable_type, COUNT(*) as count, SUM(total_amount) as total')
            ->groupBy('paymentable_type')
            ->get();

        return response()->json([
            'success' => true,
            'data' => [
                'total_paid' => $totalPaid,
                'total_subscription_fees' => $totalSubscriptionFees,
                'payment_methods' => $paymentMethods,
                'service_types' => $serviceTypes,
                'total_payments' => $user->userPayments()->count(),
                'completed_payments' => $user->userPayments()->where('status', 'completed')->count(),
                'pending_payments' => $user->userPayments()->where('status', 'pending')->count(),
                'cancelled_payments' => $user->userPayments()->where('status', 'cancelled')->count(),
                'refund_requested_payments' => $user->userPayments()->where('status', 'refund_requested')->count(),
            ],
            'message' => 'تم جلب إحصائيات المدفوعات بنجاح'
        ]);
    }

    /**
     * تحديث حالة الدفعة (للمشرفين)
     */
    public function updateStatus(Request $request, Payment $payment): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'status' => 'required|in:pending,processing,completed,failed,cancelled,refunded',
            'notes' => 'nullable|string|max:1000',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'بيانات غير صحيحة',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $payment->update([
                'status' => $request->status,
                'notes' => $request->notes ?? $payment->notes,
            ]);

            // تحديث التواريخ حسب الحالة
            switch ($request->status) {
                case 'completed':
                    $payment->update(['completed_at' => now()]);
                    break;
                case 'cancelled':
                    $payment->update(['cancelled_at' => now()]);
                    break;
                case 'refunded':
                    $payment->update(['refund_requested_at' => now()]);
                    break;
            }

            return response()->json([
                'success' => true,
                'message' => 'تم تحديث حالة الدفعة بنجاح',
                'data' => $payment->load('paymentable')
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'حدث خطأ أثناء تحديث حالة الدفعة',
                'error' => config('app.debug') ? $e->getMessage() : 'خطأ داخلي'
            ], 500);
        }
    }

    /**
     * البحث في المدفوعات
     */
    public function search(Request $request): JsonResponse
    {
        $user = Auth::user();

        $query = $user->payments()->with('paymentable');

        // البحث في رقم المعاملة
        if ($request->has('transaction_id')) {
            $query->where('transaction_id', 'like', '%' . $request->transaction_id . '%');
        }

        // البحث في الملاحظات
        if ($request->has('notes')) {
            $query->where('notes', 'like', '%' . $request->notes . '%');
        }

        // البحث في المبلغ
        if ($request->has('amount_min')) {
            $query->where('amount', '>=', $request->amount_min);
        }

        if ($request->has('amount_max')) {
            $query->where('amount', '<=', $request->amount_max);
        }

        $payments = $query->orderBy('created_at', 'desc')->paginate($request->get('per_page', 20));

        return response()->json([
            'success' => true,
            'data' => $payments,
            'message' => 'تم البحث في المدفوعات بنجاح'
        ]);
    }
}
