package controller

import (
	"arimelody-web/model"
	"bytes"
	"encoding/json"
	"net/http"
	"net/url"
	"time"
)

const TWITCH_API_BASE = "https://api.twitch.tv/helix/"

func TwitchSetup(app *model.AppState) error {
    app.Twitch = &model.TwitchState{}
    err := RefreshTwitchToken(app)
    return err
}

func RefreshTwitchToken(app *model.AppState) error {
    if app.Twitch != nil && app.Twitch.Token != nil && time.Now().UTC().After(app.Twitch.Token.ExpiresAt) {
        return nil
    }

    requestUrl, _ := url.Parse("https://id.twitch.tv/oauth2/token")
    req, _ := http.NewRequest(http.MethodPost, requestUrl.String(), bytes.NewBuffer([]byte(url.Values{
        "client_id": []string{ app.Config.Twitch.ClientID },
        "client_secret": []string{ app.Config.Twitch.Secret },
        "grant_type": []string{ "client_credentials" },
    }.Encode())))

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }

    type TwitchOAuthToken struct {
        AccessToken string `json:"access_token"`
        ExpiresIn int `json:"expires_in"`
        TokenType string `json:"token_type"`
    }
    oauthResponse := TwitchOAuthToken{}
    err = json.NewDecoder(res.Body).Decode(&oauthResponse)
    if err != nil {
        return err
    }

    app.Twitch.Token = &model.TwitchOAuthToken{
        AccessToken: oauthResponse.AccessToken,
        ExpiresAt: time.Now().UTC().Add(time.Second * time.Duration(oauthResponse.ExpiresIn)).UTC(),
        TokenType: oauthResponse.TokenType,
    }

    return nil
}

var lastStreamState *model.TwitchStreamInfo
var lastStreamStateAt time.Time

func GetTwitchStatus(app *model.AppState, broadcaster string) (*model.TwitchStreamInfo, error) {
    if lastStreamState != nil && time.Now().UTC().Before(lastStreamStateAt.Add(time.Minute)) {
        return lastStreamState, nil
    }

    requestUrl, _ := url.Parse(TWITCH_API_BASE + "streams")
    requestUrl.RawQuery = url.Values{
        "user_login": []string{ broadcaster },
    }.Encode()
    req, _ := http.NewRequest(http.MethodGet, requestUrl.String(), nil)
    req.Header.Set("Client-Id", app.Config.Twitch.ClientID)
    req.Header.Set("Authorization", "Bearer " + app.Twitch.Token.AccessToken)

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }

    type StreamsResponse struct {
        Data []model.TwitchStreamInfo `json:"data"`
    }
    streamInfo := StreamsResponse{}
    err = json.NewDecoder(res.Body).Decode(&streamInfo)
    if err != nil {
        return nil, err
    }

    if len(streamInfo.Data) == 0 {
        return nil, nil
    }

    lastStreamState = &streamInfo.Data[0]
    lastStreamStateAt = time.Now().UTC()
    return lastStreamState, nil
}
