package controllers

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"

	"git.dynamicdiscord.de/kalipso/zineshop/models"
	//"git.dynamicdiscord.de/kalipso/zineshop/services"
	"git.dynamicdiscord.de/kalipso/zineshop/repositories"
)

type ConfigController interface {
	AddConfigHandler(*gin.Context)
	ConfigHandler(*gin.Context)
	ConfigView(*gin.Context)

	GetAllPaper(*gin.Context)
	PaperView(*gin.Context)
	PaperHandler(*gin.Context)
	AddPaperHandler(*gin.Context)

	InvoiceView(*gin.Context)
	InvoiceHandler(*gin.Context)

	CreateTag(*gin.Context)
	GetAllTags(*gin.Context)
	TagView(*gin.Context)
	TagHandler(*gin.Context)
	AddTagHandler(*gin.Context)
}

type configController struct{}

func NewConfigController() ConfigController {
	return &configController{}
}

func (rc *configController) AddConfigHandler(c *gin.Context) {
	key := c.PostForm("key")
	value := c.PostForm("value")

	if key == "" || value == "" {
		err := "Key or Value empty during config creation"
		fmt.Println(err)
		c.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
		return
	}

	config := models.Config{
		Key:   key,
		Value: value,
	}

	_, err := repositories.ConfigOptions.Create(config)
	if err != nil {
		data := CreateSessionData(c, gin.H{
			"error":   err,
			"success": "",
		})

		c.HTML(http.StatusOK, "configview.html", data)
		return
	}

	rc.ConfigView(c)
}

func (rc *configController) ConfigView(c *gin.Context) {
	configOptions, err := repositories.ConfigOptions.GetAll()

	if err != nil {
		c.HTML(http.StatusBadRequest, "configview.html", gin.H{"data": gin.H{"error": err}})
	}

	data := CreateSessionData(c, gin.H{
		"configOptions": configOptions,
	})

	if err != nil {
		c.HTML(http.StatusBadRequest, "configview.html", data)
	}

	c.HTML(http.StatusOK, "configview.html", data)
}

func (rc *configController) ConfigHandler(ctx *gin.Context) {
	key := ctx.PostForm("key")
	value := ctx.PostForm("value")
	action := ctx.PostForm("action")

	config, err := repositories.ConfigOptions.GetById(ctx.Param("id"))

	if err != nil {
		fmt.Println(err)
		ctx.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
		return
	}

	if action == "update" {
		config.Key = key
		config.Value = value
		config, err = repositories.ConfigOptions.Update(config)

		if err != nil {
			fmt.Println(err)
			ctx.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
			return
		}
	}

	if action == "delete" {
		repositories.ConfigOptions.DeleteById(ctx.Param("id"))
	}

	rc.ConfigView(ctx)
}

func (rc *configController) PaperHandler(ctx *gin.Context) {
	newPaper, err := models.NewPaper(ctx)
	action := ctx.PostForm("action")

	if err != nil {
		fmt.Println(err)
		ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
		return
	}

	paper, err := repositories.Papers.GetById(ctx.Param("id"))

	if err != nil {
		fmt.Println(err)
		ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
		return
	}

	if action == "update" {
		paper.Name = newPaper.Name
		paper.Brand = newPaper.Brand
		paper.Size = newPaper.Size
		paper.Weight = newPaper.Weight
		paper.Price = newPaper.Price
		paper, err = repositories.Papers.Update(paper)

		if err != nil {
			fmt.Println(err)
			ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
			return
		}
	}

	if action == "delete" {
		repositories.Papers.DeleteById(ctx.Param("id"))
	}

	rc.PaperView(ctx)
}

func (rc *configController) AddPaperHandler(c *gin.Context) {
	paper, err := models.NewPaper(c)

	if err != nil {
		fmt.Println(err)
		c.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
		return
	}

	_, err = repositories.Papers.Create(paper)
	if err != nil {
		data := CreateSessionData(c, gin.H{
			"error":   err,
			"success": "",
		})

		c.HTML(http.StatusOK, "paperview.html", data)
		return
	}

	rc.PaperView(c)
}

func (rc *configController) PaperView(c *gin.Context) {
	papers, err := repositories.Papers.GetAll()

	if err != nil {
		c.HTML(http.StatusBadRequest, "paperview.html", gin.H{"data": gin.H{"error": err}})
	}

	data := CreateSessionData(c, gin.H{
		"paper": papers,
	})

	if err != nil {
		c.HTML(http.StatusBadRequest, "paperview.html", data)
	}

	c.HTML(http.StatusOK, "paperview.html", data)
}

func (rc *configController) GetAllPaper(c *gin.Context) {
	papers, err := repositories.Papers.GetAll()

	if err != nil {
		ReplyError(c, fmt.Errorf("Could not query Papers"))
		return
	}

	c.JSON(http.StatusOK, papers)
}

//////////////////////////////////////////////////////////////////////

func (rc *configController) InvoiceView(c *gin.Context) {
	invoices, err := repositories.Invoices.GetAllNewestFirst()

	if err != nil {
		c.HTML(http.StatusBadRequest, "invoiceview.html", gin.H{"data": gin.H{"error": err}})
	}

	data := CreateSessionData(c, gin.H{
		"invoices": invoices,
	})

	if err != nil {
		c.HTML(http.StatusBadRequest, "invoiceview.html", data)
	}

	c.HTML(http.StatusOK, "invoiceview.html", data)
}

func (rc *configController) InvoiceHandler(ctx *gin.Context) {
	action := ctx.PostForm("action")
	if action == "delete" {
		repositories.Invoices.DeleteById(ctx.Param("id"))
	}

	rc.InvoiceView(ctx)
}

//////////////////////////////////////////////////////////////////////

func (rc *configController) TagHandler(ctx *gin.Context) {
	name := ctx.PostForm("name")
	color := ctx.PostForm("color")
	action := ctx.PostForm("action")

	tag, err := repositories.Tags.GetById(ctx.Param("id"))

	if err != nil {
		fmt.Println(err)
		ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
		return
	}

	if action == "update" {
		tag.Name = name
		tag.Color = color
		tag, err = repositories.Tags.Update(tag)

		if err != nil {
			fmt.Println(err)
			ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
			return
		}
	}

	if action == "delete" {
		repositories.Tags.DeleteById(ctx.Param("id"))
	}

	rc.TagView(ctx)
}

func (rc *configController) AddTagHandler(c *gin.Context) {
	tag, err := models.NewTag(c)

	if err != nil {
		fmt.Println(err)
		c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
		return
	}

	_, err = repositories.Tags.Create(tag)
	if err != nil {
		data := CreateSessionData(c, gin.H{
			"error":   err,
			"success": "",
		})

		c.HTML(http.StatusOK, "tagview.html", data)
		return
	}

	rc.TagView(c)
}

func (rc *configController) TagView(c *gin.Context) {
	tags, err := repositories.Tags.GetAll()

	if err != nil {
		c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"data": gin.H{"error": err}})
	}

	data := CreateSessionData(c, gin.H{
		"tags": tags,
	})

	if err != nil {
		c.HTML(http.StatusBadRequest, "tagview.html", data)
	}

	c.HTML(http.StatusOK, "tagview.html", data)
}

func (rc *configController) CreateTag(c *gin.Context) {
	tag, err := models.NewTagByJson(c)

	if err != nil {
		ReplyError(c, err)
	}

	_, err = repositories.Tags.Create(tag)
	if err != nil {
		ReplyError(c, fmt.Errorf("tag creation failed: %s", err))
		return
	}

	//userID := user.(models.User).ID
	//rc.DB.Model(&models.shopItem{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID})

	//if result.Error != nil {
	//	ReplyError(c, fmt.Errorf("shopItem creation failed: %s", result.Error))
	//	return
	//}

	ReplyOK(c, fmt.Sprintf("tag '%s' was created", tag.Name))

}

func (rc *configController) GetAllTags(c *gin.Context) {
	tags, err := repositories.Tags.GetAll()

	if err != nil {
		ReplyError(c, fmt.Errorf("Could not query Tags"))
		return
	}

	c.JSON(http.StatusOK, tags)
}
