<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\Quote;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/** @extends Factory<Quote> */
class QuoteFactory extends Factory
{
    protected $model = Quote::class;

    /** @return array<string, mixed> */
    public function definition(): array
    {
        $items = [];
        $itemCount = $this->faker->numberBetween(1, 4);

        for ($i = 0; $i < $itemCount; $i++) {
            $items[] = [
                'description' => $this->faker->sentence(4),
                'quantity' => $this->faker->numberBetween(1, 5),
                'unit_price' => $this->faker->randomFloat(2, 5, 500),
            ];
        }

        $subtotal = collect($items)->sum(fn (array $item): float => $item['unit_price'] * $item['quantity']);
        $tax = round($subtotal * 0.1, 2);

        return [
            'user_id' => User::factory(),
            'prospect_email' => null,
            'prospect_name' => null,
            'number' => Quote::generateNumber(),
            'status' => 'draft',
            'items' => $items,
            'subtotal' => $subtotal,
            'tax' => $tax,
            'total' => $subtotal + $tax,
            'currency' => 'USD',
            'notes' => $this->faker->optional()->paragraph(),
            'valid_until' => $this->faker->optional()->dateTimeBetween('+7 days', '+60 days'),
            'accepted_at' => null,
            'sent_at' => null,
            'created_by' => User::factory(),
        ];
    }

    public function prospect(): static
    {
        return $this->state(fn (): array => [
            'user_id' => null,
            'prospect_email' => $this->faker->safeEmail(),
            'prospect_name' => $this->faker->name(),
        ]);
    }

    public function sent(): static
    {
        return $this->state(fn (): array => [
            'status' => 'sent',
            'sent_at' => now(),
        ]);
    }

    public function accepted(): static
    {
        return $this->state(fn (): array => [
            'status' => 'accepted',
            'sent_at' => now()->subDays(3),
            'accepted_at' => now(),
        ]);
    }

    public function rejected(): static
    {
        return $this->state(fn (): array => [
            'status' => 'rejected',
            'sent_at' => now()->subDays(3),
        ]);
    }

    public function expired(): static
    {
        return $this->state(fn (): array => [
            'status' => 'sent',
            'sent_at' => now()->subDays(45),
            'valid_until' => now()->subDays(5),
        ]);
    }
}
