package api

import (
	"fmt"
	"log"
	"net/http"
	"strconv"

	adminapi "srs.epita.fr/fic-server/admin/api"
	"srs.epita.fr/fic-server/libfic"

	"github.com/gin-gonic/gin"
)

func declareExercicesRoutes(router *gin.RouterGroup) {
	router.GET("/exercices", listExercices)

	exercicesRoutes := router.Group("/exercices/:eid")
	exercicesRoutes.Use(exerciceHandler)
	exercicesRoutes.GET("", showExercice)

	declareQARoutes(exercicesRoutes)
}

func exerciceHandler(c *gin.Context) {
	var exercice *fic.Exercice
	if eid, err := strconv.ParseInt(string(c.Param("eid")), 10, 64); err != nil {
		c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Bad exercice identifier."})
		return
	} else if exercice, err = fic.GetExercice(eid); err != nil {
		c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Exercice not found."})
		return
	}

	if th, ok := c.Get("theme"); ok {
		if exercice.IdTheme == nil || *exercice.IdTheme != th.(*fic.Theme).Id {
			c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Exercice not found."})
			return
		}
	}

	c.Set("exercice", exercice)

	c.Next()
}

func listExercices(c *gin.Context) {
	var exercices []*fic.Exercice
	var err error

	if theme, ok := c.Get("theme"); ok {
		exercices, err = theme.(*fic.Theme).GetExercices()
	} else {
		// List all exercices
		exercices, err = fic.GetExercices()
	}
	if err != nil {
		log.Println("Unable to GetExercices: ", err.Error())
		c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list exercices: %s", err.Error())})
		return
	}

	c.JSON(http.StatusOK, exercices)
}

func showExercice(c *gin.Context) {
	if adminLink == "" {
		c.JSON(http.StatusOK, c.MustGet("exercice"))
		return
	}

	var e adminapi.Exercice
	err := fwdAdmin(c.Request.Method, fmt.Sprintf("/api/exercices/%s", string(c.Param("eid"))), nil, &e)
	if err != nil {
		log.Println("Unable to make request to admin:", err.Error())
		c.JSON(http.StatusOK, c.MustGet("exercice"))
		return
	}

	c.JSON(http.StatusOK, e)
}
