<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Enums\Gender;
use App\Enums\MaritalStatus;
use App\Enums\MembershipStatus;
use App\Models\Branch;
use App\Models\Member;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends Factory<Member>
 */
class MemberFactory extends Factory
{
    public function definition(): array
    {
        $gender = fake()->randomElement(Gender::cases());
        $firstName = $gender === Gender::Male ? fake()->firstNameMale() : fake()->firstNameFemale();
        $dateOfBirth = fake()->optional(0.9)->dateTimeBetween('-95 years', '-1 year');

        return [
            'branch_id' => Branch::factory(),
            'household_id' => null,
            'household_role' => null,
            'title' => fake()->optional(0.4)->randomElement(['Mr', 'Mrs', 'Dr', 'Rev']),
            'first_name' => $firstName,
            'middle_name' => fake()->optional(0.3)->firstName(),
            'last_name' => fake()->lastName(),
            'preferred_name' => fake()->optional(0.15)->firstName(),
            'gender' => $gender,
            'date_of_birth' => $dateOfBirth,
            'marital_status' => fake()->optional(0.8)->randomElement(MaritalStatus::cases()),
            'email' => fake()->optional(0.7)->safeEmail(),
            'phone_primary' => fake()->optional(0.85)->numerify('##########'),
            'phone_secondary' => fake()->optional(0.2)->numerify('##########'),
            'address_line1' => fake()->optional(0.6)->streetAddress(),
            'address_line2' => null,
            'city' => fake()->optional(0.6)->city(),
            'state_province' => fake()->optional(0.5)->state(),
            'postal_code' => fake()->optional(0.5)->postcode(),
            'country' => 'US',
            'photo_path' => null,
            'membership_status' => $this->weightedMembershipStatus(),
            'date_joined' => $dateOfBirth ? fake()->optional(0.7)->dateTimeBetween($dateOfBirth, 'now') : null,
            'date_baptized' => fake()->optional(0.5)->dateTimeBetween('-30 years', 'now'),
            'baptism_type' => fake()->optional(0.5)->randomElement(['water', 'holy_spirit']),
            'occupation' => fake()->optional(0.6)->jobTitle(),
            'employer' => fake()->optional(0.4)->company(),
            'emergency_contact_name' => fake()->optional(0.5)->name(),
            'emergency_contact_phone' => fake()->optional(0.5)->numerify('##########'),
            'emergency_contact_relationship' => fake()->optional(0.5)->randomElement(['Spouse', 'Parent', 'Sibling', 'Child', 'Friend']),
            'custom_fields' => null,
            'created_by' => null,
            'updated_by' => null,
        ];
    }

    /**
     * 80% member, 8% visitor, 5% new_convert, 4% inactive, 2% transferred_out, 1% deceased.
     */
    private function weightedMembershipStatus(): MembershipStatus
    {
        $roll = fake()->numberBetween(1, 100);

        return match (true) {
            $roll <= 80 => MembershipStatus::Member,
            $roll <= 88 => MembershipStatus::Visitor,
            $roll <= 93 => MembershipStatus::NewConvert,
            $roll <= 97 => MembershipStatus::Inactive,
            $roll <= 99 => MembershipStatus::TransferredOut,
            default => MembershipStatus::Deceased,
        };
    }
}
