<?php

namespace App\Livewire\Pricing;

use App\Domain\Pricing\Enums\PricingRuleType;
use App\Domain\Pricing\Models\PricingRule;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Livewire\Concerns\WithSorting;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('قواعد التسعير')]
class PricingRuleList extends Component
{
    use WithPagination, WithSorting, UsesBranchScope;

    #[Url]
    public string $search = '';

    #[Url]
    public string $ruleType = '';

    #[Url]
    public string $activeFilter = '';

    public function mount(): void
    {
        $this->authorize('pricing.list');
        if (!request()->has('sortBy')) {
            $this->sortBy = 'priority';
        }
        if (!request()->has('sortDir')) {
            $this->sortDir = 'asc';
        }
    }

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedRuleType(): void
    {
        $this->resetPage();
    }

    public function updatedActiveFilter(): void
    {
        $this->resetPage();
    }

    public function toggleActive(string $uuid): void
    {
        $this->authorize('pricing.update');

        // BranchScope alone is not enough here. PricingRule targets branches
        // through the pricing_rule_branches pivot as well as the legacy
        // branch_id column, and the scope only reads the column — so a rule
        // with branch_id NULL that is pivot-targeted at another branch passes
        // the scope while never appearing in the list below. forBranch() is
        // the predicate that reads both, and it is the one render() uses, so
        // the toggle can only reach a rule this screen actually showed.
        $branchId = $this->getActiveBranchId();

        $rule = PricingRule::where('uuid', $uuid)
            ->when($branchId, fn ($q) => $q->forBranch($branchId))
            ->firstOrFail();

        $rule->update(['is_active' => !$rule->is_active]);
    }

    public function render()
    {
        // forBranch() stays even though BranchScope is already on this model:
        // the scope reads branch_id only, and a rule's real targeting lives in
        // the pricing_rule_branches pivot. This narrows further, never wider.
        $branchId = $this->getActiveBranchId();
        $query = PricingRule::query()
            ->when($branchId, fn ($q) => $q->forBranch($branchId))
            ->with(['branch'])
            ->when($this->search, fn ($q) => $q->where('name_ar', 'ilike', "%{$this->search}%"))
            ->when($this->ruleType, fn ($q) => $q->where('rule_type', $this->ruleType))
            ->when($this->activeFilter !== '', fn ($q) => $q->where('is_active', $this->activeFilter === '1'))
            ->orderBy($this->sortBy, $this->sortDir);

        return view('livewire.pricing.pricing-rule-list', [
            'rules' => $query->paginate(20),
            'ruleTypes' => collect(PricingRuleType::cases())->mapWithKeys(fn ($t) => [$t->value => $t->label()])->toArray(),
        ]);
    }
}
