package back

import (
	"fmt"
	"strconv"

	"github.com/gin-gonic/contrib/sessions"
	"github.com/gin-gonic/contrib/static"
	"github.com/gin-gonic/gin"
)

var router *gin.Engine

var month map[string]string

func init() {

	initSetting()
	initLog()
	initPostgreSQL()

	m := manager{}
	fmt.Println("ADMIN EXISTS:", m.SelectTest())

	month = make(map[string]string)
	month["01"] = " января "
	month["02"] = " февраля "
	month["03"] = " марта "
	month["04"] = " апреля "
	month["05"] = " мая "
	month["06"] = " июня "
	month["07"] = " июля "
	month["08"] = " августа "
	month["09"] = " сентября "
	month["10"] = " октября "
	month["11"] = " ноября "
	month["12"] = " декабря "

	prepareMenu()
	prepareNews()
	prepareNewsPagination()
	prepareNotice()

	loadSession()

	router = gin.Default()

	word := sessions.NewCookieStore([]byte("RepairToSecretKey"))
	router.Use(sessions.Sessions("session", word))

	router.Static("/css/"+Setting.ServerVersion, Setting.Assets+"css/")
	router.Static("/js/"+Setting.ServerVersion, Setting.Assets+"js/")
	router.Static("/fonts", Setting.Assets+"font/")
	router.Static("/img", Setting.Assets+"img/")

	router.Use(static.Serve("/", static.LocalFile(Setting.Data, false)))

	router.LoadHTMLFiles(
		Setting.HTML+"index.html",
		Setting.HTML+"404.html",
		Setting.HTML+"position.html",
		Setting.HTML+"BigBoss.html",
	)

	router.GET("/", handlerIndex)

	// "/данные/материал/hello world"
	// "/данные/новость/f9a8c99c874"
	// "/данные/объявление/89c304af9f7e"
	router.GET("/данные/:category/:link", handlerMaterial)
	router.GET("/страница/:page", handlerIndexPage)
	router.GET("/page/:page", handlerPages)

	router.POST("/login", handlerLogin)
	router.POST("/logout", handlerLogout)

	router.NoRoute(handlerNoRoute)

	prepareRouterMenu()
	prepareRouterMaterial()
	prepareRouterDocument()
}

// Run запустить сервер
func Run() {
	var e error

	if Setting.ServerSSL {
		e = router.RunTLS(Setting.ServerHost+":"+Setting.ServerPort, Setting.ServerSSLCert, Setting.ServerSSLKey)
	} else {
		e = router.Run(Setting.ServerHost + ":" + Setting.ServerPort)
	}

	logger.Println(e)
}

func handlerIndex(c *gin.Context) {

	isMain := true
	isAdmin := false
	isLogin := false

	role := getRoleFromContext(c)
	if len(role) != 0 {
		if role == "__admin" {
			isAdmin = true
		}
		isLogin = true
	}

	h := gin.H{}

	h["IsMain"] = isMain
	h["IsLogin"] = isLogin
	h["IsAdmin"] = isAdmin
	if isAdmin {
		h["Menu"] = templateMenuAll
		h["MenuTop"] = templateMenuAllTop
	} else {
		h["Menu"] = templateMenu
		h["MenuTop"] = templateMenuTop
	}
	h["News"] = templateNews
	h["Pagination"] = templateNewsPagination
	h["Notice"] = templateNotice
	h["ServerVersion"] = Setting.ServerVersion

	c.HTML(200, "index.html", h)
}

func handlerPages(c *gin.Context) {

	isMain := false
	isAdmin := false
	isLogin := false

	h := gin.H{}

	h["IsMain"] = isMain
	h["IsLogin"] = isLogin
	h["IsAdmin"] = isAdmin
	h["News"] = templateNews
	h["Pagination"] = templateNewsPagination
	h["Notice"] = templateNotice
	h["ServerVersion"] = Setting.ServerVersion
	h["AvailableMaterial"] = false
	h["Page"] = c.Param("page")

	c.HTML(200, "index.html", h)
}

func handlerIndexPage(c *gin.Context) {

	isMain := true
	isAdmin := false
	isLogin := false

	role := getRoleFromContext(c)
	if len(role) != 0 {
		if role == "__admin" {
			isAdmin = true
		}
		isLogin = true
	}

	page, e := strconv.ParseInt(c.Param("page"), 10, 64)
	if e != nil {
		logger.Println(e)
		page = 0
	}

	h := gin.H{}

	h["IsMain"] = isMain
	h["IsLogin"] = isLogin
	h["IsAdmin"] = isAdmin
	if isAdmin {
		h["Menu"] = templateMenuAll
		h["MenuTop"] = templateMenuAllTop
	} else {
		h["Menu"] = templateMenu
		h["MenuTop"] = templateMenuTop
	}
	h["News"] = getNewsByPage(int(page))
	h["Pagination"] = getNewsPaginationByPage(int(page))
	h["Notice"] = templateNotice
	h["ServerVersion"] = Setting.ServerVersion

	c.HTML(200, "index.html", h)
}

func handlerLogin(c *gin.Context) {
	var m manager

	e := c.BindJSON(&m)
	if e != nil {
		fmt.Println(e.Error())

		c.JSON(200, gin.H{
			"Error": "Неверный логин/пароль",
		})
		return
	}

	e = m.Select()
	if e != nil {
		fmt.Println(e.Error())

		c.JSON(200, gin.H{
			"Error": "Неверный логин/пароль",
		})
		return
	}

	s := sessions.Default(c)

	hash, e := GenerateHash(m.Login)
	if e != nil {
		logger.Println(e)
		c.JSON(200, gin.H{
			"Error": "Ошибка сервера",
		})
		return
	}

	newSession := session{}
	newSession.Hash = hash
	newSession.Manager = m.ID

	e = newSession.Insert()
	if e != nil {
		logger.Println(e)
		c.JSON(200, gin.H{
			"Error": "Ошибка сервера",
		})
		return
	}

	s.Set(sessionKey, hash)

	e = s.Save()
	if e != nil {
		fmt.Println(e.Error())
		c.JSON(200, gin.H{
			"Error": "Ошибка сохранения сессии в куки",
		})
		return
	}

	c.JSON(200, gin.H{
		"Error": nil,
		"Name":  m.FirstName,
	})
}

func handlerLogout(c *gin.Context) {

	clearSessionFromContext(c)

	c.JSON(200, gin.H{
		"Error": nil,
	})
}

func handlerNoRoute(c *gin.Context) {
	h := gin.H{}

	h["Page"] = "400"

	isAdmin := false
	isLogin := false

	role := getRoleFromContext(c)
	if len(role) != 0 {
		if role == "__admin" {
			isAdmin = true
		}
		isLogin = true
	}

	h["IsMain"] = false
	h["IsLogin"] = isLogin
	h["IsAdmin"] = isAdmin
	if isAdmin {
		h["Menu"] = templateMenuAll
		h["MenuTop"] = templateMenuAllTop
	} else {
		h["Menu"] = templateMenu
		h["MenuTop"] = templateMenuTop
	}
	h["AvailableMaterial"] = false

	h["ServerVersion"] = Setting.ServerVersion

	c.HTML(200, "index.html", h)
}

func handlerCatalog(c *gin.Context) {
	isMain := false
	isAdmin := false
	isLogin := false

	role := getRoleFromContext(c)
	if len(role) != 0 {
		if role == "__admin" {
			isAdmin = true
		}
		isLogin = true
	}

	h := gin.H{}

	h["IsMain"] = isMain
	h["IsLogin"] = isLogin
	h["IsAdmin"] = isAdmin

	h["Page"] = "catalog"
	h["AvailableMaterial"] = false
	h["ServerVersion"] = Setting.ServerVersion

	c.HTML(200, "index.html", h)
}
