package middleware

import (
	"context"
	"slices"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
)

// EnterpriseStoreInterface 企业存储接口
// 用于权限检查时查询企业信息
type EnterpriseStoreInterface interface {
	GetByID(ctx context.Context, id uint) (*model.Enterprise, error)
	GetByIDs(ctx context.Context, ids []uint) ([]*model.Enterprise, error)
}

// CanManageShop 检查当前用户是否有权管理目标店铺
// 超级管理员和平台用户自动通过（SubordinateShopIDs 为 nil）
// 代理账号只能管理自己店铺及下级店铺
// 企业账号禁止管理店铺
func CanManageShop(ctx context.Context, targetShopID uint) error {
	userType := GetUserTypeFromContext(ctx)

	// 企业账号禁止管理店铺
	if userType == constants.UserTypeEnterprise {
		return errors.New(errors.CodeForbidden, "无权限管理店铺")
	}

	// 从 Context 获取预计算的下级店铺 ID 列表
	subordinateIDs := GetSubordinateShopIDs(ctx)

	// nil 表示不受限制（超级管理员/平台用户）
	if subordinateIDs == nil {
		return nil
	}

	// 检查目标店铺是否在下级列表中
	if slices.Contains(subordinateIDs, targetShopID) {
		return nil
	}

	return errors.New(errors.CodeForbidden, "无权限管理该店铺")
}

// CanManageEnterprise 检查当前用户是否有权管理目标企业
// 超级管理员和平台用户自动通过（SubordinateShopIDs 为 nil）
// 代理账号只能管理归属于自己店铺或下级店铺的企业
// 企业账号禁止管理其他企业
func CanManageEnterprise(ctx context.Context, targetEnterpriseID uint, enterpriseStore EnterpriseStoreInterface) error {
	userType := GetUserTypeFromContext(ctx)

	// 企业账号禁止管理其他企业
	if userType == constants.UserTypeEnterprise {
		return errors.New(errors.CodeForbidden, "无权限管理企业")
	}

	// 从 Context 获取预计算的下级店铺 ID 列表
	subordinateIDs := GetSubordinateShopIDs(ctx)

	// nil 表示不受限制（超级管理员/平台用户）
	if subordinateIDs == nil {
		return nil
	}

	// 获取目标企业信息
	enterprise, err := enterpriseStore.GetByID(ctx, targetEnterpriseID)
	if err != nil {
		return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
	}

	// 代理账号不能管理平台级企业（owner_shop_id 为 NULL）
	if enterprise.OwnerShopID == nil {
		return errors.New(errors.CodeForbidden, "无权限管理平台级企业")
	}

	// 检查企业归属的店铺是否在下级列表中
	if slices.Contains(subordinateIDs, *enterprise.OwnerShopID) {
		return nil
	}

	return errors.New(errors.CodeForbidden, "无权限管理该企业")
}

// ContainsShopID 检查目标店铺 ID 是否在当前用户可管理的店铺列表中
// 平台用户/超管返回 true（不受限制）
// 代理用户检查是否在 SubordinateShopIDs 中
func ContainsShopID(ctx context.Context, targetShopID uint) bool {
	subordinateIDs := GetSubordinateShopIDs(ctx)
	if subordinateIDs == nil {
		return true // 不受限制
	}
	return slices.Contains(subordinateIDs, targetShopID)
}
