package user

import (
	"context"
	"strings"

	"hyapp/pkg/xerr"
	userdomain "hyapp/services/user-service/internal/domain/user"
)

const (
	defaultContentBlacklistPageSize int32 = 50
	maxContentBlacklistPageSize     int32 = 200
	maxContentBlacklistReasonRunes        = 255
)

// UserContentBlacklistCommand 是后台增加/移除运营内容屏蔽的治理命令。
// 时间由 user-service owner 生成，不能信任后台进程或客户端传入的时钟。
type UserContentBlacklistCommand struct {
	UserID          int64
	OperatorAdminID int64
	Reason          string
	NowMs           int64
}

// ListUserContentBlacklist 分页读取当前 active 屏蔽用户。
func (s *Service) ListUserContentBlacklist(ctx context.Context, page int32, pageSize int32) ([]userdomain.ContentBlacklistEntry, int64, error) {
	if s.contentBlacklistRepository == nil {
		return nil, 0, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
	}
	if page < 1 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = defaultContentBlacklistPageSize
	}
	if pageSize > maxContentBlacklistPageSize {
		pageSize = maxContentBlacklistPageSize
	}
	return s.contentBlacklistRepository.ListUserContentBlacklist(ctx, page, pageSize)
}

// AdminAddUserContentBlacklist 启用指定用户的运营内容屏蔽。
// 重复添加保持单行当前态并更新操作者和原因，不会把账号状态改成 banned/disabled。
func (s *Service) AdminAddUserContentBlacklist(ctx context.Context, command UserContentBlacklistCommand) (userdomain.ContentBlacklistEntry, error) {
	if s.contentBlacklistRepository == nil {
		return userdomain.ContentBlacklistEntry{}, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
	}
	normalized, err := s.normalizeUserContentBlacklistCommand(command)
	if err != nil {
		return userdomain.ContentBlacklistEntry{}, err
	}
	return s.contentBlacklistRepository.AddUserContentBlacklist(ctx, normalized)
}

// AdminRemoveUserContentBlacklist 关闭指定用户的运营内容屏蔽。
// 已经移除时返回 removed=false，允许后台重试同一个操作而不产生错误。
func (s *Service) AdminRemoveUserContentBlacklist(ctx context.Context, command UserContentBlacklistCommand) (bool, error) {
	if s.contentBlacklistRepository == nil {
		return false, xerr.New(xerr.Unavailable, "content blacklist repository is not configured")
	}
	normalized, err := s.normalizeUserContentBlacklistCommand(command)
	if err != nil {
		return false, err
	}
	return s.contentBlacklistRepository.RemoveUserContentBlacklist(ctx, normalized)
}

func (s *Service) normalizeUserContentBlacklistCommand(command UserContentBlacklistCommand) (UserContentBlacklistCommand, error) {
	if command.UserID <= 0 {
		return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "user_id is required")
	}
	if command.OperatorAdminID <= 0 {
		return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "operator_admin_id is required")
	}
	command.Reason = strings.TrimSpace(command.Reason)
	if len([]rune(command.Reason)) > maxContentBlacklistReasonRunes {
		return UserContentBlacklistCommand{}, xerr.New(xerr.InvalidArgument, "reason is too long")
	}
	// user-service 的 UTC 时钟是持久事实时间源，后台 RequestMeta.sent_at_ms 只用于链路追踪。
	command.NowMs = s.now().UTC().UnixMilli()
	return command, nil
}
