package export

import (
	"context"

	"github.com/samber/lo"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	exportrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/export"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/pagination"
)

func (s *serviceImpl) ListExports(ctx context.Context, req *globalngv1.ListExportsRequest) (*globalngv1.ListExportsResponse, bizerr.BizError) {
	if req == nil || req.GetClusterId() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster_id is required")
	}

	tilog.Info(ctx, "list exports request", zap.String("cluster_id", req.GetClusterId()))

	filter := &exportrepo.QueryExportsFilter{
		ClusterIds: []string{req.GetClusterId()},
	}
	totalSize, err := s.exportRepo.Count(ctx, filter)
	if err != nil {
		tilog.Error(ctx, "failed to count exports", zap.Error(err))
		return nil, err
	}
	if totalSize == 0 {
		return &globalngv1.ListExportsResponse{
			Exports: []*globalngv1.Export{},
		}, nil
	}

	exports, nextPageToken, paginationErr := pagination.RemotePagination(
		func(page pagination.Page) ([]*entity.Export, error) {
			list, err := s.exportRepo.List(ctx, filter, &page)
			if err != nil {
				return nil, err
			}
			return list, nil
		}, int(totalSize), req, pagination.ListDefaultPageSize, pagination.ListMaxPageSize)

	if paginationErr != nil {
		return nil, bizerr.WrapError(paginationErr, "list exports pagination")
	}

	protoExports := lo.Map(exports, func(e *entity.Export, _ int) *globalngv1.Export {
		return schemaToProto(e.Export)
	})
	return &globalngv1.ListExportsResponse{
		Exports:       protoExports,
		TotalSize:     int32(totalSize),
		NextPageToken: nextPageToken,
	}, nil
}
