<?php

namespace App\Services;

use App\Apps\CmsproChildrehab\Models\AdminUserHospital;
use App\Http\Responses\ApiResponse;
use App\Models\AdminRole;
use App\Models\AdminUser;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class UserService
{
    public function index(array $params)
    {
        $query = AdminUser::query();

        // 层级权限过滤：非超权账号只能看到可管辖角色范围内的账号
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            $manageableRoleIds = $this->getManageableRoleIds($currentUser);
            if (empty($manageableRoleIds)) {
                // 无可管辖角色，返回空分页
                return ApiResponse::paginate(collect()->paginate($params['per_page'] ?? config('cmspro.pagination.per_page', 15)));
            }
            $query->whereHas('roles', function ($q) use ($manageableRoleIds) {
                $q->whereIn('admin_roles.id', $manageableRoleIds);
            });
        }

        if (isset($params['keyword']) && ! empty($params['keyword'])) {
            $query->where(function ($q) use ($params) {
                $q->where('username', 'like', "%{$params['keyword']}%")
                    ->orWhere('name', 'like', "%{$params['keyword']}%")
                    ->orWhere('email', 'like', "%{$params['keyword']}%");
            });
        }

        if (isset($params['status']) && $params['status'] !== '') {
            $query->where('status', $params['status']);
        }

        if (isset($params['role_id']) && !empty($params['role_id'])) {
            $query->whereHas('roles', function ($q) use ($params) {
                $q->where('admin_roles.id', $params['role_id']);
            });
        }

        $perPage = $params['per_page'] ?? config('cmspro.pagination.per_page', 15);
        $users = $query->with('roles')->orderBy('id', 'desc')->paginate($perPage);

        return ApiResponse::paginate($users);
    }

    public function store(array $data)
    {
        $user = AdminUser::create([
            'username' => $data['username'],
            'password' => Hash::make($data['password']),
            'name' => $data['name'],
            'email' => $data['email'] ?? null,
            'phone' => $data['phone'] ?? null,
            'avatar' => $data['avatar'] ?? null,
            'status' => $data['status'] ?? 1,
        ]);

        if (isset($data['role_id']) && ! empty($data['role_id'])) {
            $user->roles()->sync([$data['role_id']]);
        }

        // 保存扩展数据
        if (isset($data['ext_fields']) && is_array($data['ext_fields'])) {
            app(UserExtFieldService::class)->saveAdminUserExtData($user->id, $data['ext_fields']);
            // 同步医院绑定到关联表
            $this->syncHospitalBindings($user->id, $data['ext_fields']);
        }

        return ApiResponse::success($user, '创建成功');
    }

    public function show(int $id)
    {
        $user = AdminUser::with('roles')->find($id);

        if (! $user) {
            return ApiResponse::error(40302, '用户不存在');
        }

        // 附加扩展数据
        $extService = app(UserExtFieldService::class);
        $user->ext_fields = $extService->getAdminUserExtData($id);

        return ApiResponse::success($user);
    }

    public function update(int $id, array $data)
    {
        $user = AdminUser::find($id);

        if (! $user) {
            return ApiResponse::error(40302, '用户不存在');
        }

        // 层级权限校验：非超权账号只能编辑可管辖范围内的账号
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            if (! $this->canManageUser($currentUser, $user)) {
                return ApiResponse::error(40303, '无权编辑该用户（超出管辖范围）');
            }
        }

        $updateData = [
            'name' => $data['name'],
            'email' => $data['email'] ?? null,
            'phone' => $data['phone'] ?? null,
            'avatar' => $data['avatar'] ?? null,
        ];

        if (isset($data['password']) && ! empty($data['password'])) {
            $updateData['password'] = Hash::make($data['password']);
        }

        $user->update($updateData);

        if (isset($data['role_id'])) {
            $user->roles()->sync([$data['role_id']]);
        }

        // 保存扩展数据
        if (isset($data['ext_fields']) && is_array($data['ext_fields'])) {
            app(UserExtFieldService::class)->saveAdminUserExtData($id, $data['ext_fields']);
            // 同步医院绑定到关联表
            $this->syncHospitalBindings($id, $data['ext_fields']);
        }

        return ApiResponse::success($user, '更新成功');
    }

    public function destroy(int $id)
    {
        $user = AdminUser::find($id);

        if (! $user) {
            return ApiResponse::error(40302, '用户不存在');
        }

        if ($user->id === auth('admin')->id()) {
            return ApiResponse::error(40303, '不能删除当前登录用户');
        }

        if ($user->isSuperAdmin()) {
            return ApiResponse::error(40303, '不能删除超级管理员');
        }

        // 层级权限校验：非超权账号只能删除可管辖范围内的账号
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            if (! $this->canManageUser($currentUser, $user)) {
                return ApiResponse::error(40303, '无权删除该用户（超出管辖范围）');
            }
        }

        $user->roles()->detach();
        $user->delete();

        return ApiResponse::success(null, '删除成功');
    }

    public function updateStatus(int $id, int $status)
    {
        $user = AdminUser::find($id);

        if (! $user) {
            return ApiResponse::error(40302, '用户不存在');
        }

        if ($user->id === auth('admin')->id() && $status === 0) {
            return ApiResponse::error(40303, '不能禁用当前登录用户');
        }

        // 层级权限校验：非超权账号只能操作可管辖范围内的账号
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            if (! $this->canManageUser($currentUser, $user)) {
                return ApiResponse::error(40303, '无权操作该用户（超出管辖范围）');
            }
        }

        $user->update(['status' => $status]);

        return ApiResponse::success($user, $status === 1 ? '启用成功' : '禁用成功');
    }

    public function resetPassword(int $id, string $password)
    {
        $user = AdminUser::find($id);

        if (! $user) {
            return ApiResponse::error(40302, '用户不存在');
        }

        // 层级权限校验：非超权账号只能重置可管辖范围内的账号密码
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            if (! $this->canManageUser($currentUser, $user)) {
                return ApiResponse::error(40303, '无权重置该用户密码（超出管辖范围）');
            }
        }

        $user->update([
            'password' => Hash::make($password),
            'password_changed_at' => now(),
        ]);

        return ApiResponse::success(null, '重置密码成功');
    }

    public function all()
    {
        $users = AdminUser::where('status', 1)
            ->orderBy('id', 'desc')
            ->get(['id', 'username', 'name']);

        return ApiResponse::success($users);
    }

    public function batchDelete(array $ids)
    {
        $currentUserId = auth('admin')->id();

        if (in_array($currentUserId, $ids)) {
            return ApiResponse::error(40303, '不能删除当前登录用户');
        }

        $superAdminIds = AdminUser::whereIn('id', $ids)
            ->whereHas('roles', function ($query) {
                $query->where('code', 'super_admin');
            })
            ->pluck('id')
            ->toArray();

        if (! empty($superAdminIds)) {
            return ApiResponse::error(40303, '不能删除超级管理员');
        }

        // 层级权限校验：非超权账号只能删除可管辖范围内的账号
        $currentUser = auth('admin')->user();
        if ($currentUser && ! $this->isSuperPrivileged($currentUser)) {
            $unmanageableUsers = AdminUser::whereIn('id', $ids)->get()
                ->filter(function ($user) use ($currentUser) {
                    return ! $this->canManageUser($currentUser, $user);
                });
            if ($unmanageableUsers->isNotEmpty()) {
                return ApiResponse::error(40303, '存在超出管辖范围的用户，无法删除');
            }
        }

        DB::transaction(function () use ($ids) {
            $users = AdminUser::whereIn('id', $ids)->get();
            foreach ($users as $user) {
                $user->roles()->detach();
                $user->delete();
            }
        });

        return ApiResponse::success(null, '批量删除成功');
    }

    /**
     * 同步医院绑定到 admin_user_hospitals 关联表
     *
     * 当 ext_fields 中包含 hospital_id 时，将其同步到关联表，
     * 确保用户表单和医院管理页面的绑定数据一致。
     *
     * @param int $adminUserId
     * @param array $extFields
     */
    protected function syncHospitalBindings(int $adminUserId, array $extFields): void
    {
        if (!isset($extFields['hospital_id'])) {
            return;
        }

        $hospitalIds = $extFields['hospital_id'];
        if (!is_array($hospitalIds)) {
            $hospitalIds = $hospitalIds ? [$hospitalIds] : [];
        }

        // 过滤无效值
        $hospitalIds = array_filter(array_map('intval', $hospitalIds), function ($id) {
            return $id > 0;
        });

        // 删除旧的绑定
        AdminUserHospital::where('admin_user_id', $adminUserId)->delete();

        // 插入新绑定
        if (!empty($hospitalIds)) {
            $now = now();
            $rows = [];
            foreach ($hospitalIds as $hospitalId) {
                $rows[] = [
                    'admin_user_id' => $adminUserId,
                    'hospital_id' => $hospitalId,
                    'create_time' => $now,
                    'update_time' => $now,
                ];
            }
            AdminUserHospital::insertOrIgnore($rows);
        }
    }

    // ============ 层级权限辅助方法（与 RoleService 对齐） ============

    /**
     * 判断当前用户是否为超权账号（不受任何限制）
     * 双重保护：
     *   1. id=1 的安装账号（防止 super_admin 角色被误操作后还能兜底）
     *   2. 拥有 super_admin 角色的用户（正常业务场景）
     */
    private function isSuperPrivileged(AdminUser $user): bool
    {
        return $user->id === 1 || $user->isSuperAdmin();
    }

    /**
     * 获取指定角色分支下的所有子角色ID（递归）
     */
    private function getSubRoleIds(int $roleId): array
    {
        $ids = [];
        $children = AdminRole::where('parent_id', $roleId)->pluck('id');
        foreach ($children as $childId) {
            $ids[] = $childId;
            $ids = array_merge($ids, $this->getSubRoleIds($childId));
        }
        return $ids;
    }

    /**
     * 获取指定角色的完整分支ID列表（自身 + 所有子孙）
     */
    private function getBranchRoleIds(int $roleId): array
    {
        return array_merge([$roleId], $this->getSubRoleIds($roleId));
    }

    /**
     * 获取非超权用户可管辖的角色ID列表（自身角色 + 其所有子孙分支）
     *
     * 注：public 以供 UserResource 计算 can_manage 字段复用
     */
    public function getManageableRoleIds(AdminUser $user): array
    {
        $userRoles = $user->roles;
        $manageableIds = [];
        foreach ($userRoles as $role) {
            $manageableIds = array_merge($manageableIds, $this->getBranchRoleIds($role->id));
        }
        return array_unique($manageableIds);
    }

    /**
     * 判断当前用户是否可以管理目标用户
     *
     * 规则：目标用户必须拥有至少一个在当前用户可管辖范围内的角色
     *
     * @param AdminUser $currentUser 当前登录用户
     * @param AdminUser $targetUser  目标用户
     */
    private function canManageUser(AdminUser $currentUser, AdminUser $targetUser): bool
    {
        $manageableRoleIds = $this->getManageableRoleIds($currentUser);
        if (empty($manageableRoleIds)) {
            return false;
        }

        // 目标用户拥有至少一个可管辖角色即视为可管理
        return $targetUser->roles()
            ->whereIn('admin_roles.id', $manageableRoleIds)
            ->exists();
    }
}
