<?php

namespace Database\Factories;

use App\Models\Harvest;
use App\Models\VineyardRow;
use App\Models\VarietyVariation;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Harvest>
 */
class HarvestFactory extends Factory
{
    protected $model = Harvest::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        $qualities = ['excellent', 'good', 'fair', 'poor'];
        $conditions = ['healthy', 'slightly damaged', 'botrytis', 'overripe'];

        $weatherConditions = [
            'Sunny, 20°C',
            'Sunny, 22°C',
            'Partly cloudy, 18°C',
            'Overcast, 16°C',
            'Clear sky, 24°C',
            'Light rain, 14°C'
        ];

        return [
            'vineyard_row_id' => VineyardRow::factory(),
            'variety_variation_id' => VarietyVariation::factory(),
            'user_id' => User::factory(),
            'weight' => fake()->randomFloat(2, 300.0, 1200.0),
            'sugar_content' => fake()->randomFloat(2, 16.0, 26.0),
            'date' => fake()->dateTimeBetween('-1 year', 'now'),
            'quality' => fake()->randomElement($qualities),
            'grape_condition' => fake()->randomElement($conditions),
            'notes' => fake()->optional()->sentence(12),
            'weather_conditions' => fake()->randomElement($weatherConditions),
            'harvest_time' => fake()->time('H:i:s'),
        ];
    }

    /**
     * Indicate that the harvest is of excellent quality.
     */
    public function excellent(): static
    {
        return $this->state(fn (array $attributes) => [
            'quality' => 'excellent',
            'grape_condition' => 'healthy',
        ]);
    }

    /**
     * Indicate that the harvest is recent.
     */
    public function recent(): static
    {
        return $this->state(fn (array $attributes) => [
            'date' => fake()->dateTimeBetween('-3 months', 'now'),
        ]);
    }

    /**
     * Keep the harvest aligned with its vineyard row's variation.
     */
    public function configure(): static
    {
        return $this->afterMaking(function (Harvest $harvest) {
            $row = $harvest->relationLoaded('vineyardRow') ? $harvest->vineyardRow : null;

            if (! $row && $harvest->vineyard_row_id) {
                $row = VineyardRow::find($harvest->vineyard_row_id);
                if ($row) {
                    $harvest->setRelation('vineyardRow', $row);
                }
            }

            if ($row) {
                $harvest->variety_variation_id = $row->variety_variation_id;
                return;
            }

            $variationId = $this->normalizeVarietyVariationId($harvest->variety_variation_id);

            if (! $variationId) {
                $variation = VarietyVariation::factory()->create();
                $variationId = $variation->getKey();
                $harvest->variety_variation_id = $variationId;
            } else {
                $harvest->variety_variation_id = $variationId;
            }

            $row = VineyardRow::factory()->create([
                'variety_variation_id' => $harvest->variety_variation_id,
            ]);

            $harvest->vineyard_row_id = $row->getKey();
            $harvest->setRelation('vineyardRow', $row);
        });
    }

    private function normalizeVarietyVariationId(mixed $value): ?int
    {
        if ($value instanceof VarietyVariation) {
            return $value->getKey();
        }

        return $value !== null ? (int) $value : null;
    }
}
