<?php

namespace App\Livewire\Studio\Loyalty;

use App\Livewire\Forms\Studio\Loyalty\TierForm;
use App\Models\Bottle;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\Tier as TierModel;
use App\Traits\WithAuthorization;
use App\Traits\WithCloseModal;
use App\Traits\WithConfirmation;
use App\Traits\WithToast;
use App\Traits\WithUpdatedData;
use Flux\Flux;
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
use Livewire\Component;

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

    public array $tiers = [];

    public TierForm $form;

    public string $method = 'create';

    public string $modalTitle = '';

    public function mount()
    {
        $this->tiers = TierModel::with(['memberships.user.customer.orders.items'])
            ->withCount('memberships')
            ->orderBy('min_points', 'asc')
            ->get()
            ->map(function ($tier) {
                $topMembership = $tier->memberships()
                    ->with(['user.customer.orders.items'])
                    ->orderByDesc('tier_points')
                    ->first();

                $topMemberStats = null;
                if ($topMembership && $topMembership->user && $topMembership->user->customer) {
                    $orders = $topMembership->user->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');

                    $topMemberStats = [
                        'name' => $topMembership->user->customer->name,
                        'points' => currency($topMembership->tier_points),
                        'total_orders' => currency($totalOrders),
                        'items' => [
                            'total_perfume' => currency($totalPerfume),
                            'total_product' => currency($totalProduct),
                            'total_bottle' => currency($totalBottle),
                        ],
                        'total' => [
                            'subtotal' => currency($subtotal, 'Rp'),
                            'discount' => currency($totalDiscount, 'Rp'),
                            'grand_total' => currency($grandTotal, 'Rp'),
                        ],
                    ];
                }

                return [
                    'id' => $tier->id,
                    'hash' => $tier->hash,
                    'name' => $tier->name,
                    'min_points' => currency($tier->min_points),
                    'max_points' => currency($tier->max_points),
                    'total_members' => currency($tier->memberships_count),
                    'top_member' => $topMemberStats,
                ];
            })
            ->toArray();
    }

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

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

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

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

        $tier = $this->form->store();

        $tiers = $this->tiers;
        $tiers[] = [
            'hash' => $tier->hash,
            'name' => $tier->name,
            'min_points' => currency($tier->min_points, ''),
            'max_points' => currency($tier->max_points, ''),
            'total_members' => 0,
            'top_member' => null,
        ];

        usort($tiers, fn ($a, $b) => replaceCurrency($a['min_points']) <=> replaceCurrency($b['min_points']));

        $this->tiers = $tiers;

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

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

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

        $tier = $this->form->update();

        // update array tiers
        $tiers = $this->tiers;
        foreach ($tiers as $index => $item) {
            if ($item['hash'] === $tier->hash) {
                $tiers[$index] = [
                    'hash' => $tier->hash,
                    'name' => $tier->name,
                    'min_points' => currency($tier->min_points, ''),
                    'max_points' => currency($tier->max_points, ''),
                ];
                break;
            }
        }
        $this->tiers = $tiers;

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

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

    public function delete(TierModel $tier)
    {
        $tier->delete();

        // update array tiers
        $tiers = array_values(array_filter($this->tiers, fn ($item) => $item['hash'] !== $tier->hash));
        $this->tiers = $tiers;

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

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

    public function render()
    {
        return view('livewire.studio.loyalty.tiers', [
            'pageTitle' => 'Tier',
        ]);
    }
}
