package main

import (
	"bytes"
	"encoding/csv"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/adlio/trello"
	"github.com/go-resty/resty/v2"
)

var key = "5bfadedbf817bf6322ff7d05927775b9"
var token = "8b7a3403f27d8068961c2c8520471b20d7c3e7e0dd5bb435b5505cd698415b53"

var authParams = map[string]string{
	"key":   key,
	"token": token,
}

func main() {
	client := trello.NewClient(key, token)
	//dumpBoardData(client) // dumps some board info
	cardList := readCSV()
	fmt.Printf("Discovered %d cards to input... starting now... \n\n", len(cardList))
	createCards(cardList, client)

}

func createCards(cardList [][]string, client *trello.Client) {
	for _, card := range cardList {
		var tCard trello.Card
		if card[3] != "" {
			date, err := time.Parse("01-02-2006", card[3]) // Google Sheet should have date formatted in this exact style
			if err != nil {
				fmt.Printf("Error parsing date for: %s with error: %s\n", card[0], err)
				return
			}
			tCard = trello.Card{
				IDList: "5f3034f8b483d68c0961cba8",
				Name:   card[0],
				Desc:   card[1],
				Due:    &date,
				//IDCheckLists: []string{"6068a8f9ee98f04652e554ee"},
			}
		} else {
			tCard = trello.Card{
				IDList: "5f3034f8b483d68c0961cba8",
				Name:   card[0],
				Desc:   card[1],
				//IDCheckLists: []string{"6068a8f9ee98f04652e554ee"},
			}
		}
		//steps := client.GetChecklist("6068a8f9ee98f04652e554ee")

		err := client.CreateCard(&tCard, trello.Arguments{"customFieldItems": "true"})
		if err != nil {
			fmt.Printf("Failure Creating card: %s err: %s\n", tCard.Name, err)
			return
		}
		fmt.Println("Success Creating Card: ", tCard.Name)
		fetchCard(tCard.Name, client, card)
	}
}

func fetchCard(name string, client *trello.Client, cardInfo []string) {
	list, err := client.GetList("5f3034f8b483d68c0961cba8", trello.Defaults())
	if err != nil {
		fmt.Println("Failure getting list: ", err)
		return
	}
	cards, err := list.GetCards(trello.Arguments{"customFieldItems": "true"})
	if err != nil {
		fmt.Println("Error fetching cards for list: ", err)
	}

	for _, card := range cards {
		if card.Name == name {
			if cardInfo[2] != "" {
				switch cardInfo[2] {
				case "TOP":
					card.MoveToTopOfList()
				case "BOTTOM":
					card.MoveToBottomOfList()
				}
			}
			rC := resty.New()

			if cardInfo[6] != "" {
				triCountID := "5ef4f55cfb48ea34a560828d"
				bodyTriCount := fmt.Sprintf(`{ "value": { "text": "%s" } }`, cardInfo[6])
				resp, err := rC.R().
					SetQueryParams(authParams).
					SetHeader("Content-Type", "application/json").
					SetBody(bodyTriCount).
					Put(fmt.Sprintf("https://api.trello.com/1/cards/%s/customField/%s/item", card.ID, triCountID))
				if err != nil {
					fmt.Printf("Error updating tricount: %s err: %s\n", card.Name, err)
				}
				fmt.Println("Tri Count Response: ", resp)
			}

			if cardInfo[5] != "" {
				maxTextureID := "5ef4c3b2fa3ad365c1ca4d1d"
				bodyTexture := fmt.Sprintf(`{ "value": { "number": "%s" } }`, cardInfo[5])
				respTextureSize, err := rC.R().
					SetQueryParams(authParams).
					SetHeader("Content-Type", "application/json").
					SetBody(bodyTexture).
					Put(fmt.Sprintf("https://api.trello.com/1/cards/%s/customField/%s/item", card.ID, maxTextureID))
				if err != nil {
					fmt.Printf("Error updating tricount: %s err: %s\n", card.Name, err)
				}
				fmt.Println("Texture Size Response: ", respTextureSize)
			}

			if cardInfo[4] != "" {
				estTimeID := "5ee685ce2cd79c1a4154cc46"
				var intervalID string
				estTimeStr := cardInfo[4]
				switch estTimeStr {
				case "1H":
					intervalID = "5ee685ce2cd79c1a4154cc47"
				case "3H":
					intervalID = "5ee685ce2cd79c1a4154cc48"
				case "5H":
					intervalID = "5ee685ce2cd79c1a4154cc49"
				case "8H":
					intervalID = "5ee685ce2cd79c1a4154cc4a"
				}
				bodyTime := fmt.Sprintf(`{ "idValue": "%s" }`, intervalID)

				respEstTime, err := rC.R().
					SetQueryParams(authParams).
					SetHeader("Content-Type", "application/json").
					SetBody(bodyTime).
					Put(fmt.Sprintf("https://api.trello.com/1/cards/%s/customField/%s/item", card.ID, estTimeID))
				if err != nil {
					fmt.Printf("Error updating estimated time: %s err: %s\n", card.Name, err)
				}
				fmt.Println("Estimated Time Response:  ", respEstTime)
			}

			attachArray := strings.Split(cardInfo[7], ",")
			for _, fileName := range attachArray {
				if fileName != "" {
					attachFile(card, fileName)
				}
			}

			fmt.Printf("Done Updating Card: %s \n Starting Next Card.....\n\n\n", card.Name)

			//getCustomFields(client)
		}
	}
}

func attachFile(card *trello.Card, fileName string) {
	isCover := "false"
	if strings.Contains(fileName, "cover") {
		isCover = "true"
	}
	fullParams := authParams
	fullParams["setCover"] = isCover
	filePath := fmt.Sprintf("images/%s", fileName)
	fmt.Println("Attaching file from path: ", filePath)
	fileBin, err := os.ReadFile(filePath)
	if err != nil {
		fmt.Printf("Unable to open file: %s err: %s", "cover", err)
	}
	rC := resty.New()
	_, err = rC.R().
		SetQueryParams(fullParams).
		SetFileReader("file", fileName, bytes.NewReader(fileBin)).
		SetMultipartFormData(map[string]string{
			"name": fileName,
		}).
		Post(fmt.Sprintf("https://api.trello.com/1/cards/%s/attachments", card.ID))
	if err != nil {
		fmt.Printf("Error adding attachment: %s err: %s\n", card.Name, err)
	}
}

func getCustomFields(client *trello.Client) {
	board, err := client.GetBoard("IsxWGAfF", trello.Defaults())
	if err != nil {
		fmt.Println("Error getting board: ", err)
	}
	fields, err := board.GetCustomFields(trello.Defaults())
	if err != nil {
		fmt.Println("Error getting fields:  ", err)
	}
	for _, field := range fields {
		if field.Name == "Estimated Time" {
			option1 := field.Options[2]
			fmt.Printf("%+v\n", field)
			fmt.Printf("%+v\n", option1)

		}
	}
}

func readCSV() (cardList [][]string) {
	cardListCSV, err := os.Open("cards.csv")
	if err != nil {
		fmt.Println("Error opening csv file: ", err)
		os.Exit(1)
	}
	reader := csv.NewReader(cardListCSV)

	records, err := reader.ReadAll()
	if err != nil {
		fmt.Println("Error reading csv: ", err)
		os.Exit(1)
	}
	cardList = records[1:]
	return cardList
}

func dumpBoardData(client *trello.Client) {
	board, err := client.GetBoard("IsxWGAfF", trello.Defaults())
	if err != nil {
		fmt.Println("Error getting board: ", err)
	}
	fields, err := board.GetCustomFields(trello.Defaults())
	if err != nil {
		fmt.Println("Error getting fields:  ", err)
	}
	for _, field := range fields {
		fmt.Printf("%+v\n", field)
	}
	lists, err := board.GetLists(trello.Defaults())
	if err != nil {
		fmt.Println("Error fetching lists: ", err)
	}

	for _, list := range lists {
		//fmt.Println("List: ", list.ID, list.Name, i)
		if list.ID == "5f3034f8b483d68c0961cba8" {
			cards, err := list.GetCards(trello.Arguments{"customFieldItems": "true"})
			if err != nil {
				fmt.Println("Error fetching cards for list: ", err)
			}
			for _, card := range cards {
				if card.Name == "Obsidian" {
					fmt.Printf("%+v\n\n", card)
					customFieldItems := card.CustomFieldItems[0]
					fmt.Printf("%+v\n\n", customFieldItems)
					//fmt.Println("Im here NOW!", card)
				}

				// checklist, err := client.GetChecklist("6068a8f9ee98f04652e554ee", trello.Defaults())
				// if err != nil {
				// 	fmt.Println("Unalbe to find checklist: ", err)
				// }
				// fmt.Printf("%+v\n", checklist)
			}
		}

	}
}
