<?php

namespace Ignite\Core\Console\Dev;

use Ignite\Core\Contracts\Repositories\ParticipantRepository;
use Ignite\Core\Entities\Group;
use Ignite\Core\Entities\User;
use Ignite\Core\Events\EnrollmentComplete;
use Illuminate\Auth\Events\Registered;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Event;

/**
 * Artisan command to create and register a participant.
 *
 * Usage:
 *   php artisan ignite:dev:create-participant {group} {name} {email} [--type=] [--company=] [--address_1=] ...
 */
class CreateParticipant extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'ignite:dev:create-participant
        {group : The group key (e.g. admin, client)}
        {name : Full name of the participant}
        {email : Email address}
        {--type= : Participant Type}
        {--company= : Company name}
        {--address_1= : Address line 1}
        {--address_2= : Address line 2}
        {--city= : City}
        {--state= : State or province}
        {--postal= : Postal code}
        {--country= : Country code (e.g. US, CA, etc.)}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create and register a participant';

    /**
     * Execute the console command.
     *
     * @return int|void
     */
    public function handle()
    {
        // Get default participant type from config if not provided
        $defaultType = array_values(config('core.participant.types', ['']))[0];
        $type = $this->option('type') ?: $defaultType;

        // Prepare participant data
        $data = [
            'name' => $this->argument('name'),
            'email' => $this->argument('email'),
            'type' => $type,
            'company' => $this->option('company') ?? '',
            'address_1' => $this->option('address_1') ?? '',
            'address_2' => $this->option('address_2') ?? '',
            'city' => $this->option('city') ?? '',
            'state' => $this->option('state') ?? '',
            'postal' => $this->option('postal') ?? '',
            'country' => $this->option('country') ?? '',
            // Use fixed, obviously fake SSN for testing purposes
            'ssn' => encrypt('111-222-3333'),
        ];

        $this->createParticipant($this->argument('group'), $data);
    }

    /**
     * Create a participant and assign to group.
     *
     * @param string $groupName The group key.
     * @param array $data Participant data.
     * @return mixed Participant entity or null.
     */
    protected function createParticipant(string $groupName, array $data)
    {
        if (empty($data['email'])) {
            return null;
        }

        $participantRepo = resolve(ParticipantRepository::class);

        // Check if participant already exists by email
        $participant = $participantRepo->findByEmail($data['email']);
        if (!$participant) {
            // Split name into first and last
            $name = trim($data['name']);
            $nameParts = preg_split('/\s+/', $name, -1, PREG_SPLIT_NO_EMPTY);
            if (count($nameParts) > 1) {
                $data['first'] = implode(' ', array_slice($nameParts, 0, -1));
                $data['last'] = $nameParts[count($nameParts) - 1];
            } else {
                $data['first'] = $name;
                $data['last'] = '';
            }
            unset($data['name']);

            // Create participant
            $participant = $participantRepo->create(array_merge($data, [
                'internal' => User::TYPE_INTERNAL,
            ]));

            // Assign group to user
            $group = Group::query()->where('key', $groupName)->first();
            if ($group) {
                $participant->user->groups()->attach($group->getKey());
            }

            // Dispatch Registered and EnrollmentComplete events
            Event::dispatch(new Registered($participant->user));
            Event::dispatch(new EnrollmentComplete($participant->user));

            $this->info("Participant '{$participant->user->email}' registered and email sent.");
        } else {
            $this->warn("Participant already exists.");
        }

        return $participant;
    }
}
