<?php

namespace App\Livewire\Studio\Loyalty;

use App\Livewire\Forms\Studio\Loyalty\TierForm;
use App\Models\Bottle;
use App\Models\Membership;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\Tier as TierModel;
use App\Traits\Authorization\WithAuthorization;
use App\Traits\Components\WithCloseModal;
use App\Traits\Components\WithConfirmation;
use App\Traits\Components\WithToast;
use App\Traits\Notification\WithSubscribeNotification;
use App\Traits\Utilities\WithUpdatedData;
use Flux\Flux;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Title('Tier')]
class Tier extends Component
{
    use WithAuthorization, WithCloseModal, WithConfirmation, WithSubscribeNotification, WithToast, WithUpdatedData;

    public TierForm $form;

    public string $method = 'create';

    public string $modalTitle = '';

    public function getTopMemberStats($tierId): ?array
    {
        $topMembership = Membership::where('tier_id', $tierId)
            ->with(['user.customer.orders.items'])
            ->orderByDesc('total_spending')
            ->first();

        if (! $topMembership || ! $topMembership->user || ! $topMembership->user->customer) {
            return null;
        }

        $customer = $topMembership->user->customer;
        $orders = $customer->orders;
        $totalOrders = $orders->count();

        // Sum items
        $totalPerfume = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Perfume::class))->sum('quantity');
        $totalProduct = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Product::class))->sum('quantity');
        $totalBottle = $orders->flatMap(fn ($order) => $order->items->where('orderable_type', Bottle::class))->sum('quantity');

        // Sum total
        $subtotal = $orders->sum('subtotal');
        $totalDiscount = $orders->sum('discount');
        $grandTotal = $orders->sum('total');

        return [
            'name' => $customer->name,
            'spending' => formatCurrencyNumber($topMembership->total_spending, 'Rp'),
            'total_orders' => formatCurrencyNumber($totalOrders),
            'items' => [
                'total_perfume' => formatCurrencyNumber($totalPerfume),
                'total_product' => formatCurrencyNumber($totalProduct),
                'total_bottle' => formatCurrencyNumber($totalBottle),
            ],
            'total' => [
                'subtotal' => formatCurrencyNumber($subtotal, 'Rp'),
                'discount' => formatCurrencyNumber($totalDiscount, 'Rp'),
                'grand_total' => formatCurrencyNumber($grandTotal, 'Rp'),
            ],
        ];
    }

    public function create(): void
    {
        $this->canOrAbort('create tier');

        $this->form->store();

        // Reorder the entire tier chain to ensure proper max_spending
        TierModel::reorderTierChain();

        $this->toast('Tier berhasil ditambahkan.');

        Flux::modals()->close();
    }

    public function update(): void
    {
        $this->canOrAbort('update tier');

        $oldMinSpending = $this->form->tier->min_spending;
        $newMinSpending = parseRupiahToInt($this->form->min_spending);

        $this->form->update();

        // If min_spending changed, reorder the entire tier chain
        if ($oldMinSpending !== $newMinSpending) {
            TierModel::reorderTierChain();
        }

        $this->toast('Tier berhasil diperbarui.');

        Flux::modals()->close();
    }

    public function delete(TierModel $tier): void
    {
        $this->canOrAbort('delete tier');

        // Validate if tier can be deleted
        $canDelete = TierModel::canDeleteTier($tier->id);
        if (! $canDelete['can_delete']) {
            $this->toast($canDelete['message'], 'Gagal', 'danger');

            return;
        }

        $tier->delete();

        // Reorder tier chain after deletion to ensure proper max_spending
        TierModel::reorderTierChain();

        $this->toast('Tier berhasil dihapus.');

        Flux::modals()->close();
    }

    #[On('modal:open')]
    public function openModal(string $method, string $modalTitle, ?string $id = null): void
    {
        $this->resetValidation();
        $this->resetErrorBag();

        $this->method = $method;
        $this->modalTitle = $modalTitle;

        $id && $this->form->setTier(TierModel::byHashOrFail($id));
    }

    public function render(): View
    {
        $tiers = TierModel::withCount('memberships')
            ->orderBy('min_spending', 'asc')
            ->get()
            ->map(fn (TierModel $tier) => [
                'id' => $tier->id,
                'hash' => $tier->hash,
                'name' => $tier->name,
                'min_spending' => formatCurrencyNumber($tier->min_spending, 'Rp'),
                'max_spending' => $tier->max_spending ? formatCurrencyNumber($tier->max_spending, 'Rp') : 'Tak terbatas',
                'total_members' => formatCurrencyNumber($tier->memberships_count),
                'top_member' => $this->getTopMemberStats($tier->id),
            ])
            ->toArray();

        return view('livewire.studio.loyalty.tiers', [
            'pageTitle' => 'Tier',
            'tiers' => $tiers,
        ]);
    }
}
