package api

import (
	"bytes"
	"encoding/json"
	"net/http"
	"path"
)

type Genre struct {
	Name  string `json:"name"`
	Level int    `json:"level"`
}

type Anime struct {
	ID              int     `json:"id"`
	Title           string  `json:"title"`
	Type            string  `json:"type"`
	Episodes        int     `json:"episodes"`
	State           string  `json:"state"`
	Rating          string  `json:"rating"`
	StartDate       string  `json:"start_date"`
	EndDate         string  `json:"end_date"`
	Genres          []Genre `json:"genres"`
	AverageDuration int     `json:"average_duration"`
	AnidbID         int     `json:"anidb_id"`
	MyanimelistID   int     `json:"myanimelist_id"`
}

type AnimeSearch struct {
	Title string `json:"title"`
}

var baseURL = "https://api.meikan.moe/v1/"

func getJSON(url string, target interface{}) error {
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	return json.NewDecoder(r.Body).Decode(&target)
}

func postJSON(url string, form AnimeSearch, target interface{}) error {
	b := new(bytes.Buffer)
	json.NewEncoder(b).Encode(form)

	r, err := http.Post(url, "application/json; charset=utf-8", b)
	if err != nil {
		return err
	}
	defer r.Body.Close()
	return json.NewDecoder(r.Body).Decode(target)
}

func AnimeByID(id string) (Anime, error) {
	anime := Anime{}
	url := baseURL + path.Join("anime", id)
	err := getJSON(url, &anime)
	return anime, err
}

func SearchAnime(title string) ([]Anime, error) {
	anime := []Anime{}

	form := AnimeSearch{Title: title}
	url := baseURL + "anime"
	err := postJSON(url, form, &anime)
	return anime, err
}
