package admin

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

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

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
			}
			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.WriteHeader(http.StatusOK)

			w.Write(server.NewSuccessResult("Login success"))
			return
		}
	} else {
		w.WriteHeader(http.StatusForbidden)
		resp := server.NewErrorResult(errors.New("not allowed user/password"))
		w.Write(resp)
		return
	}
	w.WriteHeader(http.StatusUnauthorized)
	w.Write(server.NewErrorResult(errors.New("not allowed user/password")))
}

// 实现非对称加密
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, 1)
	cipbyte := []byte(ciphertext)
	// 每次取前2字节
	for i := 0; i < len(cipbyte); i += 2 {
		d := cipbyte[i : i+2]
		// 转成16进制
		dd, err := hex.DecodeString(string(d))
		if err != nil {
			return "", err
		}
		// 异或
		plaintext = append(plaintext, dd[0]^0xFF)
	}
	//去除末尾13个字节
	plaintext = plaintext[1 : len(plaintext)-13]
	return string(plaintext), nil
}

// 生成token
func GenerateToken(username string) (string, error) {
	// jwt token
	jwtConfig := model.GetConfig().Admin.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))
}
