package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"

	"code.justin.tv/live/yt-live-annotations/youtube"

	"golang.org/x/net/context"
)

type messageAttribute struct {
	Type  string `json:"Type"`
	Value string `json:"Value"`
}

type message struct {
	Message           string `json:"Message"`
	MessageAttributes struct {
		Source messageAttribute `json:"source"`
		Event  messageAttribute `json:"event"`
	} `json:"MessageAttributes"`
}

type messageBody struct {
	ChannelID int `json:"channel_id"`
}

// processMessage implements an endpoint to handle SQS messages
func (s *Server) processMessage(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	buf, err := ioutil.ReadAll(r.Body)
	if err != nil {
		s.serveError(w, r, http.StatusInternalServerError, fmt.Errorf("error reading body"), "event")
		return
	}

	var m message
	err = json.Unmarshal(buf, &m)
	if err != nil {
		s.serveError(w, r, http.StatusOK, fmt.Errorf("error unmarshalling into message: %v - %v", string(buf), err), "event")
		return
	}

	var body messageBody
	err = json.Unmarshal([]byte(m.Message), &body)
	if err != nil {
		s.serveError(w, r, http.StatusOK, fmt.Errorf("error unmarshalling message body: %v - %v", m.Message, err), "event")
		return
	}

	channelID := strconv.Itoa(body.ChannelID)

	enabled, err := s.backend.GetAnnotationsEnabled(ctx, channelID)
	if err != nil {
		s.serveError(w, r, http.StatusInternalServerError, fmt.Errorf("error getting whether annotations are enabled for %v", channelID), "event")
		return
	}

	if !enabled {
		s.serveSuccess(w, "event")
		return
	}

	var newStatus int
	if m.MessageAttributes.Event.Value == "stream_change_up" {
		newStatus = youtube.StatusUp
	} else if m.MessageAttributes.Event.Value == "stream_change_down" {
		newStatus = youtube.StatusDown
	} else {
		s.serveError(w, r, http.StatusOK, fmt.Errorf("invalid message event type %v", m.MessageAttributes.Event.Value), "event")
		return
	}

	err = s.yt.SetYoutubeAnnotationsStatus(ctx, strconv.Itoa(body.ChannelID), newStatus)
	if err != nil {
		s.serveError(w, r, http.StatusOK, fmt.Errorf("error setting annotations status for %v: %v", channelID, err), "event")
		return
	}

	err = s.backend.UpdateAnnotationsTimestamp(ctx, strconv.Itoa(body.ChannelID))
	if err != nil {
		s.serveError(w, r, http.StatusInternalServerError, fmt.Errorf("error updating annotations timestamp for %v: %v", channelID, err), "event")
		return
	}

	s.serveSuccess(w, "event")
}
