package main

import (
	"cds/dao"
	"cds/models"
	"fmt"
	"os"
	"time"

	_ "cds/docs"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/template/html"
	"github.com/joho/godotenv"
	"github.com/markbates/goth"
	"github.com/markbates/goth/providers/discord"
	"github.com/markbates/goth/providers/steam"
	"github.com/shareed2k/goth_fiber"
	"go.mongodb.org/mongo-driver/mongo"
)

//const DISCORD_API = "https://discord.com/api/v10/"

func setupRoutes(app *fiber.App) {
	app.Get("/", index)

	//api := app.Group("/api")
	//routes.AccountRoute(api.Group("/accounts"))
	//routes.GroupeRoute(api.Group("/groups"))
	//app.Get("/swagger/*", swagger.HandlerDefault)

	app.Get("/login/:provider", goth_fiber.BeginAuthHandler)
	app.Get("/auth/:provider", auth)
}

func checkDiscord(c *fiber.Ctx) error {
	gothuser, err := goth_fiber.CompleteUserAuth(c)
	if err != nil {
		print("== ERROR ==")
		panic(err)
	}

	/*
		fmt.Println(gothuser.UserID)
		fmt.Println(gothuser.Name)
		fmt.Println(gothuser.RawData["discriminator"])
		fmt.Println(gothuser.AccessToken)
	*/

	token := c.Cookies("token", "")
	fmt.Println("Discord cookie:" + token)
	id := gothuser.UserID
	name := fmt.Sprint(gothuser.Name, "#", gothuser.RawData["discriminator"])

	// on vérifie s'il existe déjà dans la db sinon on le créé
	user, err := dao.GetByDiscord(id)
	if user != nil && token == "" {
		cookie := new(fiber.Cookie)
		cookie.Name = "token"
		cookie.Value = user.Id.Hex()
		cookie.Expires = time.Now().Add(24 * time.Hour)
		c.Cookie(cookie)
	}

	if err == mongo.ErrNoDocuments {
		user = models.NewUserDiscord(id, name)
		id, err = dao.CreateUser(user)
		if err != nil {
			fmt.Println(err)
		}

		if token == "" {
			cookie := new(fiber.Cookie)
			cookie.Name = "token"
			cookie.Value = id
			cookie.Expires = time.Now().Add(24 * time.Hour)
			c.Cookie(cookie)
		}
	} else if err != nil {
		fmt.Println(err)
	}

	c.Redirect("/")
	return nil
}

func auth(c *fiber.Ctx) error {
	provider, err := goth_fiber.GetProviderName(c)
	if err != nil {
		print("== ERROR ==")
		panic(err)
	}

	if provider == "discord" {
		return checkDiscord(c)
	} else if provider == "steam" {
		return checkSteam(c)
	}

	return nil
}

func checkSteam(c *fiber.Ctx) error {
	token := c.Cookies("token", "")
	gothuser, err := goth_fiber.CompleteUserAuth(c)
	if err != nil {
		print("== ERROR ==")
		panic(err)
	}

	id := gothuser.UserID

	user, err := dao.GetById(fmt.Sprint(token))

	if user == nil {
		user, err = dao.GetBySteam(id)
		if user != nil && token == "" {
			cookie := new(fiber.Cookie)
			cookie.Name = "token"
			cookie.Value = user.Id.Hex()
			cookie.Expires = time.Now().Add(24 * time.Hour)
			c.Cookie(cookie)
		}

		if err == mongo.ErrNoDocuments {
			user = models.NewUserSteam(id)
			id, err = dao.CreateUser(user)
			if err != nil {
				fmt.Println(err)
			}

			if token == "" {
				cookie := new(fiber.Cookie)
				cookie.Name = "token"
				cookie.Value = id
				cookie.Expires = time.Now().Add(24 * time.Hour)
				c.Cookie(cookie)
			}
		} else if err != nil {
			fmt.Println(err)
		}
	} else if user.SteamId == "" {
		if user.DiscordId != "" {
			dao.AddSteam(user.DiscordId, id)
		}
	}

	c.Redirect("/")
	return nil
}

func index(c *fiber.Ctx) error {
	token := c.Cookies("token", "")
	var discord string = ""
	var steam string = ""
	if token != "" {
		user, _ := dao.GetById(fmt.Sprint(token))
		if user != nil {
			steam = user.SteamId
			discord = user.DiscordName
		}
	}

	return c.Render("index", fiber.Map{
		"connected":   token != "",
		"urlDiscord":  "/login/discord",
		"urlSteam":    "/login/steam",
		"discordName": discord,
		"steamName":   steam,
	})
}

// @title           CDS API
// @version         1.0 (alpha)
// @description     API du site web de CDS
// @contact.name   La super équipe de dev
// @license.name  AGPL 3.0
// @license.url   https://www.gnu.org/licenses/agpl-3.0.html
// @host      localhost:8080
// @BasePath  /api
func main() {
	err := godotenv.Load()
	if err != nil {
		panic(err)
	}

	app := fiber.New(fiber.Config{Views: html.New("./views", ".html")})
	goth.UseProviders(
		discord.New(
			os.Getenv("DISCORD_ID"),
			os.Getenv("DISCORD_SECRET"),
			"http://localhost:8080/auth/discord",
			discord.ScopeIdentify, discord.ScopeGuilds),
		steam.New(os.Getenv("STEAM_KEY"), "http://localhost:8080/auth/steam"),
	)

	setupRoutes(app)

	err = app.Listen(":8080")
	if err != nil {
		panic(err)
	}
}