package v1

import (
	"context"
	"fmt"
	"time"

	"github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud"
	aclioudprovider "github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/alicloud"
	awsprovider "github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/aws"
	azureprovider "github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/azure"
	gcpprovider "github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/gcp"

	"google.golang.org/api/cloudresourcemanager/v1"

	"github.com/pingcap-inc/pchub/internal/apiserver/store"

	modelv1 "github.com/pingcap-inc/pchub/model/v1"
	"github.com/pingcap-inc/pchub/pkg/log"
)

type resourceManagerService struct {
	store store.Factory
}

type ResourceManagerSrv interface {
	SyncToCloud(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error
	SyncCloudMember(ctx context.Context) error
}

var _ ResourceManagerSrv = (*resourceManagerService)(nil)

func newResourceManager(srv *service) *resourceManagerService {
	return &resourceManagerService{store: srv.store}
}

func (r *resourceManagerService) GetGoogleClient(ctx context.Context) (*cloudresourcemanager.Service, error) {
	// 使用新的云平台架构
	gcpProvider, err := gcpprovider.NewProviderWithStore(r.store)
	if err != nil {
		return nil, fmt.Errorf("failed to create GCP provider with store: %w", err)
	}

	return gcpProvider.GetGoogleClient(ctx)
}

type AWSToken struct {
	AccessKeyId     string    `json:"accessKeyId"`
	SecretAccessKey string    `json:"secretAccessKey"`
	SessionToken    string    `json:"sessionToken"`
	Expiration      time.Time `json:"expiration"`
}

func (r *resourceManagerService) SyncToCloud(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error {
	log.L(ctx).Info("start sync to cloud")

	// 创建云平台工厂
	factory := cloud.NewFactory()

	// 创建对应的云平台提供者
	provider, err := factory.CreateProvider(cloudResource.Provider.Code)
	if err != nil {
		return fmt.Errorf("failed to create cloud provider: %w", err)
	}

	// 执行同步
	if err := provider.SyncUserRoles(ctx, roles, cloudResource, optionType); err != nil {
		return fmt.Errorf("failed to sync to %s: %w", provider.GetProviderName(), err)
	}

	log.L(ctx).Infof("Sync to cloud: %s success", cloudResource.Provider.Name)
	return nil
}

func (r *resourceManagerService) SyncCloudMember(ctx context.Context) error {
	log.L(ctx).Info("start sync cloud member")

	// 同步GCP成员
	gcpProvider, err := gcpprovider.NewProviderWithStore(r.store)
	if err != nil {
		log.L(ctx).Error("failed to create GCP provider:" + err.Error())
		return err
	}
	if err := gcpProvider.SyncMembers(ctx); err != nil {
		log.L(ctx).Error("sync gcp member failed:" + err.Error())
		return err
	}
	//
	//// 同步AWS成员
	awsProvider, err := awsprovider.NewProviderWithStore(r.store)
	if err != nil {
		log.L(ctx).Error("failed to create AWS provider:" + err.Error())
		return err
	}
	if err := awsProvider.SyncMembers(ctx); err != nil {
		log.L(ctx).Error("sync aws member failed:" + err.Error())
		return err
	}

	// 同步Azure成员
	azureProvider, err := azureprovider.NewProviderWithStore(r.store)
	if err != nil {
		log.L(ctx).Error("failed to create Azure provider:" + err.Error())
		return err
	}
	if err := azureProvider.SyncMembers(ctx); err != nil {
		log.L(ctx).Error("sync azure member failed:" + err.Error())
		return err
	}

	// 同步Alicloud成员
	alicloudProvider, err := aclioudprovider.NewProviderWithStore(r.store)
	if err != nil {
		log.L(ctx).Error("failed to create Alicloud provider:" + err.Error())
		return err
	}
	if err := alicloudProvider.SyncMembers(ctx); err != nil {
		log.L(ctx).Error("sync alicloud member failed:" + err.Error())
		return err
	}

	log.L(ctx).Info("sync cloud member success")
	return nil
}
