<?php

namespace App\Livewire\Merchant;

use App\Models\PaymentMethod;
use App\Models\UserAddress;
use App\Services\CartService;
use App\Services\CheckoutService;
use App\Services\PointsService;
use App\Services\ShippingService;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\WithFileUploads;

#[Layout('layouts.merchant')]
#[Title('إتمام الطلب - تاجر بلس')]
class CheckoutPage extends Component
{
    use WithFileUploads;

    public int $pointsToRedeem = 0;
    public ?int $paymentMethodId = null;
    public string $notes = '';
    public bool $usePoints = false;

    /** صورة إيصال الدفع (مطلوبة للطرق غير النقدية) */
    public $paymentReceipt = null;

    public string $addressOption = 'default';
    public ?int $selectedAddressId = null;

    public string $new_shop_name = '';
    public string $new_governorate = '';
    public string $new_city = '';
    public string $new_address_details = '';
    public string $new_landmark = '';
    public string $new_extra_phone = '';
    public bool $save_new_address = true;

    public function mount(): void
    {
        $default = auth()->user()->defaultAddress;
        if ($default) {
            $this->selectedAddressId = $default->id;
        }
        $first = PaymentMethod::where('status', 'active')->orderBy('sort_order')->first();
        $this->paymentMethodId = $first?->id;
    }

    public function updatedUsePoints(): void
    {
        if (! $this->usePoints) {
            $this->pointsToRedeem = 0;
        }
    }

    public function updatedPointsToRedeem(): void
    {
        if ($this->pointsToRedeem < 0) {
            $this->pointsToRedeem = 0;
        }
    }

    public function updatedAddressOption(): void
    {
        if ($this->addressOption === 'default') {
            $default = auth()->user()->defaultAddress;
            $this->selectedAddressId = $default?->id;
        }
    }

    public function updatedPaymentMethodId(): void
    {
        $this->paymentReceipt = null;
        $this->resetValidation('paymentReceipt');
    }

    public function getSelectedPaymentMethodProperty(): ?PaymentMethod
    {
        if (! $this->paymentMethodId) {
            return null;
        }

        return PaymentMethod::find($this->paymentMethodId);
    }

    public function getShippingGovernorateProperty(): ?string
    {
        if ($this->addressOption === 'new') {
            return $this->new_governorate ?: null;
        }

        if ($this->selectedAddressId) {
            $address = auth()->user()->addresses()->find($this->selectedAddressId);
            return $address?->governorate;
        }

        return null;
    }

    public function getShippingCostProperty(): float
    {
        return app(ShippingService::class)->calculateCost($this->shippingGovernorate);
    }

    public function getPaymentFeeProperty(): float
    {
        if (! $this->paymentMethodId) {
            return 0;
        }

        $pm = PaymentMethod::find($this->paymentMethodId);
        if (! $pm) {
            return 0;
        }

        $user = auth()->user();
        $cartService = app(CartService::class);
        $summary = $this->usePoints && $this->pointsToRedeem > 0
            ? $cartService->recalculateWithRedemption($user, $this->pointsToRedeem)
            : $cartService->recalculate();

        $netSubtotal = $summary->subtotal - $summary->discountFromPoints;

        return $pm->calculateFee($netSubtotal);
    }

    public function placeOrder(): void
    {
        $user = auth()->user();
        $cartService = app(CartService::class);

        if ($cartService->count() === 0) {
            session()->flash('error', 'السلة فارغة');
            return;
        }

        if (! $this->paymentMethodId) {
            session()->flash('error', 'يرجى اختيار طريقة الدفع');
            return;
        }

        $pm = PaymentMethod::find($this->paymentMethodId);
        if (! $pm) {
            session()->flash('error', 'طريقة الدفع غير صالحة');
            return;
        }

        if (! $pm->isCod()) {
            $this->validate([
                'paymentReceipt' => 'required|image|max:5120',
            ], [
                'paymentReceipt.required' => 'يرجى رفع صورة إيصال الدفع',
                'paymentReceipt.image' => 'الملف يجب أن يكون صورة (jpg, png, webp)',
                'paymentReceipt.max' => 'حجم الصورة يجب ألا يتجاوز 5 ميجابايت',
            ]);
        }

        $addressId = null;
        $governorate = null;
        $addressSnapshot = null;

        if ($this->addressOption === 'new') {
            $this->validate([
                'new_governorate' => 'required|string',
                'new_address_details' => 'required|string|max:500',
            ]);

            $addressData = [
                'shop_name' => $this->new_shop_name ?: null,
                'governorate' => $this->new_governorate,
                'city' => $this->new_city ?: null,
                'address_details' => $this->new_address_details,
                'landmark' => $this->new_landmark ?: null,
                'extra_phone' => $this->new_extra_phone ?: null,
                'is_default' => false,
            ];

            if ($this->save_new_address) {
                $newAddr = $user->addresses()->create($addressData);
                $addressId = $newAddr->id;
            }

            $governorate = $this->new_governorate;
            $addressSnapshot = implode('، ', array_filter([
                $this->new_shop_name,
                $this->new_address_details,
                $this->new_city,
                $this->new_governorate,
            ]));
        } else {
            $address = $user->addresses()->find($this->selectedAddressId);
            if (! $address) {
                session()->flash('error', 'يرجى اختيار عنوان شحن');
                return;
            }
            $addressId = $address->id;
            $governorate = $address->governorate;
            $addressSnapshot = $address->full_address;
        }

        $shippingCost = app(ShippingService::class)->calculateCost($governorate);
        $paymentFee = $this->paymentFee;

        $receiptPath = null;
        if (! $pm->isCod() && $this->paymentReceipt) {
            $receiptPath = $this->paymentReceipt->store('receipts', 'public');
        }

        try {
            $order = app(CheckoutService::class)->placeOrder(
                user: $user,
                paymentMethodId: $this->paymentMethodId,
                paymentFee: $paymentFee,
                pointsToRedeem: $this->usePoints ? $this->pointsToRedeem : 0,
                notes: $this->notes ?: null,
                shippingCost: $shippingCost,
                shippingAddressId: $addressId,
                shippingGovernorate: $governorate,
                shippingAddressSnapshot: $addressSnapshot,
                paymentReceiptPath: $receiptPath,
            );

            session()->flash('success', "تم إنشاء الطلب #{$order->id} بنجاح");
            $this->redirect(route('merchant.orders.show', $order), navigate: false);
        } catch (\Exception $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function render()
    {
        $user = auth()->user();
        $cartService = app(CartService::class);
        $pointsService = app(PointsService::class);

        $summary = $this->usePoints && $this->pointsToRedeem > 0
            ? $cartService->recalculateWithRedemption($user, $this->pointsToRedeem)
            : $cartService->recalculate();

        $summary->shippingCost = $this->shippingCost;
        $summary->paymentFee = $this->paymentFee;
        $summary->extraCharges = 0;
        $summary->total = round(
            $summary->subtotal - $summary->discountFromPoints
            + $summary->shippingCost + $summary->paymentFee + $summary->extraCharges,
            2
        );

        $maxRedeemable = $pointsService->getMaxRedeemablePoints($user, $summary->subtotal);

        $addresses = $user->addresses()->orderByDesc('is_default')->get();
        $governorates = UserAddress::getEgyptGovernorates();
        $paymentMethods = PaymentMethod::where('status', 'active')->orderBy('sort_order')->get();

        return view('livewire.merchant.checkout-page', compact(
            'summary', 'maxRedeemable', 'addresses', 'governorates', 'paymentMethods'
        ));
    }
}
