<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\Bundle;
use App\Models\Cart;
use App\Models\Product;
use App\Models\ProductOrder;
use App\Models\ReserveMeeting;
use App\Models\Ticket;
use App\Models\Webinar;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use mysql_xdevapi\Exception;

class CartManagerController extends Controller
{
    public $cookieKey = 'carts';

    public function getCarts()
    {
        $carts = null;

        if (auth()->check()) {
            $user = auth()->user();

            $carts = $user->carts()
                ->with([
                    'webinar',
                    'bundle',
                    'productOrder' => function ($query) {
                        $query->with(['product']);
                    },
                    'reserveMeeting.meeting.creator',
                ])
                ->get();
        } else {
            $cookieCarts = Cookie::get($this->cookieKey);

            if (!empty($cookieCarts)) {
                $cookieCarts = json_decode($cookieCarts, true);

                if (!empty($cookieCarts) and count($cookieCarts)) {
                    $carts = collect();

                    foreach ($cookieCarts as $cookieCart) {

                        if (!empty($cookieCart['item_name']) and $cookieCart['item_name'] == 'webinar_id') {
                            $webinar = Webinar::where('id', $cookieCart['item_id'])
                                ->where('private', false)
                                ->where('status', 'active')
                                ->first();

                            if (!empty($webinar)) {
                                $ticket = null;

                                if (!empty($cookieCart['ticket_id'])) {
                                    $ticket = Ticket::where('id', $cookieCart['ticket_id'])->first();
                                }

                                $item = new Cart();
                                $item->webinar_id = $webinar->id;
                                $item->webinar = $webinar;
                                $item->ticket = $ticket;

                                $carts->add($item);
                            }
                        } elseif (!empty($cookieCart['item_name']) and $cookieCart['item_name'] == 'bundle_id') {
                            $bundle = Bundle::where('id', $cookieCart['item_id'])
                                ->where('status', 'active')
                                ->first();

                            if (!empty($bundle)) {
                                $ticket = null;

                                if (!empty($cookieCart['ticket_id'])) {
                                    $ticket = Ticket::where('id', $cookieCart['ticket_id'])->first();
                                }

                                $item = new Cart();
                                $item->bundle_id = $bundle->id;
                                $item->bundle = $bundle;
                                $item->ticket = $ticket;

                                $carts->add($item);
                            }
                        } elseif (!empty($cookieCart['item_name']) and $cookieCart['item_name'] == 'product_id') {
                            $product = Product::where('id', $cookieCart['item_id'])->first();

                            if (!empty($product)) {
                                $item = new Cart();

                                $item->product_order_id = $product->id;
                                $item->productOrder = (object)[
                                    'quantity' => $cookieCart['item_id'] ?? 1,
                                    'product' => $product
                                ];

                                $carts->add($item);
                            }
                        }
                    }
                }
            }
        }

        return $carts;
    }

    public function storeCookieCartsToDB()
    {
        try {
            if (auth()->check()) {
                $user = auth()->user();
                $carts = Cookie::get($this->cookieKey);

                if (!empty($carts)) {
                    $carts = json_decode($carts, true);

                    if (!empty($carts)) {
                        foreach ($carts as $cart) {
                            if (!empty($cart['item_name']) and !empty($cart['item_id'])) {

                                if ($cart['item_name'] == 'webinar_id') {
                                    $this->storeUserWebinarCart($user, $cart);
                                } elseif ($cart['item_name'] == 'product_id') {
                                    $this->storeUserProductCart($user, $cart);
                                } elseif ($cart['item_name'] == 'bundle_id') {
                                    $this->storeUserBundleCart($user, $cart);
                                }
                            }
                        }
                    }

                    Cookie::queue($this->cookieKey, null, 0);
                }
            }
        } catch (\Exception $exception) {

        }
    }

    public function storeUserWebinarCart($user, $data)
    {
        $webinar_id = $data['item_id'];
        $ticket_id = $data['ticket_id'] ?? null;

        $webinar = Webinar::where('id', $webinar_id)
            ->where('private', false)
            ->where('status', 'active')
            ->first();

        if (!empty($webinar) and !empty($user)) {
            $checkCourseForSale = checkCourseForSale($webinar, $user);

            if ($checkCourseForSale != 'ok') {
                return $checkCourseForSale;
            }

            $activeSpecialOffer = $webinar->activeSpecialOffer();

            Cart::updateOrCreate([
                'creator_id' => $user->id,
                'webinar_id' => $webinar_id,
            ], [
                'ticket_id' => $ticket_id,
                'special_offer_id' => !empty($activeSpecialOffer) ? $activeSpecialOffer->id : null,
                'created_at' => time()
            ]);

            return 'ok';
        }

        $toastData = [
            'title' => trans('public.request_failed'),
            'msg' => trans('cart.course_not_found'),
            'status' => 'error'
        ];
        return back()->with(['toast' => $toastData]);
    }

    public function storeUserBundleCart($user, $data)
    {
        $bundle_id = $data['item_id'];
        $ticket_id = $data['ticket_id'] ?? null;

        $bundle = Bundle::where('id', $bundle_id)
            ->where('status', 'active')
            ->first();

        if (!empty($bundle) and !empty($user)) {
            $checkCourseForSale = checkCourseForSale($bundle, $user);

            if ($checkCourseForSale != 'ok') {
                return $checkCourseForSale;
            }

            $activeSpecialOffer = $bundle->activeSpecialOffer();

            Cart::updateOrCreate([
                'creator_id' => $user->id,
                'bundle_id' => $bundle_id,
            ], [
                'ticket_id' => $ticket_id,
                'special_offer_id' => !empty($activeSpecialOffer) ? $activeSpecialOffer->id : null,
                'created_at' => time()
            ]);

            return 'ok';
        }

        $toastData = [
            'title' => trans('public.request_failed'),
            'msg' => trans('cart.course_not_found'),
            'status' => 'error'
        ];
        return back()->with(['toast' => $toastData]);
    }

    public function storeUserProductCart($user, $data)
    {
        $product_id = $data['item_id'];
        $specifications = $data['specifications'] ?? null;
        $quantity = $data['quantity'] ?? 1;

        $product = Product::where('id', $product_id)
            ->where('status', 'active')
            ->first();

        if (!empty($product) and !empty($user)) {
            $checkProductForSale = checkProductForSale($product, $user);

            if ($checkProductForSale != 'ok') {
                return $checkProductForSale;
            }

            $activeDiscount = $product->getActiveDiscount();

            Log::info('Creating/Updating ProductOrder', [
                'product_id' => $product->id,
                'seller_id' => $product->creator_id,
                'buyer_id' => $user->id,
                'quantity' => $quantity
            ]);

            // البحث عن ProductOrder موجود أولاً
            $productOrder = ProductOrder::where('product_id', $product->id)
                ->where('seller_id', $product->creator_id)
                ->where('buyer_id', $user->id)
                ->where('status', 'pending')
                ->first();

            // إذا لم يوجد، إنشاء واحد جديد مع ضمان وجود id صحيح (بدون الاعتماد على AUTO_INCREMENT)
            if (empty($productOrder)) {
                // توليد id يدوي إذا كان الجدول لا يدعم AUTO_INCREMENT بشكل صحيح
                $nextId = (ProductOrder::max('id') ?? 0) + 1;

                // استخدام DB::table()->insert() مباشرة لإدراج السجل مع الـ ID المحدد
                DB::table('product_orders')->insert([
                    'id' => $nextId,
                    'product_id' => $product->id,
                    'seller_id' => $product->creator_id,
                    'buyer_id' => $user->id,
                    'specifications' => $specifications ? json_encode($specifications) : null,
                    'quantity' => $quantity,
                    'discount_id' => !empty($activeDiscount) ? $activeDiscount->id : null,
                    'status' => 'pending',
                    'created_at' => time()
                ]);

                // جلب الـ ProductOrder بعد الإدراج
                $productOrder = ProductOrder::find($nextId);

                Log::info('New ProductOrder created with manual id', [
                    'product_order_id' => $productOrder ? $productOrder->id : null,
                    'next_id' => $nextId
                ]);
            } else {
                // تحديث الـ ProductOrder الموجود
                $productOrder->specifications = $specifications ? json_encode($specifications) : null;
                $productOrder->quantity = $quantity;
                $productOrder->discount_id = !empty($activeDiscount) ? $activeDiscount->id : null;
                $productOrder->save();

                Log::info('Existing ProductOrder updated', ['product_order_id' => $productOrder->id]);
            }

            // التحقق من أن ProductOrder تم إنشاؤه/تحديثه بشكل صحيح
            if (empty($productOrder) || empty($productOrder->id) || $productOrder->id == 0) {
                Log::error('ProductOrder creation failed', [
                    'productOrder' => $productOrder ? $productOrder->toArray() : null,
                    'productOrder_id' => $productOrder ? $productOrder->id : null,
                    'product_id' => $product->id,
                    'user_id' => $user->id
                ]);
                
                $toastData = [
                    'title' => trans('public.request_failed'),
                    'msg' => 'فشل إنشاء طلب المنتج',
                    'status' => 'error'
                ];
                
                // إذا كان الطلب AJAX، إرجاع JSON response
                if (request()->ajax() || request()->wantsJson()) {
                    return response()->json([
                        'success' => false,
                        'title' => $toastData['title'],
                        'msg' => $toastData['msg']
                    ], 400);
                }
                
                return back()->with(['toast' => $toastData]);
            }

            Log::info('ProductOrder created/updated successfully', [
                'product_order_id' => $productOrder->id,
                'product_id' => $product->id
            ]);

            Cart::updateOrCreate([
                'creator_id' => $user->id,
                'product_order_id' => $productOrder->id,
            ], [
                'product_discount_id' => !empty($activeDiscount) ? $activeDiscount->id : null,
                'created_at' => time()
            ]);

            Log::info('Cart item added successfully', [
                'user_id' => $user->id,
                'product_order_id' => $productOrder->id
            ]);

            return 'ok';
        }

        $toastData = [
            'title' => trans('public.request_failed'),
            'msg' => trans('cart.course_not_found'),
            'status' => 'error'
        ];
        return back()->with(['toast' => $toastData]);
    }

    public function storeCookieCart($data)
    {
        $carts = Cookie::get($this->cookieKey);

        if (!empty($carts)) {
            $carts = json_decode($carts, true);
        } else {
            $carts = [];
        }

        $item_id = $data['item_id'];
        $item_name = $data['item_name'];

        if (empty($data['quantity'])) {
            $data['quantity'] = 1;
        }

        $carts[$item_name . '_' . $item_id] = $data;

        Cookie::queue($this->cookieKey, json_encode($carts), 30 * 24 * 60);
    }

    public function getCartCount(): int
    {
        $carts = $this->getCarts();

        return $carts ? $carts->count() : 0;
    }

    public function store(Request $request)
    {
        // Logging للتحقق من الطلب
        Log::info('=== CART STORE REQUEST ===');
        Log::info('Request Method:', ['method' => $request->method()]);
        Log::info('Request Data:', $request->all());
        Log::info('Is AJAX:', ['ajax' => $request->ajax()]);
        Log::info('Wants JSON:', ['wants_json' => $request->wantsJson()]);
        Log::info('Headers:', ['headers' => $request->headers->all()]);

        $user = auth()->user();
        Log::info('User:', ['user_id' => $user ? $user->id : 'null', 'authenticated' => auth()->check()]);

        $this->validate($request, [
            'item_id' => 'required',
            'item_name' => 'nullable',
        ]);

        $data = $request->except('_token');
        $item_name = $data['item_name'];
        Log::info('Item Name:', ['item_name' => $item_name, 'item_id' => $data['item_id'] ?? 'null']);

        // التحقق من تسجيل الدخول - إذا لم يكن المستخدم مسجل، يتم حفظ المنتج في cookie ثم توجيهه إلى صفحة تسجيل الدخول مع حفظ URL الحالي
        if (empty($user)) {
            // حفظ المنتج في cookie حتى يمكن إضافته إلى السلة بعد تسجيل الدخول
            $this->storeCookieCart($data);
            // الحصول على URL الحالي (الصفحة التي كان فيها المستخدم)
            // أولاً: محاولة الحصول من الـ form parameter (return_url)
            // ثانياً: من referer header
            // ثالثاً: من previous URL
            $currentUrl = $request->input('return_url') 
                ?: $request->headers->get('referer') 
                ?: url()->previous();
            
            // إذا كان الطلب AJAX، إرجاع JSON response
            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'redirect' => '/login?url=' . urlencode($currentUrl)
                ], 302);
            }
            
            // توجيه المستخدم إلى صفحة تسجيل الدخول مع إضافة URL الحالي كـ parameter للعودة إليه بعد تسجيل الدخول
            return redirect('/login?url=' . urlencode($currentUrl));
        }

        // store in DB
        $result = null;

        if ($item_name == 'webinar_id') {
            Log::info('Storing webinar to cart');
            $result = $this->storeUserWebinarCart($user, $data);
        } elseif ($item_name == 'product_id') {
            Log::info('Storing product to cart');
            $result = $this->storeUserProductCart($user, $data);
        } elseif ($item_name == 'bundle_id') {
            Log::info('Storing bundle to cart');
            $result = $this->storeUserBundleCart($user, $data);
        }

        Log::info('Store Result:', ['result' => $result]);

        if ($result != 'ok') {
            Log::warning('Store failed:', ['result' => $result]);
            return $result;
        }

        $cartCount = $this->getCartCount();

        if (isset($request->buynow)){
            $redirectUrl = route('cart.index');
            $userCarts = Cart::where('creator_id', $user->id)
                ->with(['productOrder.product'])
                ->get();
            $hasPhysicalProduct = $userCarts->contains(function ($cart) {
                return !empty($cart->productOrder)
                    && !empty($cart->productOrder->product)
                    && $cart->productOrder->product->type === Product::$physical;
            });
            if (!$hasPhysicalProduct) {
                $redirectUrl = url('/cart?checkout=1');
            }

            if ($request->ajax() || $request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'redirect' => $redirectUrl,
                    'cart_count' => $cartCount,
                ]);
            }

            return redirect($redirectUrl);
        }

        if ($request->ajax() || $request->wantsJson()) {
            Log::info('Returning JSON success response');
            $response = [
                'success' => true,
                'title' => trans('cart.cart_add_success_title'),
                'msg' => trans('cart.cart_add_success_msg'),
                'cart_count' => $cartCount,
            ];
            Log::info('JSON Response:', $response);
            return response()->json($response);
        }

        $toastData = [
            'title' => trans('cart.cart_add_success_title'),
            'msg' => trans('cart.cart_add_success_msg'),
            'status' => 'success'
        ];
        return back()->with(['toast' => $toastData]);
    }

    public function destroy($id)
    {
        if (auth()->check()) {
            $user_id = auth()->id();

            $cart = Cart::where('id', $id)
                ->where('creator_id', $user_id)
                ->first();

            if (!empty($cart)) {
                if (!empty($cart->reserve_meeting_id)) {
                    $reserve = ReserveMeeting::where('id', $cart->reserve_meeting_id)
                        ->where('user_id', $user_id)
                        ->first();

                    if (!empty($reserve)) {
                        $reserve->delete();
                    }
                }

                $cart->delete();
            }
        } else {
            $carts = Cookie::get($this->cookieKey);

            if (!empty($carts)) {
                $carts = json_decode($carts, true);

                if (!empty($carts[$id])) {
                    unset($carts[$id]);
                }

                Cookie::queue($this->cookieKey, json_encode($carts), 30 * 24 * 60);
            }
        }

        return response()->json([
            'code' => 200
        ], 200);
    }
}
