package services

import (
	"fmt"
	"log"
	"os"
	"ticket-pimp/internal/domain"
	"time"

	"github.com/imroc/req/v3"
)

type Coda struct {
	*CommonClient
}

type ICoda interface {
	ListDocs()
	CreateApp(task domain.CodaApplication)
	CreateTask(title string, desc string, creatorName string, creatorID string) (string, error)
	GetRowLink(id string) (string, error)
}

func NewCodaClient(token string) *Coda {

	client := NewClient().
		SetTimeout(15 * time.Second).
		SetCommonBearerAuthToken(token).
		SetBaseURL("https://coda.io/apis/v1")

	return &Coda{
		CommonClient: &CommonClient{
			client,
		},
	}
}

func (c *Coda) ListDocs() {

	const tableID = "grid-obBN3tWdeh"
	const docID = "Ic3IZpQ3Wk"

	resp, _ := c.R().
		SetQueryParam("tableTypes", "table").
		//SetSuccessResult(&i).
		Get("/docs/" + docID + "/tables/" + tableID + "/rows")

	if resp.Err != nil {
		log.Print(resp.Err)
		return
	}

	log.Print(resp)
}

func (c *Coda) CreateApp(task domain.CodaApplication) {
	resp, _ := c.R().
		SetBody(task).
		SetContentType("application/json").
		SetBearerAuthToken(os.Getenv("CODA_TOKEN2")).
		Post("/docs/Ic3IZpQ3Wk/hooks/automation/grid-auto-NlUwM7F7Cr")

	fmt.Print(resp)
}

func (c *Coda) CreateTask(title string, desc string, creatorName string, creatorID string) (string, error) {
	const (
		docID   = "vceN8BewiU"
		tableID = "grid-GPdeq96hUq"
	)

	request := domain.NewTaskRequest()
	request.
		NewRow().
		NewCell("c-rvWipOfkxr", title).
		NewCell("c-fLsUoIqQG9", creatorName).
		NewCell("c-psmWFHIoKl", creatorID).
		NewCell("c-ASsOsB1hzH", desc)

	type TaskURL struct {
		ID []string `json:"addedRowIds"`
	}

	tasks := TaskURL{}

	_, err := c.R().
		SetContentType("application/json").
		SetQueryParam("disableParsing", "true").
		SetBodyJsonMarshal(&request).
		SetSuccessResult(&tasks).
		Post("/docs/" + docID + "/tables/" + tableID + "/rows")
	if err != nil {
		return "", err
	}
	return tasks.ID[0], nil
}

func (c *Coda) GetRowLink(id string) (string, error) {
	const (
		docID   = "vceN8BewiU"
		tableID = "grid-GPdeq96hUq"
	)
	type RowResponse struct {
		Link string `json:"browserLink"`
	}
	rowResponse := RowResponse{}
	resp, err := c.R().
		SetRetryCount(20).
		SetRetryBackoffInterval(1*time.Second, 5*time.Second).
		SetSuccessResult(&rowResponse).
		AddRetryHook(func(resp *req.Response, err error) {
			req := resp.Request.RawRequest
			fmt.Println("Retry request:", req.Method, req.URL)
			fmt.Println("Retry to retrieve row")
		}).
		AddRetryCondition(func(resp *req.Response, err error) bool {
			log.Println(resp.String())
			return err != nil || resp.StatusCode == 404
		}).
		Get("/docs/" + docID + "/tables/" + tableID + "/rows/" + id)
	if err != nil {
		return "", err
	}
	_ = resp
	return rowResponse.Link, nil
}
