<?php

namespace App\Actions\Auth;

use App\Actions\Profile\CreatePlayerProfileOnRegistration;
use App\Enums\UserRole;
use App\Enums\UserStatus;
use App\Models\User;
use App\Services\PhoneNormalizationService;
use App\Support\PublicId;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;

class RegisterUserAction
{
    public function __construct(
        private CreatePlayerProfileOnRegistration $createPlayerProfile,
        private PhoneNormalizationService $phoneNormalizer,
    ) {}

    public function execute(array $data): User
    {
        return DB::transaction(function () use ($data) {
            $phoneData = $this->resolvePhoneData($data);

            $user = User::create([
                'public_id' => PublicId::generate(),
                'name' => $data['display_name'],
                'username' => $data['username'],
                'display_name' => $data['display_name'],
                'email' => $data['email'],
                'email_verified_at' => now(),
                'password' => $data['password'],
                'country_code' => $data['country_code'],
                'preferred_locale' => $data['preferred_locale'],
                'timezone' => $data['timezone'],
                'phone_country_code' => $phoneData['phone_country_code'] ?? null,
                'phone_number' => $phoneData['phone_number'] ?? null,
                'phone_e164' => $phoneData['phone_e164'] ?? null,
                'role' => UserRole::User,
                'status' => UserStatus::Active,
                'terms_accepted_at' => now(),
            ]);

            $this->createPlayerProfile->execute($user, $data);

            return $user;
        });
    }

    private function resolvePhoneData(array $data): array
    {
        if (blank($data['phone'] ?? null)) {
            return [];
        }

        $dialCode = $data['phone_country_code'] ?? null;

        if (blank($dialCode)) {
            throw new InvalidArgumentException(__('validation.phone_invalid'));
        }

        return $this->phoneNormalizer->normalize($dialCode, $data['phone']) ?? [];
    }
}
