<?php

namespace App\Livewire\Financial;

use App\Domain\Financial\Enums\ExpenseCategory;
use App\Domain\Financial\Services\ExpenseService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Traits\ChecksTemporaryUploads;
use App\Domain\Shared\Traits\UsesBranchScope;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\WithFileUploads;

#[Layout('layouts.app')]
#[Title('تسجيل مصروف')]
class ExpenseForm extends Component
{
    use UsesBranchScope, WithFileUploads, ChecksTemporaryUploads;

    public string $category = '';
    public string $amount_display = '';
    public string $description = '';
    public string $recipient_name = '';
    public string $payment_method = 'cash';
    public string $receipt_reference = '';
    public ?string $expense_date = null;
    public string $notes = '';
    public $attachment = null;

    public function mount(): void
    {
        $this->authorize('expenses.create');
        $this->expense_date = now()->toDateString();
    }

    public function rules(): array
    {
        return [
            'category' => 'required|in:' . implode(',', array_column(ExpenseCategory::cases(), 'value')),
            'amount_display' => 'required|numeric|min:0.01',
            'description' => 'required|string|max:500',
            'recipient_name' => 'nullable|string|max:255',
            'payment_method' => 'required|in:cash,card,bank_transfer,wallet,online,cheque,other',
            'receipt_reference' => 'nullable|string|max:100',
            'expense_date' => 'required|date',
            'notes' => 'nullable|string',
            'attachment' => 'nullable|file|max:' . config('uploads.max_kb') . '|mimes:jpg,jpeg,png,pdf,webp',
        ];
    }

    public function messages(): array
    {
        return [
            'category.required' => 'اختر فئة المصروف',
            'amount_display.required' => 'المبلغ مطلوب',
            'amount_display.min' => 'المبلغ يجب أن يكون أكبر من صفر',
            'description.required' => 'وصف المصروف مطلوب',
            'description.max' => 'الوصف يجب ألا يتجاوز 500 حرف',
            'payment_method.required' => 'اختر طريقة الدفع',
            'expense_date.required' => 'تاريخ المصروف مطلوب',
            'attachment.max' => __('حجم الملف لا يتجاوز :mb ميجابايت', ['mb' => intdiv((int) config('uploads.max_kb'), 1024)]),
            'attachment.mimes' => 'الملف يجب أن يكون صورة (jpg, png, webp) أو PDF',
        ];
    }

    public function removeAttachment(): void
    {
        $this->attachment = null;
    }

    public function save(ExpenseService $service): void
    {
        if (! $this->temporaryUploadIsUsable('attachment', $this->attachment)) {
            return;
        }

        $this->validate();

        try {
            // Receipts go to the private disk and are read back through
            // ExpenseAttachmentController — the public disk needs a storage
            // symlink the containers never create.
            $attachment = [];

            if ($this->attachment) {
                $attachment = [
                    'attachment_path' => $this->attachment->store('expenses/receipts', 'local'),
                    'attachment_name' => $this->attachment->getClientOriginalName(),
                    'attachment_disk' => 'local',
                    'attachment_mime' => $this->attachment->getMimeType(),
                    'attachment_size' => $this->attachment->getSize(),
                ];
            }

            $service->recordExpense([
                'branch_id' => $this->getActiveBranchId(),
                'category' => $this->category,
                'amount' => (int) round((float) $this->amount_display * 100),
                'description' => $this->description,
                'recipient_name' => $this->recipient_name ?: null,
                'payment_method' => $this->payment_method,
                'receipt_reference' => $this->receipt_reference ?: null,
                'expense_date' => $this->expense_date,
                'notes' => $this->notes ?: null,
                ...$attachment,
            ], auth()->user());

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

    public function render()
    {
        return view('livewire.financial.expense-form', [
            'categories' => ExpenseCategory::cases(),
        ]);
    }
}
