<?php

namespace App\Livewire\Financial;

use App\Domain\Financial\Enums\ExpenseCategory;
use App\Domain\Financial\Models\Expense;
use App\Domain\Financial\Services\ExpenseService;
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 ExpenseList extends Component
{
    use WithPagination, UsesBranchScope, WithSorting;

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

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

    #[Url]
    public ?string $from_date = null;

    #[Url]
    public ?string $to_date = null;

    public bool $showCancelModal = false;
    public ?string $cancellingExpenseUuid = null;
    public string $cancellationReason = '';

    public function mount(): void
    {
        if (!request()->has('sortBy')) {
            $this->sortBy = 'expense_date';
        }
    }

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

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

    public function openCancelModal(string $uuid): void
    {
        $this->cancellingExpenseUuid = $uuid;
        $this->cancellationReason = '';
        $this->showCancelModal = true;
    }

    public function confirmCancel(ExpenseService $service): void
    {
        $this->validate([
            'cancellationReason' => 'required|min:3|max:500',
        ], [
            'cancellationReason.required' => 'يرجى كتابة سبب الإلغاء',
            'cancellationReason.min' => 'السبب قصير جداً',
        ]);

        $expense = Expense::where('uuid', $this->cancellingExpenseUuid)->firstOrFail();

        try {
            $service->cancelExpense($expense, $this->cancellationReason, auth()->user());
            session()->flash('success', __('تم إلغاء المصروف بنجاح'));
        } catch (\App\Domain\Shared\Exceptions\DomainException $e) {
            session()->flash('error', $e->getMessage());
        }

        $this->showCancelModal = false;
        $this->cancellingExpenseUuid = null;
        $this->cancellationReason = '';
    }

    public function render()
    {
        $branchId = $this->getActiveBranchId();

        $expenses = Expense::with(['creator'])
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->when($this->category_filter, fn ($q) => $q->where('category', $this->category_filter))
            ->when($this->from_date, fn ($q) => $q->where('expense_date', '>=', $this->from_date))
            ->when($this->to_date, fn ($q) => $q->where('expense_date', '<=', $this->to_date))
            ->when($this->search, fn ($q) => $q->where(function ($q) {
                $q->where('description', 'ilike', "%{$this->search}%")
                    ->orWhere('recipient_name', 'ilike', "%{$this->search}%");
            }))
            ->orderBy($this->sortBy, $this->sortDir)
            ->paginate(20);

        $totalAmount = Expense::query()
            ->where('status', 'active')
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->when($this->category_filter, fn ($q) => $q->where('category', $this->category_filter))
            ->when($this->from_date, fn ($q) => $q->where('expense_date', '>=', $this->from_date))
            ->when($this->to_date, fn ($q) => $q->where('expense_date', '<=', $this->to_date))
            ->sum('amount');

        return view('livewire.financial.expense-list', [
            'expenses' => $expenses,
            'totalAmount' => $totalAmount,
            'categories' => ExpenseCategory::cases(),
        ]);
    }
}
