package main

import (
	"database/sql"
	"embed"
	"gin-test/pkg/sample"
	"gin-test/pkg/user"
	"github.com/go-chi/jwtauth/v5"
	"github.com/rs/zerolog/log"
	"net/http"
	"os"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"

	"github.com/golang-migrate/migrate/v4"
	"github.com/golang-migrate/migrate/v4/database/mysql"
	"github.com/golang-migrate/migrate/v4/source/iofs"
	"github.com/unrolled/render"
	"github.com/urfave/cli/v2"
)

// content holds our static web server content.
//go:embed static/* templates/*
var webserver embed.FS

//go:embed database/migrations/*.sql
var migrationFS embed.FS

func main() {
	app := &cli.App{
		Name: "Webpage",
		Usage: "Sample Webapplication in golang",
		Commands: []*cli.Command{
			{
				Name:    "run",
				//Aliases: []string{"c"},
				Usage:   "Run Webapplication",
				Action:  func(c *cli.Context) error {
					return runWebpage()
				},
			},
			{
				Name:    "migrate",
				//Aliases: []string{"a"},
				Usage:   "Execute the migrations",
				Action:  func(c *cli.Context) error {
					return runMigration()
				},
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal().Err(err).Msg("Cant run application")
	}
}

func runMigration() error {
	log.Debug().Msg("Start Migration")
	db, err := sql.Open("mysql", "root:test@tcp(localhost:3306)/test?multiStatements=true")
	if err != nil {
		log.Fatal().Err(err).Msg("Cant conect to Database")
	}

	d, err := iofs.New(migrationFS, "database/migrations")

	if err != nil {
		log.Fatal().Err(err).Msg("Cant create iofs")
	}

	driver, err := mysql.WithInstance(db, &mysql.Config{})

	if err != nil {
		log.Fatal().Err(err).Msg("Cant create driver")
	}

	m, err := migrate.NewWithInstance(
		"iofs", d,
		"test", driver)

	if err != nil {
		log.Fatal().Err(err).Msg("Cant create migration object")
	}

	err = m.Up()
	if err != nil {
		log.Error().Err(err).Msg("Cant execute Migrations")
		return err
	}
	log.Info().Msg("Execute Migrations")
	return nil
}

func runWebpage() error {
	r := chi.NewRouter()
	render := render.New(render.Options{
		FileSystem: &render.EmbedFileSystem{
			FS: webserver,
		},
	})
	r.Use(middleware.Logger)

	r.Handle("/static/*", http.FileServer(http.FS(webserver)))
	r.Group(func(r chi.Router) {
		r.Use(TemplateMiddelware)
		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			render.HTML(w, http.StatusOK, "index", map[string]string {"title": "Soeren"})
		})

		tokenAuth := jwtauth.New("HS256", []byte("secret"), nil)
		uc := user.GetUserClient()


		sample.Register(r)
		user.Register(r, tokenAuth, uc)
	})


	http.ListenAndServe(":3000", r) //todo; handle this error
	return nil
}

