package api

import (
	"context"
	"time"

	jiraent "github.com/tidbcloud/devops/entity/jira"
)

type IssueSnapshotFilter struct {
	StatusIn      *[]string
	CreatedAfter  *time.Time
	CreatedBefore *time.Time
	PriorityIn    *[]string
	ProjectKeyIn  *[]string

	CustomerEnvIs *jiraent.IssueCustomerEnvironment
	ClusterIDIn   *[]string
	TenantIDIn    *[]string
	ComponentIn   *[]string
	IssueKeyIn    *[]string
}

type IssueInRepoFilter struct {
	IssueSnapshotFilter

	HaveTriage          *bool
	HaveTimelineSummary *bool
	KeyIn               *[]string
}

type IssueTriageFilter struct {
}

type ListUnifiedIssuesParam struct {
	IssueInRepoFilter

	WithTriage          bool
	WithTimelineSummary bool
	WithJira            bool
	WithJiraComments    bool // only valid when WithJira is true

	Page    uint32
	PerPage uint32
}

type GetUnifiedIssueParam struct {
	WithTriage          bool
	WithTimelineSummary bool
}

type SyncIssueSnapshotByJQLParam struct {
	MaxCount int
	FailFast bool // whether to stop when encountering an error
	PerPage  int  // items per page when fetching from Jira, default to 50
}

type StoreIssueInRepoByJQLResult struct {
	Total         int
	SuccessIssues []string
	FailureIssues []string
}

type ListIssuesFromJiraParam struct {
	WithComments bool
	PageToken    string
	PageSize     int
}

type ListIssuesFromJiraResult struct {
	Issues        []*jiraent.IssueInJira
	IsLast        bool
	NextPageToken string
}

type GetIssueFromJiraParam struct {
	WithComments bool
}

type ListIssueTriageTagDefinitionsParam struct {
	TypesIn       *[]jiraent.IssueTriageTagType
	NamesIn       *[]string
	LabelsContain map[string]string
}

type IssueServiceAPI interface {
	ListUnifiedIssues(ctx context.Context, param ListUnifiedIssuesParam) ([]*jiraent.UnifiedIssue, int64, error)
	GetUnifiedIssue(ctx context.Context, key string, param GetUnifiedIssueParam) (*jiraent.UnifiedIssue, error)

	// SyncIssueSnapshotByKey fetches an issue from Jira and store it into repo.
	SyncIssueSnapshotByKey(ctx context.Context, key string) (*jiraent.IssueInRepo, error)
	// SyncIssueSnapshotByJQL fetches issues from Jira by JQL and store them into repo.
	SyncIssueSnapshotByJQL(ctx context.Context, jql string, param SyncIssueSnapshotByJQLParam) (*StoreIssueInRepoByJQLResult, error)

	// UpsertIssueTriage creates or updates an issue triage.
	UpsertIssueTriage(ctx context.Context, triage *jiraent.IssueTriage) (*jiraent.IssueTriage, error)
	// GetIssueTimelineSummary gets the timeline summary of an issue.
	SetIssueTimelineSummary(ctx context.Context, key string, summary *jiraent.IssueTimelineSummary) error

	// ListIssuesFromJira queries issues from Jira by a JQL.
	ListIssuesFromJira(ctx context.Context, jql string, param ListIssuesFromJiraParam) (*ListIssuesFromJiraResult, error)
	// GetIssueFromJira gets an issue by key from Jira.
	GetIssueFromJira(ctx context.Context, key string, param GetIssueFromJiraParam) (*jiraent.IssueInJira, error)

	// ListIssueTriageTags lists issue triage tags by filter.
	ListIssueTriageTagDefinitions(ctx context.Context, param ListIssueTriageTagDefinitionsParam) ([]*jiraent.IssueTriageTagDefinition, error)
	// CreateIssueTriageTag creates a new issue triage tag.
	CreateIssueTriageTagDefinition(ctx context.Context, tag *jiraent.IssueTriageTagDefinition) (*jiraent.IssueTriageTagDefinition, error)
	// DeleteIssueTriageTag deletes an issue triage tag by name and type.
	DeleteIssueTriageTagDefinition(ctx context.Context, name string, typ jiraent.IssueTriageTagType) error
}
