package tmdb

import (
	"notabug.org/apiote/amuse/config"
	"notabug.org/apiote/amuse/datastructure"
	"notabug.org/apiote/amuse/network"

	"encoding/json"
	"errors"
	"net/http"

	"notabug.org/apiote/gott"
)

type Genres struct {
	Genres []struct {
		Id   int
		Name string
	}
}

func createGenresRequest(args ...interface{}) (interface{}, error) {
	request := args[0].(*network.Request)
	result := args[1].(*network.Result)
	result.Client = &http.Client{}

	var itemType string
	if request.Id == datastructure.ItemTypeFilm {
		itemType = "movie"
	} else if request.Id == datastructure.ItemTypeTvserie {
		itemType = "tv"
	} else {
		return gott.Tuple(args), errors.New("Wrong itemType: " + request.Id)
	}

	httpRequest, err := http.NewRequest("GET", "https://api.themoviedb.org/3/genre/"+itemType+"/list?api_key="+config.TmdbApiKey+"&language="+request.Language, nil)
	result.Request = httpRequest
	return gott.Tuple(args), err
}

func unmarshalGenres(args ...interface{}) (interface{}, error) {
	result := args[1].(*network.Result)
	genres := &Genres{}
	err := json.Unmarshal(result.Body, genres)
	if err != nil {
		return gott.Tuple(args), err
	}

	genreMap := map[int]string{}
	for _, genre := range genres.Genres {
		genreMap[genre.Id] = genre.Name
	}

	result.Result = genreMap
	return gott.Tuple(args), nil
}

func GetGenres(language string, itemType datastructure.ItemType) (map[int]string, error) {
	genres, err := gott.
		NewResult(gott.Tuple{&network.Request{Id: string(itemType), Language: language}, &network.Result{}}).
		Bind(createGenresRequest).
		Bind(getCacheEntry).
		Map(network.AddHeaders).
		Bind(network.DoRequest).
		Bind(network.HandleRequestError).
		Bind(network.ReadResponse).
		Tee(cleanCache).
		Tee(saveCacheEntry).
		Bind(unmarshalGenres).
		Finish()

	if err != nil {
		return map[int]string{}, err
	} else {
		return genres.(gott.Tuple)[1].(*network.Result).Result.(map[int]string), nil
	}
}
