<?php

namespace Database\Factories;

use App\Models\Post;
use App\Models\User;
use App\Models\Group;
use App\Enums\PostType;
use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
 */
class PostFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        $user = User::inRandomOrder()->first();
        $hasGroup = (bool) count($user->groups);
        $date = now()->subDay(rand(1, 20));

        $postTypes = PostType::values();
        if ($hasGroup) {
            $type = Arr::random($postTypes);
            switch ($type) {
                case PostType::GROUP->value:
                    $this->prepareGroupPost($user, $originId, $isSeen, $isAccepted);
                    break;
                case PostType::SHARE_PUBLIC->value:
                case PostType::SHARE_FRIENDS->value:
                case PostType::SHARE_PRIVATE->value:
                    $this->prepareSharePost($type, $originId, $isSeen, $isAccepted);
                    break;
                default:
                    $originId = null;
                    $isSeen = true;
                    $isAccepted = true;
                    break;
            }
        } else {
            $type = Arr::random(array_diff($postTypes, [PostType::GROUP->value]));
            $originId = null;
            if (in_array($type, [
                PostType::SHARE_PUBLIC->value,
                PostType::SHARE_FRIENDS->value,
                PostType::SHARE_PRIVATE->value,
            ])) {
                $this->prepareSharePost($type, $originId, $isSeen, $isAccepted);
            }
            $isSeen = true;
            $isAccepted = true;
        }

        return [
            'content' => fake()->realText(),
            'user_id' => $user->id,
            'type' => $type,
            'origin_id' => $originId,
            'is_seen' => $isSeen,
            'is_accepted' => $isAccepted,
            'created_at' => $date,
            'updated_at' => $date,
        ];
    }

    protected function prepareSharePost(&$type, &$originId, &$isSeen, &$isAccepted)
    {
        $sharablePosts = Post::type(PostType::PUBLIC)->get();
        if (count($sharablePosts) <= 0) {
            $type = PostType::PUBLIC;
        } else {
            $originId = $sharablePosts->random();
        }
        $isSeen = true;
        $isAccepted = true;
    }

    protected function prepareGroupPost(User $user, &$originId, &$isSeen, &$isAccepted)
    {
        $group = fake()->boolean() ? $user->groups()->inRandomOrder()->first() : Group::inRandomOrder()->first();
        $originId = $group->id;
        if ($group->user_id == $user->id) {
            $isSeen = true;
            $isAccepted = true;
        } else {
            $isSeen = fake()->boolean();
            $isAccepted = $isSeen && fake()->boolean();
        }
    }
}
