<?php

namespace App\Livewire\Financial;

use App\Domain\Facility\Models\Facility;
use App\Domain\Financial\Services\ExpenseService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Traits\UsesBranchScope;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('تسجيل إيجار منشأة')]
class FacilityRentForm extends Component
{
    use UsesBranchScope;

    public ?int $facility_id = null;
    public string $period = '';
    public string $amount_display = '';
    public string $payment_method = 'cheque';
    public string $cheque_number = '';
    public ?string $cheque_date = null;
    public string $bank_name = '';
    public string $recipient_name = '';
    public ?string $payment_date = null;
    public string $notes = '';

    public function mount(?int $facility = null): void
    {
        $this->authorize('facilities.update');

        $this->facility_id = $facility;
        $this->payment_date = now()->toDateString();
        $this->period = now()->format('Y-m');

        if ($facility) {
            // BranchScope narrows Facility to the active branch, so a route
            // parameter naming another branch's facility resolves to null here
            // and prefills nothing.
            $f = Facility::find($facility);
            if ($f && $f->monthly_rental_cost) {
                $this->amount_display = number_format($f->monthly_rental_cost / 100, 2, '.', '');
            }
        }
    }

    public function rules(): array
    {
        // `exists:` is a raw table query: it sees neither the academy scope nor
        // the branch scope, and $facility_id arrives from the browser. The
        // <select> that feeds it is filtered, so this rule was the one place a
        // rent payment could be booked against another branch's facility — and,
        // for that matter, against another tenant's. Branch is null only in
        // all-branches mode, where there is nothing to narrow to.
        $branchId = $this->getActiveBranchId();
        $academyId = app('current_academy')?->id;

        $facilityExists = Rule::exists('facilities', 'id')
            ->whereNull('deleted_at')
            ->when($academyId !== null, fn ($rule) => $rule->where('academy_id', $academyId))
            ->when($branchId !== null, fn ($rule) => $rule->where('branch_id', $branchId));

        $rules = [
            'facility_id' => ['required', $facilityExists],
            'period' => 'required|string|size:7',
            'amount_display' => 'required|numeric|min:0.01',
            'payment_method' => 'required|in:cash,card,bank_transfer,wallet,online,cheque,other',
            'recipient_name' => 'nullable|string|max:255',
            'payment_date' => 'required|date',
            'notes' => 'nullable|string',
        ];

        if ($this->payment_method === 'cheque') {
            $rules['cheque_number'] = 'required|string|max:50';
            $rules['cheque_date'] = 'required|date';
            $rules['bank_name'] = 'required|string|max:100';
        }

        return $rules;
    }

    public function messages(): array
    {
        return [
            'facility_id.required' => 'اختر المنشأة',
            'period.required' => 'حدد الشهر',
            'amount_display.required' => 'المبلغ مطلوب',
            'amount_display.min' => 'المبلغ يجب أن يكون أكبر من صفر',
            'payment_method.required' => 'اختر طريقة الدفع',
            'cheque_number.required' => 'رقم الشيك مطلوب',
            'cheque_date.required' => 'تاريخ الشيك مطلوب',
            'bank_name.required' => 'اسم البنك مطلوب',
            'payment_date.required' => 'تاريخ الدفع مطلوب',
        ];
    }

    public function save(ExpenseService $service): void
    {
        $this->validate();

        try {
            $service->recordRentPayment([
                'branch_id' => $this->getActiveBranchId(),
                'facility_id' => $this->facility_id,
                'period' => $this->period,
                'amount' => (int) round((float) $this->amount_display * 100),
                'payment_method' => $this->payment_method,
                'cheque_number' => $this->cheque_number ?: null,
                'cheque_date' => $this->cheque_date ?: null,
                'bank_name' => $this->bank_name ?: null,
                'recipient_name' => $this->recipient_name ?: null,
                'payment_date' => $this->payment_date,
                'notes' => $this->notes ?: null,
            ], auth()->user());

            session()->flash('success', __('تم تسجيل دفعة الإيجار بنجاح'));
            $this->redirect(route('expenses.rent.list'), navigate: true);
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

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

        return view('livewire.financial.facility-rent-form', [
            'facilities' => Facility::where('status', 'active')
                ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
                ->orderBy('name_ar')
                ->get(['id', 'name_ar', 'monthly_rental_cost']),
        ]);
    }
}
