package api

import (
	"3dshow/conf"
	"3dshow/db"
	"3dshow/db/repo"
	"context"
	"fmt"

	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

type Service struct {
	Gin            *gin.Engine
	Mongo          *db.MongoDB
	Redis          *redis.Client
	Port           int32
	DebugUserId    string
	DebugUserPhone string
	DebugUserRole  string
	JWT            *UtilsJwt
	Conf           *conf.AppConf
}

func (svc *Service) Run() {
	svc.Gin.Run(fmt.Sprintf(":%d", svc.Port))
}

type ApiSession struct {
	Svc  *Service
	User *JWTUser
}

func (api *ApiSession) CreateRepoCtx() *repo.RepoSession {
	return &repo.RepoSession{
		Ctx:    context.Background(),
		Client: api.Svc.Mongo,
	}
}

func NewHttpService(app *conf.AppConf, dbMongo *db.MongoDB, redisClient *redis.Client) *Service {

	engine := gin.Default()

	store := cookie.NewStore([]byte("spu3d-server"))
	engine.Use(sessions.Sessions("dcsession", store))
	engine.Static("/public", "static")
	config := cors.DefaultConfig()
	// config.AllowOrigins == []string{"http://google.com", "http://facebook.com"}
	config.AllowAllOrigins = true
	config.AllowHeaders = append(config.AllowHeaders, "authorization")
	engine.Use(cors.New(config))

	jwt := NewUitlsJwt(app)

	s := &Service{Conf: app, Redis: redisClient, JWT: jwt, Gin: engine, Mongo: dbMongo, Port: app.Port, DebugUserId: app.Debug.UserId, DebugUserPhone: app.Debug.UserPhone, DebugUserRole: app.Debug.UserRole}

	RegRouters(s)

	return s
}

// GinRouter 路由
type GinRouter struct {
	group *gin.RouterGroup
	svc   *Service
}

func (svc *Service) NewGinRouter(path string) *GinRouter {
	return &GinRouter{group: svc.Gin.Group(path), svc: svc}
}

// RouterInterface 路由接口
type RouterInterface interface {
	GET(path string, httpHandler Handler)
	POST(path string, httpHandler Handler)
}

// GET http Get 请求
func (g GinRouter) GET(path string, httpHandler Handler) {
	g.group.GET(path, ResultWrapper(httpHandler, g.svc))
}

// POST http POST 请求
func (g GinRouter) POST(path string, httpHandler Handler) {
	g.group.POST(path, ResultWrapper(httpHandler, g.svc))
}

// GETJWT http Get 请求
func (g GinRouter) GETJWT(path string, httpHandler JWTHander) {
	g.group.GET(path, g.svc.JWT.MiddleFunc(), ResultJWTWrapper(httpHandler, g.svc))
}

// GETJWTTest http Get 请求
func (g GinRouter) GETJWTTest(path string, httpHandler JWTHander) {
	g.group.GET(path, ResultJWTTestWrapper(httpHandler, g.svc))
}

// POSTJWT http POST 请求
func (g GinRouter) POSTJWT(path string, httpHandler JWTHander) {
	g.group.POST(path, g.svc.JWT.MiddleFunc(), ResultJWTWrapper(httpHandler, g.svc))
}

// DeleteJWT http POST 请求
func (g GinRouter) DeleteJWT(path string, httpHandler JWTHander) {
	g.group.DELETE(path, g.svc.JWT.MiddleFunc(), ResultJWTWrapper(httpHandler, g.svc))
}

// DeleteJWT http POST 请求
func (g GinRouter) DeleteJWTTEST(path string, httpHandler JWTHander) {
	g.group.DELETE(path, ResultJWTTestWrapper(httpHandler, g.svc))
}

// POSTJWTTest 测试
func (g GinRouter) POSTJWTTest(path string, httpHandler JWTHander) {
	g.group.POST(path, ResultJWTTestWrapper(httpHandler, g.svc))
}


// 代参数判断权限
func (g GinRouter) GETJWTKEY(path string, httpHandler JWTHander, keys ...string) {
	g.group.GET(path, g.svc.JWT.MiddleFunc(), ResultJWTWrapperKey(httpHandler, g.svc, keys))
}

func (g GinRouter) POSTJWTKEY(path string, httpHandler JWTHander, keys ...string) {
	g.group.POST(path, g.svc.JWT.MiddleFunc(), ResultJWTWrapperKey(httpHandler, g.svc, keys))
}