<?php

namespace App\Livewire\Reservation;

use App\Models\Reservation\Cart;
use App\Traits\HelperTraits;
use App\Models\Reservation\TemporaryOrder;
use App\Settings\{GeneralSettings, SEOSettings};
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Livewire\Component;
use Livewire\Attributes\Url;
use Artesaos\SEOTools\Traits\SEOTools as SEOToolsTrait;

class CartSummary extends Component implements HasForms
{
    use InteractsWithForms, HelperTraits, SEOToolsTrait;

    #[Url(as: 'ref', keep: true)]
    public $referrer = '/';

    public $carts;
    public ?array $data = [];
    public $isModalOpen = false;
    public $locations;
    public $deliveryAddress;
    protected $listeners = ['updateQuantity'];
    public $id;

    /**
     * Mount lifecycle hook.
     */
    public function mount($id = null)
    {
        $this->id = $id;
        $this->updateCartsFromSession();
        $this->initializeCarts();
        $this->setSeoData();
        $this->initializeDeliveryAddress();
    }

    public function initializeCarts()
    {
        $this->carts = auth()->user()->carts()->when($this->id, function ($query) {
            $query->where('id', $this->id);
        })->get();
    }

    protected function updateCartsFromSession()
    {
        $carts = session()->get('cart', []);
        foreach ($carts as $cart) {
            $existingCart = auth()->user()->carts()->where('ad_id', $cart['ad_id'])->first();
            if ($existingCart) {
                $existingCart->increment('quantity', $cart['quantity']);
            } else {
                auth()->user()->carts()->create($cart);
            }
        }
        session()->forget('cart');
    }

    protected function initializeDeliveryAddress()
    {
        $this->locations = auth()->user()->locations()->where('type', 'delivery_address')->get();

        if ($this->locations->isEmpty()) {
            session()->put('delivery-address', null);
        } elseif (!session()->has('delivery-address')) {
            session()->put('delivery-address', $this->locations[0]);
        }

        $this->deliveryAddress = session()->get('delivery-address', null);
    }

    public function form(Form $form): Form
    {
        return $form->schema($this->locationForm())->statePath('data');
    }

    public function selectAddress($addressId)
    {
        $this->helperSelectAddress($addressId);
    }

    public function addAddress(): void
    {
        $this->helperAddAddress();
    }

    public function removeCart($cartID)
    {
        Cart::destroy($cartID);

        Notification::make()
            ->title(__('messages.t_removed_successfully'))
            ->success()
            ->send();

        $this->initializeCarts();
    }

    public function updateQuantity($cartID, $quantity)
    {
        if ($quantity <= 0) {
            $this->removeCart($cartID);
        } elseif ($quantity > getECommerceMaximumQuantityPerItem()) {
            Notification::make()
                ->title(str_replace('[X]', getECommerceMaximumQuantityPerItem(), __('messages.t_you_have_reached_item_value')))
                ->warning()
                ->send();
        } else {
            Cart::where('id', $cartID)->update(['quantity' => $quantity]);

            Notification::make()
                ->title(__('messages.t_updated_successfully'))
                ->success()
                ->send();
        }

        $this->initializeCarts();
    }

    public function createTemporaryOrderAndRedirectToCheckoutPage($orderType = RESERVATION_TYPE_RETAIL)
    {
        $totalAmount = $this->carts->sum(function ($cart) {
            $price = $cart->ad->isEnabledOffer() && $cart->ad->offer_price ? $cart->ad->offer_price : $cart->ad->price;

            return $cart->quantity * $price;
        });

        if ($orderType == RESERVATION_TYPE_POINT_VAULT && max(auth()->user()->wallet?->points, 0) < $totalAmount) {
            Notification::make()
                ->title('Please add more points to proceed with the purchase.')
                ->success()
                ->send();
        }

        $temporaryOrder = TemporaryOrder::create([
            'user_id' => auth()->id(),
            'items' => $this->carts->pluck('id'),
            'total_amount' => $totalAmount,
            'status' => 'order_created',
            'shipping_address_id' => $this->deliveryAddress->id,
        ]);

        session()->put('current_temporary_order', $temporaryOrder->id);
        session()->put('current_total_amount', $temporaryOrder->total_amount);

        if ($orderType == RESERVATION_TYPE_POINT_VAULT) {

            $wallet = auth()->user()->wallet;

            $wallet->update([
                'points' => $wallet->points - $totalAmount
            ]);

            return redirect()->route('reservation.payment-callback.point_based_order', $temporaryOrder->id);
        }

        return redirect()->route('reservation.checkout-summary');
    }

    protected function setSeoData()
    {
        $generalSettings = app(GeneralSettings::class);
        $seoSettings     = app(SEOSettings::class);

        $title = __('messages.t_cart_summary') . ' ' . ($generalSettings->separator ?? '-') . ' ' .
            ($generalSettings->site_name ?? config('app.name'));
        $this->seo()->setTitle($title);
        $this->seo()->setDescription($seoSettings->meta_description);
    }

    /**
     * Render the Cart Summary view.
     */
    public function render()
    {
        return view('livewire.reservation.cart-summary');
    }
}
