<?php

namespace App\Actions\Fortify;

use App\Concerns\PasswordValidationRules;
use App\Concerns\ProfileValidationRules;
use App\Enums\UserKycStatus;
use App\Models\User;
use App\Services\AdminEventNotifier;
use App\Support\MaintenanceMode;
use App\Support\TurnstileVerifier;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\CreatesNewUsers;

class CreateNewUser implements CreatesNewUsers
{
    use PasswordValidationRules, ProfileValidationRules;

    /**
     * Validate and create a newly registered user.
     *
     * @param  array<string, string>  $input
     */
    public function create(array $input): User
    {
        if (MaintenanceMode::enabled()) {
            throw ValidationException::withMessages([
                'email' => ['El registro no está disponible mientras la plataforma está en mantenimiento.'],
            ]);
        }

        TurnstileVerifier::assertValidFromInput($input, request()->ip());

        $input['referral_code'] = self::normalizeReferralCode($input['referral_code'] ?? null);

        Validator::make($input, [
            ...$this->profileRules(),
            'referral_code' => [
                'nullable',
                'string',
                'max:255',
                Rule::exists('users', 'referral_code')->where(static fn ($q) => $q->where('referral_program_enabled', true)),
            ],
            'password' => $this->passwordRules(),
        ])->validate();

        $user = DB::transaction(function () use ($input): User {
            $isFirstUserEver = ! User::query()->exists();
            $referrer = filled($input['referral_code'] ?? null)
                ? User::query()->where('referral_code', $input['referral_code'])->first()
                : null;

            return User::create([
                'first_name' => $input['first_name'],
                'last_name' => $input['last_name'],
                'email' => $input['email'],
                'contact_number' => $input['contact_number'],
                'country' => $input['country'],
                'password' => $input['password'],
                'is_admin' => $isFirstUserEver,
                'referral_program_enabled' => false,
                'referred_by_user_id' => $isFirstUserEver ? null : $referrer?->id,
                'kyc_status' => $isFirstUserEver
                    ? UserKycStatus::Approved
                    : UserKycStatus::RequiresSubmission,
                'kyc_rejection_reason' => null,
            ]);
        });

        app(AdminEventNotifier::class)->notifyNewUser($user);

        return $user;
    }

    private static function normalizeReferralCode(mixed $value): ?string
    {
        if (! is_string($value) || trim($value) === '') {
            return null;
        }

        $value = trim($value);

        if (filter_var($value, FILTER_VALIDATE_URL)) {
            parse_str((string) parse_url($value, PHP_URL_QUERY), $query);
            $value = is_string($query['ref'] ?? null) ? $query['ref'] : $value;
        }

        return strtoupper(trim($value));
    }
}
