package admin

import (
	"errors"
	"net/http"
	"time"

	"git.pyer.club/kingecg/gohttpd/server"
	"github.com/golang-jwt/jwt/v5"
	"pyer.club/kingecg/gohttpd/model"
)

type LoginModel struct {
	Username string `json:"username"`
	Encrypt  string `json:"password"`
}

func login(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	ctxData := ctx.Value(server.RequestCtxKey("data")).(map[string]interface{})
	data, ok := ctxData["data"]
	if !ok {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	t := data.(LoginModel)
	if t.Username == "admin" {
		decryptText, _ := Decrypt(t.Encrypt)
		if decryptText == model.GetConfig().Admin.Password {
			token, err := GenerateToken(t.Username)
			if err != nil {
				w.WriteHeader(http.StatusInternalServerError)
				w.Write(server.NewErrorResult(err))
				return
			}
			w.WriteHeader(http.StatusOK)
			http.SetCookie(w, &http.Cookie{
				Name:     "token",
				Value:    token,
				Path:     "/",
				HttpOnly: true,
				Secure:   true,
				SameSite: http.SameSiteStrictMode,
				Expires:  time.Now().Add(time.Hour * 24 * 7),
			})
			w.Write(server.NewSuccessResult(token))
		}
	} else {
		w.WriteHeader(http.StatusForbidden)
		resp := server.NewErrorResult(errors.New("Not allowed user/password"))
		w.Write(resp)
	}
	return
}

// 实现非对称加密
func Encrypt(plaintext string) (string, error) {
	ciphertext := make([]byte, len(plaintext))
	for i := 0; i < len(plaintext); i++ {
		ciphertext[i] = plaintext[i] ^ 0xFF
	}
	return string(ciphertext), nil
}

// 实现非对称解密
func Decrypt(ciphertext string) (string, error) {
	plaintext := make([]byte, len(ciphertext))
	for i := 0; i < len(ciphertext); i++ {
		plaintext[i] = ciphertext[i] ^ 0xFF
	}
	//去除末尾13个字节
	plaintext = plaintext[:len(plaintext)-13]
	return string(plaintext), nil
}

// 生成token
func GenerateToken(username string) (string, error) {
	// jwt token
	jwtConfig := model.GetConfig().Jwt
	secret := jwtConfig.Secret
	expire := jwtConfig.Expire
	issuer := jwtConfig.Issuer
	audience := jwtConfig.Audience
	claim := &jwt.RegisteredClaims{
		ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expire) * time.Hour)),
		Issuer:    issuer,
		Audience:  []string{audience},
		IssuedAt:  jwt.NewNumericDate(time.Now()),
		Subject:   username,
	}
	// 生成token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
	return token.SignedString([]byte(secret))
}
