<?php

namespace App\Http\Requests;

use App\Enums\InvoiceStatus;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StoreInvoiceRequest extends FormRequest
{
    public function authorize(): bool
    {
        return in_array($this->user()?->role, ['business_owner', 'staff'], true);
    }

    protected function prepareForValidation(): void
    {
        $items = collect($this->input('items', []))
            ->filter(function (array $item): bool {
                return filled($item['service_id'] ?? null)
                    || filled($item['description'] ?? null)
                    || filled($item['quantity'] ?? null)
                    || filled($item['unit_price'] ?? null);
            })
            ->values()
            ->all();

        $this->merge([
            'currency' => strtoupper((string) ($this->input('currency') ?: 'USD')),
            'items' => $items,
        ]);
    }

    public function rules(): array
    {
        $businessId = $this->attributes->get('current_business')?->id;

        return [
            'invoice_number' => [
                'nullable',
                'string',
                'max:60',
                Rule::unique('invoices', 'invoice_number')->where('business_id', $businessId),
            ],
            'customer_id' => [
                'required',
                'integer',
                Rule::exists('customers', 'id')->where('business_id', $businessId),
            ],
            'appointment_id' => [
                'nullable',
                'integer',
                Rule::exists('appointments', 'id')->where('business_id', $businessId),
            ],
            'status' => ['required', Rule::in(array_keys(InvoiceStatus::options()))],
            'issue_date' => ['required', 'date'],
            'due_date' => ['nullable', 'date', 'after_or_equal:issue_date'],
            'currency' => ['required', 'string', 'size:3'],
            'discount_total' => ['nullable', 'numeric', 'min:0', 'max:999999.99'],
            'notes' => ['nullable', 'string', 'max:3000'],
            'footer_note' => ['nullable', 'string', 'max:2000'],
            'items' => ['required', 'array', 'min:1'],
            'items.*.service_id' => [
                'nullable',
                'integer',
                Rule::exists('services', 'id')->where('business_id', $businessId),
            ],
            'items.*.description' => ['required', 'string', 'max:255'],
            'items.*.quantity' => ['required', 'numeric', 'min:0.01', 'max:9999.99'],
            'items.*.unit_price' => ['required', 'numeric', 'min:0', 'max:999999.99'],
            'items.*.tax_rate' => ['nullable', 'numeric', 'min:0', 'max:100'],
        ];
    }

    public function payload(): array
    {
        $validated = $this->validated();

        return [
            'invoice_number' => $validated['invoice_number'] ?? null,
            'customer_id' => $validated['customer_id'],
            'appointment_id' => $validated['appointment_id'] ?? null,
            'status' => $validated['status'],
            'issue_date' => $validated['issue_date'],
            'due_date' => $validated['due_date'] ?? null,
            'currency' => $validated['currency'],
            'discount_total' => $validated['discount_total'] ?? 0,
            'notes' => $validated['notes'] ?? null,
            'footer_note' => $validated['footer_note'] ?? null,
            'items' => $validated['items'],
        ];
    }
}
