package handler

import (
	"encoding/json"
	"fmt"
	"github.com/parnurzeal/gorequest"
	"net/http"
	"strings"
	"time"
)

// KfzHandler Kfz处理器
type KfzHandler struct {
}

// NewKfzHandler 创建Kfz处理器实例
func NewKfzHandler() *KfzHandler {
	return &KfzHandler{}
}

// KfzLogin 登录孔网并返回用户信息
func (h *KfzHandler) KfzLogin(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(32 << 20)
	username := r.PostForm.Get("username")
	password := r.PostForm.Get("password")

	if username == "" || password == "" {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(`{"code":500,"message":"username和password不能为空"}`))
		return
	}

	token, err := outKfzLogin(username, password)
	if err != nil {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
		return
	}

	userInfo, err := outKfzGetUserInfo(token)
	if err != nil {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
		return
	}

	userInfo.Token = token

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"code":    200,
		"message": "success",
		"data":    userInfo,
	})
}

/*
 * 孔网登录
 * param username[string] 孔网用户名
 * param password[string] 孔网密码
 * return token,错误信息
 * Error 登录请求失败
 * Error 登录失败(HTTP状态码: %d)
 * Error 登录成功但未获取到Cookie
 * Error 登录失败: 未找到 PHPSESSID
 * Error 账号或密码错误
 * Error 登录失败
 * Error 登录失败，未知错误！
 */
func outKfzLogin(username, password string) (string, error) {
	// 检查用户名和密码是否为空
	if username == "" || password == "" {
		return "", fmt.Errorf("请输入用户名和密码!")
	}

	// 准备POST请求的表单数据
	formData := map[string]string{
		"loginName": username,
		"loginPass": password,
		"returnUrl": "http://user.kongfz.com/",
	}
	// 孔网登录URL
	loginUrl := "https://login.kongfz.com/Pc/Login/account"

	// 发送登录请求
	resp, body, errs := gorequest.New().
		Post(loginUrl).
		Set("Content-Type", "application/x-www-form-urlencoded").
		Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36").
		Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8").
		Send(formData).
		Timeout(15 * time.Second).
		End()

	// 请求错误处理
	if len(errs) > 0 {
		return "", fmt.Errorf("登录请求失败: %v", errs)
	}

	// 检查HTTP状态码
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("登录失败(HTTP状态码: %d)", resp.StatusCode)
	}

	// 提取Cookie
	cookie := resp.Header.Get("Set-Cookie")
	// 检查是否登录成功（通过响应内容判断）
	if strings.Contains(body, "window.location.href='https://login.kongfz.cn/Pc/Session/rsync") {
		if cookie == "" {
			return "", fmt.Errorf("登录成功但未获取到Cookie")
		}

		// 登录成功
		if strings.Contains(cookie, "PHPSESSID=") {
			token := strings.Split(strings.Split(cookie, "PHPSESSID=")[1], ";")[0]
			return token, nil
		}

		return "", fmt.Errorf("登录失败: 未找到PHPSESSID")
	}

	// 错误信息
	var res struct {
		Status  bool   `json:"status"`
		ErrCode int    `json:"errCode"`
		ErrInfo string `json:"errInfo"`
	}
	// 解析json
	if err := json.Unmarshal([]byte(body), &res); err == nil {
		if res.ErrCode == 1001 || res.ErrCode == 1005 {
			return "", fmt.Errorf("账号或密码错误！")
		}

		if res.ErrInfo != "" {
			return "", fmt.Errorf("登录失败: %s", res.ErrInfo)
		}
	}

	return "", fmt.Errorf("登录失败，未知错误！")
}

// UserInfo 孔网用户信息结构体
type UserInfo struct {
	UserID   int64  `json:"userId"`   // 用户ID
	Nickname string `json:"nickname"` // 用户昵称
	Mobile   string `json:"mobile"`   // 手机号
	Token    string `json:"token"`    // token
}

/*
 * 获取孔网用户信息
 * param token[string] 孔网token
 * return 孔网用户信息结构体,错误信息
 * Error 查询请求失败
 * Error HTTP错误
 * Error 解析JSON失败
 * Error 获取用户失败
 */
func outKfzGetUserInfo(token string) (*UserInfo, error) {
	// 用户信息URL
	url := "https://user.kongfz.com/User/Index/getUserInfo/"

	// 发送请求
	resp, body, errs := gorequest.New().
		Get(url).
		Set("Cookie", fmt.Sprintf("PHPSESSID=%s", token)).
		Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
		Set("Accept", "application/json, text/plain, */*").
		Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
		Timeout(15 * time.Second).
		End()
	if len(errs) > 0 {
		return nil, fmt.Errorf("查询用户信息请求失败: %v", errs)
	}

	//检查HTTP状态码
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("HTTP错误: %s", resp.Status)
	}

	// 响应数据
	var userInfo struct {
		Status bool `json:"status"`
		Data   struct {
			UserID   int64  `json:"userId"`
			Nickname string `json:"nickname"`
			Mobile   string `json:"mobile"`
		}
	}
	// 解析json
	if err := json.Unmarshal([]byte(body), &userInfo); err != nil {
		return nil, fmt.Errorf("解析JSON失败: %w", err)
	}

	// 创建用户信息对象
	user := &UserInfo{}
	if !userInfo.Status {
		return nil, fmt.Errorf("获取用户失败！")
	}
	user.UserID = userInfo.Data.UserID
	user.Nickname = userInfo.Data.Nickname
	user.Mobile = userInfo.Data.Mobile
	return user, nil
}
