<?php

namespace Database\Factories;

use App\Models\ProjectCharter;
use App\Models\ProjectCharterChangeRequest;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ProjectCharterChangeRequest>
 */
class ProjectCharterChangeRequestFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        $changeType = fake()->randomElement([
            ProjectCharterChangeRequest::CHANGE_TYPE_SCOPE,
            ProjectCharterChangeRequest::CHANGE_TYPE_DURATION,
            ProjectCharterChangeRequest::CHANGE_TYPE_COST,
        ]);

        return [
            'project_charter_id' => ProjectCharter::factory(),
            'change_type' => $changeType,
            'status' => ProjectCharterChangeRequest::STATUS_PENDING,
            'justification' => fake()->paragraph(3),
            'new_start_date' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_DURATION ? fake()->dateTimeBetween('now', '+1 month') : null,
            'new_end_date' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_DURATION ? fake()->dateTimeBetween('+1 month', '+6 months') : null,
            'additional_duration_days' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_DURATION ? fake()->numberBetween(1, 30) : null,
            'additional_cost' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_COST ? fake()->numberBetween(1000, 50000) : null,
            'cost_breakdown' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_COST ? fake()->paragraph(2) : null,
            'scope_changes' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_SCOPE ? fake()->paragraph(3) : null,
            'includes_duration_change' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_SCOPE ? fake()->boolean() : false,
            'includes_cost_change' => $changeType === ProjectCharterChangeRequest::CHANGE_TYPE_SCOPE ? fake()->boolean() : false,
            'requested_by' => User::factory(),
        ];
    }

    /**
     * Indicate that the change request is pending.
     */
    public function pending(): static
    {
        return $this->state(fn (array $attributes) => [
            'status' => ProjectCharterChangeRequest::STATUS_PENDING,
        ]);
    }

    /**
     * Indicate that the change request is first approved.
     */
    public function firstApproved(): static
    {
        return $this->state(fn (array $attributes) => [
            'status' => ProjectCharterChangeRequest::STATUS_FIRST_APPROVED,
            'first_approved_by' => User::factory(),
            'first_approval_notes' => fake()->sentence(),
            'first_approved_at' => fake()->dateTimeBetween('-1 week', 'now'),
        ]);
    }

    /**
     * Indicate that the change request is fully approved.
     */
    public function approved(): static
    {
        return $this->state(fn (array $attributes) => [
            'status' => ProjectCharterChangeRequest::STATUS_APPROVED,
            'first_approved_by' => User::factory(),
            'first_approval_notes' => fake()->sentence(),
            'first_approved_at' => fake()->dateTimeBetween('-2 weeks', '-1 week'),
            'final_approved_by' => User::factory(),
            'final_approval_notes' => fake()->sentence(),
            'final_approved_at' => fake()->dateTimeBetween('-1 week', 'now'),
        ]);
    }

    /**
     * Indicate that the change request is rejected.
     */
    public function rejected(): static
    {
        return $this->state(fn (array $attributes) => [
            'status' => ProjectCharterChangeRequest::STATUS_REJECTED,
            'reviewed_by' => User::factory(),
            'review_notes' => fake()->sentence(),
            'reviewed_at' => fake()->dateTimeBetween('-1 week', 'now'),
        ]);
    }

    /**
     * Indicate that this is a scope change request.
     */
    public function scopeChange(): static
    {
        return $this->state(fn (array $attributes) => [
            'change_type' => ProjectCharterChangeRequest::CHANGE_TYPE_SCOPE,
            'scope_changes' => fake()->paragraph(3),
            'includes_duration_change' => fake()->boolean(),
            'includes_cost_change' => fake()->boolean(),
        ]);
    }

    /**
     * Indicate that this is a duration change request.
     */
    public function durationChange(): static
    {
        return $this->state(fn (array $attributes) => [
            'change_type' => ProjectCharterChangeRequest::CHANGE_TYPE_DURATION,
            'new_start_date' => fake()->dateTimeBetween('now', '+1 month'),
            'new_end_date' => fake()->dateTimeBetween('+1 month', '+6 months'),
            'additional_duration_days' => fake()->numberBetween(1, 30),
        ]);
    }

    /**
     * Indicate that this is a cost change request.
     */
    public function costChange(): static
    {
        return $this->state(fn (array $attributes) => [
            'change_type' => ProjectCharterChangeRequest::CHANGE_TYPE_COST,
            'additional_cost' => fake()->numberBetween(1000, 50000),
            'cost_breakdown' => fake()->paragraph(2),
        ]);
    }
}
