package service

import (
	"context"
	"fmt"
	"strings"

	"oci-portal/internal/oci"
)

// RegionSubscriptionView 在云端订阅信息之上补充本地维护的友好名称。
type RegionSubscriptionView struct {
	oci.RegionSubscription
	Alias string `json:"alias"`
}

// RegionSubscriptions 返回租户已订阅的区域列表（订阅 Tab 使用 SDK 实时数据）；
// 开启多区域支持时与缓存比对，有差异即入库，保持缓存跟随真实状态。
func (s *OciConfigService) RegionSubscriptions(ctx context.Context, id uint) ([]RegionSubscriptionView, error) {
	cfg, err := s.Get(ctx, id)
	if err != nil {
		return nil, err
	}
	cred, err := s.credentialsOf(cfg)
	if err != nil {
		return nil, err
	}
	subs, err := s.client.ListRegionSubscriptions(ctx, cred)
	if err != nil {
		return nil, err
	}
	if cfg.MultiRegion {
		s.reconcileRegionCache(ctx, cfg.ID, subs)
	}
	return enrichRegionAlias(subs), nil
}

// SubscribeRegion 为租户订阅新区域并返回最新订阅列表。
// OCI 区域订阅一经创建不可取消。
func (s *OciConfigService) SubscribeRegion(ctx context.Context, id uint, regionKey string) ([]RegionSubscriptionView, error) {
	regionKey = strings.ToUpper(strings.TrimSpace(regionKey))
	if regionKey == "" {
		return nil, fmt.Errorf("subscribe region: region key is empty")
	}
	cfg, err := s.Get(ctx, id)
	if err != nil {
		return nil, err
	}
	cred, err := s.credentialsOf(cfg)
	if err != nil {
		return nil, err
	}
	// 订阅请求必须发往 home region；本地表查不到时退回配置默认区域
	if err := s.client.SubscribeRegion(ctx, cred, homeRegionOf(cfg), regionKey); err != nil {
		return nil, err
	}
	subs, err := s.client.ListRegionSubscriptions(ctx, cred)
	if err != nil {
		return nil, err
	}
	// 订阅成功入库（新区域 IN_PROGRESS 状态随缓存读取持续刷新直到 READY）
	if cfg.MultiRegion {
		_ = s.saveRegionCache(ctx, cfg.ID, subs)
	}
	return enrichRegionAlias(subs), nil
}

// Limits 查询租户在指定区域、服务下的配额。
func (s *OciConfigService) Limits(ctx context.Context, id uint, q oci.LimitsQuery) ([]oci.LimitValue, error) {
	if q.Service == "" {
		return nil, fmt.Errorf("list limits: service is empty")
	}
	cfg, err := s.Get(ctx, id)
	if err != nil {
		return nil, err
	}
	cred, err := s.credentialsOf(cfg)
	if err != nil {
		return nil, err
	}
	return s.client.ListLimits(ctx, cred, q)
}

func enrichRegionAlias(subs []oci.RegionSubscription) []RegionSubscriptionView {
	views := make([]RegionSubscriptionView, 0, len(subs))
	for _, sub := range subs {
		view := RegionSubscriptionView{RegionSubscription: sub}
		if info, ok := oci.RegionByKey(sub.Key); ok {
			view.Alias = info.Alias
		}
		views = append(views, view)
	}
	return views
}
