package libamuse

import (
	"notabug.org/apiote/amuse/accounts"
	"notabug.org/apiote/amuse/datastructure"
	"notabug.org/apiote/amuse/inventaire"
	"notabug.org/apiote/amuse/wikidata"
	"notabug.org/apiote/amuse/db"

	"errors"

	"notabug.org/apiote/gott"
)

func getBook(args ...interface{}) (interface{}, error) {
	data := args[0].(*RequestData)
	result := args[1].(*Result)
	languages := result.languages
	var (
		book *datastructure.Book
		err  error
	)
	if data.id[:2] == "wd" {
		book, err = wikidata.GetBook(data.id, languages[0].String(), data.connection)
	} else if data.id[:3] == "inv" {
		book, err = inventaire.GetBook(data.id, languages[0].String(), data.connection)
	} else {
		err = errors.New("Wrong scheme")
	}
	result.result = book
	return gott.Tuple(args), err
}

func getCover(args ...interface{}) (interface{}, error) {
	data := args[0].(*RequestData)
	result := args[1].(*Result)
	book := result.result.(*datastructure.Book)
	languages := result.languages
	cover, err := wikidata.GetCover(data.id, languages[0].String(), data.connection)
	book.Cover = cover
	return gott.Tuple(args), err
}

func getBookExperiences(args ...interface{}) (interface{}, error) {
	data := args[0].(*RequestData)
	result := args[1].(*Result)
	book := result.result.(*datastructure.Book)

	if result.user.IsEmpty() {
		return gott.Tuple(args), nil
	}

	exp, err := db.GetItemExperiences(result.user.Username, data.id, datastructure.ItemTypeBook)
	book.Experiences = exp[data.id]
	return gott.Tuple(args), err
}

func renderBook(args ...interface{}) interface{} {
	result := args[1].(*Result)
	book := result.result.(*datastructure.Book)
	result.page = result.renderer.RenderBook(*book, result.languages)
	return gott.Tuple(args)
}

func ShowBook(id, language, mimetype string, auth accounts.Authentication) (string, error) {
	auth.Necessary = false
	r, err := gott.
		NewResult(gott.Tuple{&RequestData{id: id, language: language, mimetype: mimetype, auth: auth}, &Result{}}).
		Bind(parseLanguage).
		Bind(verifyToken).
		Bind(getBook).
		Bind(getDescription).
		Bind(getCover).
		Bind(getBookExperiences).
		Bind(isOnWantList).
		Bind(createRenderer).
		Map(renderBook).
		Finish()

	if err != nil {
		return "", err
	} else {
		return r.(gott.Tuple)[1].(*Result).page, nil
	}
}
