package jiracli

import (
	"context"
	"fmt"
	"os"
	"testing"

	"github.com/andygrunwald/go-jira"
	relent "github.com/tidbcloud/devops/entity/release"
	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/infra/utils/test"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
)

func TestJiraClient(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "JiraClient Suite")
}

var _ = Describe("[JiraClient]", func() {

	var cli JiraClient
	var fw = test.Framework()

	BeforeEach(func() {
		var err error
		url := os.Getenv("JIRA_URL")
		username := os.Getenv("JIRA_USERNAME")
		password := os.Getenv("JIRA_PASSWORD")

		param := ClientParam{
			Conf: &config.RootConfig{
				Clients: config.Clients{
					Jira: config.JiraConfig{
						JiraURL:      url,
						JiraUsername: username,
						JiraPassword: password,
					},
				},
			},
			Logger: fw.Logger.WithName("JiraClient"),
		}
		cli, err = NewJiraClient(param)
		Expect(err).To(BeNil())
	})

	Describe("[ListVersions]", func() {
		PIt("list versions", func() {
			ctx := context.Background()

			versions, err := cli.ListVersions(ctx, "DM")
			Expect(err).To(BeNil())
			Expect(versions).NotTo(BeEmpty())
			fmt.Println(test.MarshalIndentOrDie(versions))
		})
	})

	Describe("[GetIssue]", func() {
		PIt("get a issue", func() {
			ctx := context.Background()
			key := "TCT-27"
			opt := &jira.GetQueryOptions{
				Fields: "*all",
			}
			issue, err := cli.GetIssue(ctx, key, opt)
			Expect(err).To(BeNil())
			Expect(issue).NotTo(BeNil())
			os.WriteFile(fmt.Sprintf("%s.json", key), []byte(test.MarshalIndentOrDie(issue)), 0600)
		})

		PIt("list issues", func() {
			ctx := context.Background()
			jql := `project = ST AND created >= -30d ORDER BY created DESC`
			token := ""
			resp, err := cli.(*jiraClient).SearchIssues(ctx, jql, &SearchOptions{
				NextPageToken: token,
				MaxResults:    20,
				Fields:        []string{"*all"},
			})
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(resp))
		})
	})

	Describe("[UpdateTicketStatus]", func() {
		PIt("update ticket status", func() {
			ctx := context.Background()
			ticketID := "DM-9145"
			err := cli.UpdateIssueStatus(ctx, ticketID, relent.ReleaseTicketStatusDone)
			Expect(err).To(BeNil())
		})
	})

	Describe("[Asset]", func() {
		PIt("get asset object", func() {
			ctx := context.Background()
			obj, err := cli.GetAssetObject(ctx, "1ac3a551-77af-4c5c-9607-bd4c89495348", "4")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(obj))
		})
	})

	Describe("[CreateIssue]", func() {
		It("converts plain text description to ADF", func() {
			body, err := jiraIssueCreateRequestBody(&jira.Issue{
				Fields: &jira.IssueFields{
					Project:     jira.Project{Key: "TCOCP"},
					Type:        jira.IssueType{Name: "Operation SOP"},
					Summary:     "summary",
					Description: "line 1\nline 2",
				},
			})
			Expect(err).To(BeNil())
			fields := body["fields"].(map[string]any)
			description := fields["description"].(map[string]any)
			Expect(description["type"]).To(Equal("doc"))
			Expect(description["version"]).To(Equal(1))
			content := description["content"].([]map[string]any)
			Expect(content).To(HaveLen(2))
		})
	})

	Describe("Have a try", func() {
		PIt("print all ticket fields", func() {
			issue, _, err := cli.(*jiraClient).cli.Issue.Get("DM-8818", nil)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(issue))
		})

		PIt("list versions", func() {
			projects, _, err := cli.(*jiraClient).cli.Project.Get("DM")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(projects))
		})

	})

	// TODO: UpdateTicketStatus case
})
