package k8sresource

import (
	"context"
	"fmt"

	"github.com/go-logr/logr"
	k8sresourceent "github.com/tidbcloud/devops/entity/k8sresource"
	"github.com/tidbcloud/devops/pkg/infra/clients/metadbcli"
	"github.com/tidbcloud/devops/pkg/infra/clients/mgmthttpcli"
	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/service"
	"go.uber.org/dig"

	clusterserver "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"
	regionalv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
)

type ServiceParam struct {
	dig.In

	Conf      *config.RootConfig
	Logger    logr.Logger
	MgmtHTTP  mgmthttpcli.MgmtHTTPClient
	MetadbCli metadbcli.Client
}

type ServiceResult struct {
	dig.Out

	API     K8SResourceServiceAPI
	Service service.Service `group:"service"`
}

type svc struct {
	*service.BaseService

	mgmtHTTP  mgmthttpcli.MgmtHTTPClient
	metadbCli metadbcli.Client
}

func NewService(p ServiceParam) (ServiceResult, error) {
	base := service.NewBaseService("K8SResourceService")
	s := &svc{
		BaseService: base,
		mgmtHTTP:    p.MgmtHTTP,
		metadbCli:   p.MetadbCli,
	}

	return ServiceResult{API: s, Service: s}, nil
}

func (s *svc) GetControlplaneK8SResource(ctx context.Context, req *GetK8SResourceReq) (string, error) {
	resp, err := s.mgmtHTTP.ClusterServer(req.ClusterId).GetControlplaneK8SResource(ctx, &clusterserver.GetK8SResourceRequest{
		ClusterId:    req.ClusterId,
		Namespace:    req.Namespace,
		ResourceKind: req.ResourceKind,
		ResourceName: req.ResourceName,
	})
	if err != nil {
		return "", err
	}
	if resp == nil || resp.Matadata == "" {
		return "", fmt.Errorf("empty response from controlplane k8s resource, req: %v", req)
	}
	return resp.Matadata, nil
}

func (s *svc) ListK8SResources(ctx context.Context, params *ListK8SResourcesParams) ([]*k8sresourceent.K8SResource, int64, error) {
	req := &metadbcli.ListK8SResourceReq{
		BeginTime: params.BeginTime,
		EndTime:   params.EndTime,
		ClusterId: params.ClusterId,
		Namespace: params.Namespace,
		Region:    params.Region,
		Page:      params.Page,
		PerPage:   params.PerPage,
	}
	resources, total, err := s.metadbCli.ListK8SResource(ctx, req)
	if err != nil {
		return nil, 0, fmt.Errorf("failed to list k8s resources: %w", err)
	}
	return resources, total, nil
}

func (s *svc) ListDedicatedK8sResources(ctx context.Context, params *ListDedicatedK8sResourcesParams) (*regionalv1.ListK8SResourcesResponse, error) {
	return s.mgmtHTTP.RegionServer(params.Region, params.CloudProvider).ListK8sResources(ctx, params.Req)
}
