package service

import (
	"hyapp/pkg/xerr"
	"hyapp/services/room-service/internal/room/state"
)

// roomRole 是权限矩阵内部使用的收敛角色，不直接信任客户端 JoinRoom.role。
type roomRole string

const (
	// roleOwner 来自 RoomState.OwnerUserID，拥有房间内最高管理权限。
	roleOwner roomRole = "owner"
	// roleAdmin 来自 RoomState.AdminUsers，权限低于 owner。
	roleAdmin roomRole = "admin"
	// roleAudience 是默认兜底角色，包含未登录、未在房间和普通观众。
	roleAudience roomRole = "audience"
)

func actorRole(current *state.RoomState, actorUserID int64) roomRole {
	// 角色权威顺序按当前房间状态固定：owner > admin > audience，不能只看 RoomUser.role 展示字段。
	switch {
	case current == nil || actorUserID <= 0:
		return roleAudience
	case actorUserID == current.OwnerUserID:
		return roleOwner
	case current.AdminUsers[actorUserID]:
		return roleAdmin
	default:
		return roleAudience
	}
}

func requireActiveRoom(current *state.RoomState) error {
	// 当前只有 active 房间可执行管理和麦位命令；CloseRoom 语义后续单独扩展。
	if current == nil || current.Status != state.RoomStatusActive {
		return xerr.New(xerr.Conflict, "room is not active")
	}
	return nil
}

func requireActorPresent(current *state.RoomState, actorUserID int64) error {
	// 管理动作必须来自房间业务 presence；离房后的 admin 不能远程管理房间。
	if _, exists := current.OnlineUsers[actorUserID]; !exists {
		return xerr.New(xerr.PermissionDenied, "permission denied")
	}
	return nil
}

func requireManagerPresent(current *state.RoomState, actorUserID int64) error {
	// 先校验 presence，再校验角色，避免房间外用户凭持久 admin 身份直接操作。
	if err := requireActorPresent(current, actorUserID); err != nil {
		return err
	}
	if !isManagerRole(actorRole(current, actorUserID)) {
		return xerr.New(xerr.PermissionDenied, "permission denied")
	}
	return nil
}

func isManagerRole(role roomRole) bool {
	// 管理角色集合只包含 owner/admin，普通观众只能做自助动作。
	return role == roleOwner || role == roleAdmin
}

func canManageTarget(current *state.RoomState, actorUserID int64, targetUserID int64) error {
	// 目标用户同样按权威状态判定角色，防止客户端伪造 role 绕过管理层级。
	actor := actorRole(current, actorUserID)
	target := actorRole(current, targetUserID)
	if !isManagerRole(actor) {
		return xerr.New(xerr.PermissionDenied, "permission denied")
	}
	if target == roleOwner && actor != roleOwner {
		// admin 不能管理 owner，owner 自操作由具体命令的 self check 再收紧。
		return xerr.New(xerr.PermissionDenied, "permission denied")
	}
	return nil
}

func canSelfOrManageTarget(current *state.RoomState, actorUserID int64, targetUserID int64) error {
	// 自助动作例如自己下麦允许 audience 执行，代操作才进入管理权限矩阵。
	if actorUserID == targetUserID {
		return nil
	}
	return canManageTarget(current, actorUserID, targetUserID)
}

func requireOwnerPresent(current *state.RoomState, actorUserID int64) error {
	// owner 专属命令仍要求 owner 当前在房间业务 presence 内。
	if err := requireActorPresent(current, actorUserID); err != nil {
		return err
	}
	if actorRole(current, actorUserID) != roleOwner {
		return xerr.New(xerr.PermissionDenied, "permission denied")
	}
	return nil
}
