package controllers

import (
	"ai_developer_admin/libs/kong"
	"ai_developer_admin/libs/mysql"
	"ai_developer_admin/libs/utils"
	"ai_developer_admin/models"
	"encoding/json"
	"github.com/beego/beego/v2/core/logs"
	"net/http"
	"strings"
	"time"
)

type AppController struct {
	MainController
}

func (server *AppController) CreateApiKey() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Name == "" {
		server.respond(models.MissingParameter, "Missing name parameter")
		return
	}

	checkUser := &models.User{Id: info.UserID}
	err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
	if err != nil {
		server.respond(models.BusinessFailed, "user is not exist")
		return
	}
	data, err := kong.CreateApiKey(checkUser)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	if data.Id == "" {
		server.respond(models.BusinessFailed, data.Message)
		return
	}

	timestamp := time.Now()
	app := models.ApiKey{
		Name:        appRequest.Name,
		ApiKey:      data.Key,
		UserId:      checkUser.Id,
		CreatedTime: timestamp,
		UpdatedTime: timestamp,
		Deleted:     0,
		ApiKeyId:    data.Id,
	}
	mysql.GetMysqlInstace().Ormer.Insert(&app)
	server.respond(http.StatusOK, "")
}

func (server *AppController) ApiKeys() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest, string(body))
	//if err != nil {
	//	server.respond(models.NoRequestBody, err.Error())
	//	return
	//}

	if appRequest.Page == 0 {
		appRequest.Page = 1
	}

	if appRequest.Size == 0 {
		appRequest.Size = 10
	}
	offset := (appRequest.Page - 1) * appRequest.Size
	qs := mysql.GetMysqlInstace().Ormer.QueryTable("api_key").Filter("user_id", info.UserID)
	if info.Role == 1 || info.Role == 2 {
		qs = mysql.GetMysqlInstace().Ormer.QueryTable("api_key")
	}
	keyQs := qs.OrderBy("-created_time").Offset(offset).Limit(appRequest.Size)

	count, err := keyQs.Count()
	logs.Debug("Count = ", count)
	var keys []*models.ApiKey
	if count > 0 {
		keyQs.All(&keys)
	}
	total, err := qs.Count()
	responseData := struct {
		Total int64       `json:"total"`
		Data  interface{} `json:"data,omitempty"`
	}{
		Total: total,
		Data:  keys,
	}
	server.respond(http.StatusOK, "", responseData)
}

func (server *AppController) UpdateApikey() {
	_, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Id == 0 {
		server.respond(models.MissingParameter, "Missing id parameter")
		return
	}
	if appRequest.Name == "" {
		server.respond(models.MissingParameter, "Missing name parameter")
		return
	}
	apiKay := models.ApiKey{Id: appRequest.Id}
	err = mysql.GetMysqlInstace().Ormer.Read(&apiKay)
	if err != nil {
		server.respond(models.BusinessFailed, "api-key not exist")
		return
	}
	apiKay.Name = appRequest.Name

	_, err = mysql.GetMysqlInstace().Ormer.Update(&apiKay)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}

	server.respond(http.StatusOK, "success")
}

func (server *AppController) DelApiKey() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}

	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Id == 0 {
		server.respond(models.MissingParameter, "Missing id parameter")
		return
	}

	apiKay := models.ApiKey{Id: appRequest.Id}
	err = mysql.GetMysqlInstace().Ormer.Read(&apiKay)
	if err != nil {
		server.respond(models.BusinessFailed, "api-key not exist")
		return
	}

	data, err := kong.ListApikeys(info.Username)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	found := false
	for _, value := range data {
		if strings.Compare(value.Id, apiKay.ApiKeyId) == 0 {
			found = true
			break
		}
	}

	if found {
		err = kong.DelateApiKey(info.Username, apiKay.ApiKeyId)
		if err != nil {
			server.respond(models.BusinessFailed, "failed")
			return
		}
	}

	//if found {
	_, err = mysql.GetMysqlInstace().Ormer.Delete(&apiKay)
	if err != nil {
		server.respond(models.BusinessFailed, "failed")
		return
	}
	//}
	server.respond(http.StatusOK, "success")
}

func (server *AppController) CreateJWTToken() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}

	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Name == "" {
		server.respond(models.MissingParameter, "Missing name parameter")
		return
	}

	checkUser := &models.User{Id: info.UserID}
	err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
	if err != nil {
		server.respond(models.BusinessFailed, "user not exist")
		return
	}

	data, store, err := kong.CreateJwt(checkUser)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	if data.Id == "" {
		server.respond(models.BusinessFailed, data.Message)
		return
	}

	jwtToken, err := utils.GenerateKongToken(data, "")
	if err != nil {
		jwtToken = ""
	}
	timestamp := time.Now()
	app := models.JwtToken{
		Name:          appRequest.Name,
		JwtCredential: string(store),
		JwtToken:      jwtToken,
		UserId:        checkUser.Id,
		CreatedTime:   timestamp,
		UpdatedTime:   timestamp,
		Deleted:       0,
		JwtId:         data.Id,
	}

	mysql.GetMysqlInstace().Ormer.Insert(&app)

	server.respond(http.StatusOK, "")
}

func (server *AppController) JwtTokens() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest, string(body))
	//if err != nil {
	//	server.respond(models.NoRequestBody, err.Error())
	//	return
	//}

	if appRequest.Page == 0 {
		appRequest.Page = 1
	}

	if appRequest.Size == 0 {
		appRequest.Size = 10
	}
	offset := (appRequest.Page - 1) * appRequest.Size
	qs := mysql.GetMysqlInstace().Ormer.QueryTable("jwt_token").Filter("user_id", info.UserID)
	if info.Role == 1 || info.Role == 2 {
		qs = mysql.GetMysqlInstace().Ormer.QueryTable("jwt_token")
	}
	keyQs := qs.Offset(offset).Limit(appRequest.Size)
	count, err := keyQs.Count()
	logs.Debug("Count = ", count)
	var tokens []*models.JwtToken
	if count > 0 {
		keyQs.All(&tokens)
	}
	for _, value := range tokens {
		value.JwtCredential = ""
	}
	total, err := qs.Count()
	responseData := struct {
		Total int64       `json:"total"`
		Data  interface{} `json:"data,omitempty"`
	}{
		Total: total,
		Data:  tokens,
	}
	server.respond(http.StatusOK, "", responseData)
}

func (server *AppController) UpdateJWT() {
	_, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Id == 0 {
		server.respond(models.MissingParameter, "Missing id parameter")
		return
	}
	if appRequest.Name == "" {
		server.respond(models.MissingParameter, "Missing name parameter")
		return
	}
	token := models.JwtToken{Id: appRequest.Id}
	err = mysql.GetMysqlInstace().Ormer.Read(&token)
	if err != nil {
		server.respond(models.BusinessFailed, "JWT-token 不存在")
		return
	}
	token.Name = appRequest.Name

	_, err = mysql.GetMysqlInstace().Ormer.Update(&token)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}

	server.respond(http.StatusOK, "success")
}

func (server *AppController) DelJWT() {
	info, err := server.Check()
	if err != nil {
		server.respond(http.StatusUnauthorized, err.Error())
		return
	}

	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	if appRequest.Id == 0 {
		server.respond(models.MissingParameter, "Missing id parameter")
		return
	}

	jwt := models.JwtToken{Id: appRequest.Id}
	err = mysql.GetMysqlInstace().Ormer.Read(&jwt)
	if err != nil {
		server.respond(models.BusinessFailed, "jwt-token not exist")
		return
	}

	data, err := kong.ListJWT(info.Username)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	found := false
	for _, value := range data {
		if strings.Compare(value.Id, jwt.JwtId) == 0 {
			found = true
			break
		}
	}

	if found {
		err = kong.DelateJWT(info.Username, jwt.JwtId)
		if err != nil {
			server.respond(models.BusinessFailed, "failed")
			return
		}
	}

	//if found {
	_, err = mysql.GetMysqlInstace().Ormer.Delete(&jwt)
	if err != nil {
		server.respond(models.BusinessFailed, "failed")
		return
	}
	//}
	server.respond(http.StatusOK, "success")
}
