package action

import (
	"context"
	"log/slog"
	"strings"

	"github.com/tidbcloud/jiraport/pkg/clients/clinic"
	"github.com/tidbcloud/jiraport/pkg/clients/devops"
	"github.com/tidbcloud/jiraport/pkg/clients/jira"
	"github.com/tidbcloud/jiraport/pkg/entity"
)

type BackfillCommand struct {
	logger       *slog.Logger
	jiraClient   jira.Interface
	clinicClient clinic.Interface
	devopsClient devops.Interface
}

func newBackfillCommand(
	logger *slog.Logger,
	jiraClient jira.Interface,
	clinicClient clinic.Interface,
	devopsClient devops.Interface,
) (*BackfillCommand, error) {
	return &BackfillCommand{
		logger:       logger,
		jiraClient:   jiraClient,
		clinicClient: clinicClient,
		devopsClient: devopsClient,
	}, nil
}

func (cmd *BackfillCommand) Exec(ctx context.Context, actionExecInfo *entity.NotificationActionExecInfo, args ...string) (bool, string, error) {
	issue := actionExecInfo.Notification.Issue
	if strings.HasPrefix(issue.Key, "O11Y") {
		tenantID := issue.GetTenant()
		clusterID := issue.GetCluster()
		if tenantID == "" || tenantID == `<no value>` {
			tenantID, err := cmd.clinicClient.GetTenantIDByTenantIDAndClusterID(tenantID, clusterID)
			if err != nil {
				cmd.logger.Error("fail to get tenant id by cluster id",
					"err", err,
					"issue", issue.Key,
					"clusterID", clusterID)
			}
			if tenantID != "" {
				if err := cmd.jiraClient.BackfillTenantID(issue.Key, tenantID); err != nil {
					return false, "", err
				}
			}
		}
		//backfill the version.
		if clusterID != "" {
			version, err := cmd.clinicClient.GetClusterVersion(clusterID)
			if err != nil {
				cmd.logger.Error("fail to get cluster version by cluster id",
					"err", err,
					"issue", issue.Key,
					"clusterID", clusterID)
				return true, "", nil
			}
			if err := cmd.jiraClient.BackfillVersion(issue.Key, version); err != nil {
				return false, "", err
			}

		}
	} else if strings.HasPrefix(issue.Key, "ST-") {
		clusterAssetField := "customfield_10111"
		clusterIDField := "customfield_10088"

		// skip if cluster info already exists
		if clusterAsset, err := issue.RawIssue.Fields.Unknowns.Array(clusterAssetField); err == nil {
			if len(clusterAsset) > 0 {
				return true, "", nil
			}
		} else if clusterID, err := issue.RawIssue.Fields.Unknowns.String(clusterIDField); err == nil {
			if clusterID != "" {
				return true, "", nil
			}
		}

		cmd.logger.Info("try to backfill cluster id for st ticket", "issue", issue.Key)
		clusterID, err := cmd.devopsClient.GetClusterIDForStTicket(issue.Key)
		if err != nil {
			cmd.logger.Error("fail to get cluster id for st ticket",
				"err", err,
				"issue", issue.Key)
			return true, "", nil
		}
		if clusterID != "" {
			cmd.logger.Info("successfully get cluster id for st ticket, start to backfill", "issue", issue.Key)
			if err := cmd.jiraClient.BackfillClusterIDForTicket(issue.Key, clusterID); err != nil {
				return false, "", err
			}
		}
	}

	return true, "", nil
}
