<?php

namespace App\Services;

use App\Helpers\TenantCodeGenerator;
use App\Models\Commons\Menu;
use App\Models\Members\User;
use App\Models\Members\UserTenant;
use App\Models\Tenants\Tenant;
use App\Models\Tenants\TenantUserProfile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;

class RegisterService
{
    /**
     * 회원가입 처리 (테넌트 생성 + 사용자 생성 + 시스템 관리자 역할 부여)
     *
     * @param  array  $params  [
     *                         'user_id' => string,
     *                         'name' => string,
     *                         'email' => string,
     *                         'phone' => string,
     *                         'password' => string,
     *                         'position' => string (optional),
     *                         'company_name' => string,
     *                         'business_num' => string (optional),
     *                         'company_scale' => string (optional),
     *                         'industry' => string (optional),
     *                         ]
     * @return array ['user' => array, 'tenant' => array, 'menus' => array, 'roles' => array]
     */
    public static function register(array $params): array
    {
        return DB::transaction(function () use ($params) {
            // 1. Generate unique tenant code from company name
            $code = TenantCodeGenerator::generate($params['company_name']);

            // 2. Create Tenant with trial status and options
            $tenant = Tenant::create([
                'company_name' => $params['company_name'],
                'code' => $code,
                'business_num' => $params['business_num'] ?? null,
                'tenant_st_code' => 'trial', // 트라이얼 상태
                'options' => [
                    'company_scale' => $params['company_scale'] ?? null,
                    'industry' => $params['industry'] ?? null,
                ],
            ]);

            // 3. Clone global menu template for tenant
            $menuIds = MenuBootstrapService::cloneGlobalMenusForTenant($tenant->id);

            // 4. Create User with hashed password and options
            $user = User::create([
                'user_id' => $params['user_id'],
                'name' => $params['name'],
                'email' => $params['email'],
                'phone' => $params['phone'] ?? null,
                'password' => Hash::make($params['password']),
                'options' => [
                    'position' => $params['position'] ?? null,
                ],
            ]);

            // 5. Create TenantUserProfile (tenant-user profile mapping)
            TenantUserProfile::create([
                'user_id' => $user->id,
                'tenant_id' => $tenant->id,
                'is_default' => 1, // 기본 테넌트로 설정
                'is_active' => 1, // 활성화
            ]);

            // 5-1. Create UserTenant (tenant-user access mapping)
            UserTenant::create([
                'user_id' => $user->id,
                'tenant_id' => $tenant->id,
                'is_default' => 1, // 기본 테넌트로 설정
                'is_active' => 1, // 활성화
                'joined_at' => now(), // 가입 시각
            ]);

            // 6. Set tenant context for permissions
            app()->bind('tenant_id', fn () => $tenant->id);
            app(PermissionRegistrar::class)->setPermissionsTeamId($tenant->id);

            // 7. Create 'system_manager' role
            $role = Role::create([
                'tenant_id' => $tenant->id,
                'guard_name' => 'api',
                'name' => 'system_manager',
                'description' => '시스템 관리자',
            ]);

            // 8. Get all permissions created by MenuObserver (menu:{id}.{action} pattern)
            $permissionNames = [];
            $actions = config('authz.menu_actions', ['view', 'create', 'update', 'delete', 'approve']);

            foreach ($menuIds as $menuId) {
                foreach ($actions as $action) {
                    $permissionNames[] = "menu:{$menuId}.{$action}";
                }
            }

            $permissions = Permission::whereIn('name', $permissionNames)
                ->where('tenant_id', $tenant->id)
                ->where('guard_name', 'api')
                ->get();

            // 9. Assign all menu permissions to system_manager role
            $role->syncPermissions($permissions);

            // 10. Assign system_manager role to user
            $user->assignRole($role);

            // 11. Get created menus
            $menus = Menu::whereIn('id', $menuIds)
                ->orderBy('parent_id')
                ->orderBy('sort_order')
                ->get(['id', 'parent_id', 'name', 'url', 'icon', 'sort_order', 'is_external', 'external_url'])
                ->toArray();

            // 12. Return user, tenant, menus, and roles data
            return [
                'user' => [
                    'id' => $user->id,
                    'user_id' => $user->user_id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'phone' => $user->phone,
                    'options' => $user->options,
                ],
                'tenant' => [
                    'id' => $tenant->id,
                    'company_name' => $tenant->company_name,
                    'business_num' => $tenant->business_num,
                    'tenant_st_code' => $tenant->tenant_st_code,
                    'options' => $tenant->options,
                ],
                'menus' => $menus,
                'roles' => [
                    [
                        'id' => $role->id,
                        'name' => $role->name,
                        'description' => $role->description,
                    ],
                ],
            ];
        });
    }
}
