<?php

declare(strict_types=1);

namespace App\Services;

use App\Enums\AccountStatus;
use App\Enums\OrganizerPrimaryEventType;
use App\Models\Organizer;
use App\Models\Role;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

final class DashboardUserProvisioningService
{
    public function __construct(private readonly AuditLogger $auditLogger) {}

    /**
     * Crea un usuario desde el panel. Si el rol es organizador, también crea el registro {@see Organizer}
     * y deja la cuenta en estado aprobado (alta manual por staff).
     */
    public function createStaffUser(
        User $actor,
        string $name,
        string $email,
        string $passwordPlain,
        Role $role,
        ?string $organizationName,
        ?string $phone,
        ?OrganizerPrimaryEventType $primaryEventType,
        string $auditSummaryKey = 'user.created_staff',
    ): User {
        $this->assertActorCanAssignRole($actor, $role);

        return DB::transaction(function () use (
            $actor,
            $name,
            $email,
            $passwordPlain,
            $role,
            $organizationName,
            $phone,
            $primaryEventType,
            $auditSummaryKey,
        ): User {
            $isOrganizer = $role->slug === Role::SLUG_ORGANIZADOR;

            $user = User::query()->create([
                'name' => $name,
                'email' => $email,
                'password' => Hash::make($passwordPlain),
                'role_id' => $role->id,
                'account_status' => AccountStatus::Approved,
                'organization_name' => $isOrganizer ? $organizationName : null,
                'phone' => $isOrganizer ? ($phone ?? '') : null,
                'rejection_reason' => null,
            ]);

            if ($isOrganizer) {
                Organizer::query()->create([
                    'user_id' => $user->id,
                    'primary_event_type' => $primaryEventType ?? OrganizerPrimaryEventType::Other,
                ]);
            }

            $this->auditLogger->log(
                $auditSummaryKey,
                'users',
                __('Usuario creado desde el panel: :email', ['email' => $user->email]),
                [
                    'created_user_id' => $user->id,
                    'role_slug' => $role->slug,
                    'actor_id' => $actor->id,
                ],
                subject: $user,
                userId: $actor->id,
            );

            return $user;
        });
    }

    private function assertActorCanAssignRole(User $actor, Role $role): void
    {
        if (! $actor->hasRole(Role::SLUG_SUPER_ADMIN) && ! $actor->hasRole(Role::SLUG_ADMINISTRADOR)) {
            abort(403);
        }

        if ($role->slug === Role::SLUG_SUPER_ADMIN && ! $actor->hasRole(Role::SLUG_SUPER_ADMIN)) {
            abort(403, __('Solo un super administrador puede crear cuentas con ese rol.'));
        }
    }
}
