package appconfig

import (
	"errors"
	"strings"

	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/model"

	"gorm.io/gorm"
)

const (
	roomDiscoveryGroup                 = "room-discovery"
	roomDiscoveryScopeKey              = "scope"
	roomDiscoveryScopeViewerRegion     = "viewer_region"
	roomDiscoveryScopeAllActiveRegions = "all_active_regions"
	roomDiscoveryDescription           = "房间发现范围：viewer_region 或 all_active_regions"
)

type RoomDiscoveryConfig struct {
	AppCode     string `json:"appCode"`
	Scope       string `json:"scope"`
	UpdatedAtMS int64  `json:"updatedAtMs"`
}

func (s *AppConfigService) GetRoomDiscoveryConfig(appCode string) (RoomDiscoveryConfig, error) {
	appCode = appctx.Normalize(appCode)
	item, err := s.store.GetOwnedAppConfig(appCode, roomDiscoveryGroup, roomDiscoveryScopeKey)
	if errors.Is(err, gorm.ErrRecordNotFound) {
		// 未配置时只允许查看者所属区域；这是跨区域数据暴露的 fail-closed 边界，后台保存后才扩大范围。
		return RoomDiscoveryConfig{AppCode: appCode, Scope: roomDiscoveryScopeViewerRegion}, nil
	}
	if err != nil {
		return RoomDiscoveryConfig{}, err
	}
	return roomDiscoveryConfigFromModel(item), nil
}

func (s *AppConfigService) UpdateRoomDiscoveryConfig(appCode string, request roomDiscoveryConfigRequest) (RoomDiscoveryConfig, error) {
	item, err := roomDiscoveryConfigModel(appCode, request)
	if err != nil {
		return RoomDiscoveryConfig{}, err
	}
	// App 作用域只来自鉴权上下文；请求体不能指定 app_code，也不能覆盖其他租户的同名配置。
	if err := s.store.UpsertScopedAppConfigs(item.AppCode, []model.AppConfig{item}); err != nil {
		return RoomDiscoveryConfig{}, err
	}
	stored, err := s.store.GetOwnedAppConfig(item.AppCode, roomDiscoveryGroup, roomDiscoveryScopeKey)
	if err != nil {
		return RoomDiscoveryConfig{}, err
	}
	return roomDiscoveryConfigFromModel(stored), nil
}

func roomDiscoveryConfigModel(appCode string, request roomDiscoveryConfigRequest) (model.AppConfig, error) {
	scope := strings.ToLower(strings.TrimSpace(request.Scope))
	if scope != roomDiscoveryScopeViewerRegion && scope != roomDiscoveryScopeAllActiveRegions {
		return model.AppConfig{}, errors.New("房间发现范围不正确")
	}
	return model.AppConfig{
		AppCode:     appctx.Normalize(appCode),
		Group:       roomDiscoveryGroup,
		Key:         roomDiscoveryScopeKey,
		Value:       scope,
		Description: roomDiscoveryDescription,
	}, nil
}

func roomDiscoveryConfigFromModel(item model.AppConfig) RoomDiscoveryConfig {
	scope := strings.ToLower(strings.TrimSpace(item.Value))
	if scope != roomDiscoveryScopeViewerRegion && scope != roomDiscoveryScopeAllActiveRegions {
		// 旧 SQL 或人工写入的非法值不能突破 API 枚举契约；与 gateway 保持一致，统一降级到查看者区域。
		scope = roomDiscoveryScopeViewerRegion
	}
	return RoomDiscoveryConfig{
		AppCode:     appctx.Normalize(item.AppCode),
		Scope:       scope,
		UpdatedAtMS: item.UpdatedAtMS,
	}
}
