<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\AddressResources;
use App\Http\Resources\GetCartResource;
use App\Models\Cart;
use App\Models\Order;
use App\Models\OrderDetails;
use App\Models\OrderItem;
use App\Models\Product;
use App\Models\ProductVarient;
use App\Models\User;
use App\Models\Address;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Models\DeliveryFeeMaster;
class CartController extends Controller
{
    public function cart_update(Request $request)
    {
        if (!auth()->guard('sanctum')->check()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Please login!',
                'data' => [],
                'code' => 401,
            ]);
        }

        $user = auth()->guard('sanctum')->user();
        $cart = Cart::where('id', $request->cart_id)
            ->where('user_id', $user->id)
            ->first();

        if (!$cart) {
            return response()->json([
                'status' => 'error',
                'data' => [],
                'message' => 'Cart item not found.',
                'code' => 404,
            ], 404);
        }

        $cart->quantity = $request->quantity;

        if ($request->has('variant_id')) {
            $cart->varient_id = $request->variant_id;
        }

        $cart->save();

        return response()->json([
            'status' => 'success',
            'data' => $cart,
            'message' => 'Cart updated successfully.',
            'code' => 200,
        ], 200);
    }
    public function cart_delete(Request $request)
    {
        if (!auth()->guard('sanctum')->check()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Please login!',
                'data' => [],
                'code' => 401,
            ]);
        }
        $user = auth()->guard('sanctum')->user();
        $cart = Cart::where('id', $request->cart_id)
            ->where('user_id', $user->id)
            ->first();
        if (!$cart) {
            return response()->json([
                'status' => 'error',
                'data' => [],
                'message' => 'Cart item not found.',
                'code' => 404,
            ], 404);
        }
        $cart->delete();
        return response()->json([
            'status' => 'success',
            'data' => [],
            'message' => 'Product removed from cart.',
            'code' => 200,
        ], 200);
    }
    public function address(Request $request)
    {
        if (!auth()->guard('sanctum')->check()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Please login!',
                'data' => [],
                'code' => 401,
            ]);
        }
    
        $user = auth()->guard('sanctum')->user();
    
        $validated = $request->validate([
            'house_no'  => 'required|string',
            'road_name' => 'required|string',
            'landmark'  => 'nullable|string',
            'district'  => 'required|string',
            'state'     => 'required|string',
            'pin'       => 'required|numeric|digits:6',
        ]);
    
     
        Address::where('user_id', $user->id)->update(['is_current' => false]);
    
       
        $address             = new Address($validated);
        $address->user_id    = $user->id;
        $address->is_current = true;
        $address->save();
    
        return response()->json([
            'status'  => 'success',
            'message' => 'Address added successfully!',
            'data'    => $address,
            'code'    => 201,
        ]);
    }
    
    public function address_update(Request $request, $id)
    {
        $user = auth()->guard('sanctum')->user();
        $address = Address::where('user_id', $user->id)->findOrFail($id);

        $validated = $request->validate([
            'house_no'  => 'string',
            'road_name' => 'string',
            'landmark'  => 'nullable|string',
            'district'  => 'string',
            'state'     => 'string',
            'pin'       => 'string',
        ]);

        $address->update($validated);

        return response()->json([
            'status'  => 'success',
            'message' => 'Address updated successfully!',
            'data'    => $address,
            'code'    => 200,
        ]);
    }

    public function addresses_delete($id)
    {
        $user = auth()->guard('sanctum')->user();
        $address = Address::where('user_id', $user->id)->findOrFail($id);

        $address->delete();

        return response()->json([
            'status' => 'success',
            'message' => 'Address deleted successfully!',
            'code' => 200,
        ]);
    }
    public function addresses()
    {
        $user = auth()->guard('sanctum')->user();
        $addresses = Address::where('user_id', $user->id)->get();

        return response()->json([
            'status' => 'success',
            'message' => 'Addresses retrieved successfully!',
            'data' => $addresses,
            'code' => 200,
        ]);
    }
    public function address_current($id)
    {
        $user = auth()->guard('sanctum')->user();
        Address::where('user_id', $user->id)->update(['is_current' => false]);

        $address = Address::where('user_id', $user->id)->findOrFail($id);
        $address->is_current = true;
        $address->save();

        return response()->json([
            'status' => 'success',
            'message' => 'Current address set successfully!',
            'data' => $address,
            'code' => 200,
        ]);
    }
    public function show_address($id)
    {
        try {
            if (!auth()->guard('sanctum')->check()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Please login!',
                    'data' => [],
                    'code' => 401,
                ]);
            }

            $user = auth()->guard('sanctum')->user();
            $address = Address::where('id', $id)
                ->where('user_id', $user->id)
                ->first();

            if (!$address) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Address not found or you do not have permission to view this address.',
                    'code' => 404,
                ], 404);
            }

            return response()->json([
                'status' => 'success',
                'data' => $address,
                'message' => 'Address fetched successfully.',
                'code' => 200,
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error fetching address: ' . $e->getMessage());

            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch address.',
                'code' => 500,
            ], 500);
        }
    }
    
    public function cart()
    {
        if (!auth()->guard('sanctum')->check()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Please login!',
                'data' => [],
                'code' => 401,
            ]);
        }

        $user = auth()->guard('sanctum')->user();

        $cartItems = Cart::where('user_id', $user->id)
            ->with(['product.category', 'product.subcategory'])
            ->get();

        $totalPrice = 0;

        $cartItems->transform(function ($cartItem) use (&$totalPrice) {
            $product = $cartItem->product;

            $price = $cartItem->price;

            $cartItem->price = $price;
            $totalPrice += $cartItem->quantity * $price;

           
            $product->category_name = $product->category ? $product->category->category_name : null;
            $product->subcategory_name = $product->subcategory ? $product->subcategory->subcategory_name : null;

        
            $cartItem->variant_id = $cartItem->variant_id;

            return new GetCartResource($cartItem);
        });

        return response()->json([
            'status' => 'success',
            'data' => $cartItems,
            'total_price' => $totalPrice,
            'message' => $cartItems->isEmpty() ? 'Cart is empty.' : 'Cart items fetched successfully.',
            'code' => 200,
        ], 200);
    }
    public function cart_add(Request $request)
    {
        if (!auth()->guard('sanctum')->check()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Please login!',
                'code' => 401,
            ]);
        }

        $user = auth()->guard('sanctum')->user();

        $request->validate([
            'product_id' => 'required|integer|exists:products,id',
            'quantity'   => 'required|integer|min:1',
            'variant_id' => 'required|integer|exists:product_varients,id',
        ]);

        $product = Product::find($request->product_id);
        $variant = ProductVarient::find($request->variant_id);

        if (!$product || !$variant) {
            return response()->json([
                'status'  => 'error',
                'message' => 'Product or variant not found.',
                'code'    => 404,
            ], 404);
        }

      
        $cart = Cart::where('user_id', $user->id)
            ->where('product_id', $product->id)
            ->where('variant_id', $variant->id)
            ->first();
        if ($cart) {
            $cart->quantity += $request->quantity;
            $cart->save();
        } else {
        
            $cart = Cart::create([
                'user_id'    => $user->id,
                'product_id' => $product->id,
                'variant_id' => $variant->id,
                'quantity'   => $request->quantity,
                'price'      => $variant->price,
            ]);
        }
        
       
        if (!$cart) {
            return response()->json([
                'status'  => 'error',
                'message' => 'Failed to add item to cart.',
                'code'    => 500,
            ], 500);
        }

    
        $cartItem = [
            'product_id'  => $cart->product_id,
            'variant_id'  => $cart->variant_id,
            'quantity'    => $cart->quantity,
            'price'       => $cart->price,
            'total_price' => $cart->quantity * $cart->price,
        ];

        return response()->json([
            'status'  => 'success',
            'data'    => $cartItem,
            'message' => 'Product added to cart.',
            'code'    => 200,
        ], 201);
    }
    public function getCheckoutDetails($orderId)
    {
        try {
            $userId  = auth()->id();
            $address = Address::getCurrentAddress($userId);
            $order   = Order::with(['items.product.category', 'items.product.subcategory', 'items.product.variants'])
                ->where('id', $orderId)
                ->first();

            if (!$order) {
                return response()->json([
                    'status'  => 'error',
                    'message' => 'Order not found.',
                    'code'    => 404,
                ], 404);
            }

        
            $formattedAddress = $address ? implode(', ', array_filter([
                $address->house_no,
                $address->road_name,
                $address->landmark,
                $address->district,
                $address->state,
                $address->pin,
            ])) : 'No delivery address set';



            $orderItems = $order->items->map(function ($item) {
                $variantId = $item->product->variants->first()->id ?? 'N/A';
                return [
                    'product_details_id'   => $item->product_id,
                    'product_details_name' => $item->product->title ?? 'Unknown Product',
                    'category_name'        => $item->product->category->category_name ?? 'N/A',
                    'subcategory_name'     => $item->product->subcategory->subcategory_name ?? 'N/A',
                    'variant_id'           => $variantId,
                    'quantity'             => $item->quantity,
                    'price'                => number_format($item->price, 2),
                    'subtotal'             => number_format($item->quantity * $item->price, 2),
                ];
            });


           
            return response()->json([
                'status' => 'success',
                'data' => [
                    'order_id'         => $order->id,
                    'cart_items'       => $orderItems,
                    'delivery_address' => $formattedAddress,
                    'subtotal'         => number_format($order->subtotal, 2),
                    'delivery_fee'     => number_format($order->delivery_fee, 2),
                    'total_amount'     => number_format($order->total_amount, 2),
                ],
                'message' => 'Checkout details fetched successfully',
                'code' => 200,
            ], 200);

        } catch (\Exception $e) {
            Log::error('Error fetching order details: ' . $e->getMessage());
            return response()->json([
                'status'  => 'error',
                'message' => 'Failed to fetch order details.',
                'code'    => 500,
            ], 500);
        }
    }
  

    public function checkout(Request $request)
    {
        try {
            $userId = auth()->id();
            $address = Address::where('user_id', $userId)
                ->where('is_current', true)
                ->first() ?? Address::where('user_id', $userId)
                ->latest()
                ->first();
    
            $cartItems = Cart::with(['product.category', 'product.subcategory', 'product.variants'])
                ->where('user_id', $userId)
                ->get();
    
            if ($cartItems->isEmpty()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'No items in cart.',
                    'code' => 400,
                ], 400);
            }
    
            $packingInstruction = $request->input('packing_instruction', '');
            $subtotal = 0;
            $cartItemDetails = [];
    
            foreach ($cartItems as $cartItem) {
                $product = $cartItem->product;
                $productName = $product->title ?? 'Unknown Product';
                $categoryName = $product->category->category_name ?? 'N/A';
                $subcategoryName = $product->subcategory->subcategory_name ?? 'N/A';
                $price = (float) $cartItem->price;
    
                $quantity = (int) $cartItem->quantity;
                $itemSubtotal = $price * $quantity;
                $subtotal += $itemSubtotal;
    
                $cartItemDetails[] = [
                    'product_details_id' => $product->id ?? 'N/A',
                    'product_details_name' => $productName,
                    'category_name' => $categoryName,
                    'subcategory_name' => $subcategoryName,
                    'variant_id' => $cartItem->variant_id ?? 'N/A',
                    'quantity' => $quantity,
                    'price' => number_format($price, 2),
                    'subtotal' => number_format($itemSubtotal, 2),
                ];
            }
    
            $deliveryFeeMaster = DeliveryFeeMaster::where('price_from', '<=', $subtotal)
                ->where(function ($query) use ($subtotal) {
                    $query->where('price_to', '>=', $subtotal)
                        ->orWhereNull('price_to');
                })
                ->first();
    
            $deliveryFee = $deliveryFeeMaster ? $deliveryFeeMaster->delivery_fee : 50;
            $deliveryFee = max($deliveryFee, 20);
            $totalAmount = $subtotal + $deliveryFee;
    
            $formattedAddress = $address ? implode(', ', array_filter([
                $address->house_no,
                $address->road_name,
                $address->landmark,
                $address->district,
                $address->state,
                $address->pin,
            ])) : 'No delivery address set';
    
            $order = Order::create([
                'user_id'             => $userId,
                'delivery_address'    => $formattedAddress,
                'packing_instruction' => $packingInstruction,
                'subtotal'            => $subtotal,
                'delivery_fee'        => $deliveryFee,
                'total_amount'        => $totalAmount,
            ]);
    
            foreach ($cartItems as $cartItem) {
                $product         = $cartItem->product;
                $productName     = $product->title ?? 'Unknown Product';
                $categoryName    = $product->category->category_name ?? 'N/A';
                $subcategoryName = $product->subcategory->subcategory_name ?? 'N/A';
                $price           = (float) $cartItem->price;
    
                $variant = $product->variants->firstWhere('id', $cartItem->variant_id);
                if ($variant && $variant->discount) {
                    $discountedPrice = $price - ($price * ($variant->discount / 100));
                    $price = $discountedPrice;
                }
    
                $quantity = (int) $cartItem->quantity;
                $itemSubtotal = $price * $quantity;
    
                OrderItem::create([
                    'order_id'         => $order->id,
                    'product_id'       => $product->id ?? null,
                    'product_name'     => $productName,
                    'category_name'    => $categoryName,
                    'subcategory_name' => $subcategoryName,
                    'quantity'         => $quantity,
                    'price'            => $price,
                    'subtotal'         => $itemSubtotal,
                ]);
            }
    
            return response()->json([
                'status' => 'success',
                'data' => [
                    'cart_items'          => $cartItemDetails,
                    'subtotal'            => number_format($subtotal, 2),
                    'delivery_fee'        => number_format($deliveryFee, 2),
                    'total_amount'        => number_format($totalAmount, 2),
                    'delivery_address'    => $formattedAddress,
                    'packing_instruction' => $packingInstruction,
                ],
                'message' => 'Checkout fetched successfully',
                'order_id' => $order->id,
                'code' => 200,
            ], 200);
    
        } catch (\Exception $e) {
            Log::error('Error processing checkout: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to process checkout.',
                'code' => 500,
            ], 500);
        }
    }
    

}
