package service

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"in-server/app/main/api/internal/config"
	tianyuanapi "in-server/app/main/api/internal/service/tianyuanapi_sdk"
	"net/http"

	"github.com/tidwall/gjson"
)

type VerificationService struct {
	c                 config.Config
	tianyuanapi       *tianyuanapi.Client
	apiRequestService *ApiRequestService
}

func NewVerificationService(c config.Config, tianyuanapi *tianyuanapi.Client, apiRequestService *ApiRequestService) *VerificationService {
	return &VerificationService{
		c:                 c,
		tianyuanapi:       tianyuanapi,
		apiRequestService: apiRequestService,
	}
}

// 二要素
type TwoFactorVerificationRequest struct {
	Name   string
	IDCard string
}
type TwoFactorVerificationResp struct {
	Msg     string                     `json:"msg"`
	Success bool                       `json:"success"`
	Code    int                        `json:"code"`
	Data    *TwoFactorVerificationData `json:"data"` //
}
type TwoFactorVerificationData struct {
	Birthday string `json:"birthday"`
	Result   int    `json:"result"`
	Address  string `json:"address"`
	OrderNo  string `json:"orderNo"`
	Sex      string `json:"sex"`
	Desc     string `json:"desc"`
}

// 三要素
type ThreeFactorVerificationRequest struct {
	Name   string
	IDCard string
	Mobile string
}

// VerificationResult 定义校验结果结构体
type VerificationResult struct {
	Passed bool
	Err    error
}

// ValidationError 定义校验错误类型
type ValidationError struct {
	Message string
}

func (e *ValidationError) Error() string {
	return e.Message
}

func (r *VerificationService) TwoFactorVerification(request TwoFactorVerificationRequest) (*VerificationResult, error) {
	resp, err := r.tianyuanapi.CallInterface("YYSYBE08", map[string]interface{}{
		"name":    request.Name,
		"id_card": request.IDCard,
	})
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}

	respBytes, err := json.Marshal(resp.Data)
	if err != nil {
		return nil, fmt.Errorf("转换响应失败: %v", err)
	}

	// 使用gjson获取resultCode
	resultCode := gjson.GetBytes(respBytes, "ctidRequest.ctidAuth.resultCode")
	if !resultCode.Exists() {
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "获取resultCode失败"},
		}, nil
	}

	// 获取resultCode的第一个字符
	resultCodeStr := resultCode.String()
	if len(resultCodeStr) == 0 {
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "resultCode为空"},
		}, nil
	}

	firstChar := string(resultCodeStr[0])
	if firstChar != "0" && firstChar != "5" {
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "姓名与身份证不一致"},
		}, nil
	}

	return &VerificationResult{Passed: true, Err: nil}, nil
}

func (r *VerificationService) ThreeFactorVerification(request ThreeFactorVerificationRequest) (*VerificationResult, error) {
	resp, err := r.tianyuanapi.CallInterface("YYSY09CD", map[string]interface{}{
		"name":      request.Name,
		"id_card":   request.IDCard,
		"mobile_no": request.Mobile,
	})
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}

	respBytes, err := json.Marshal(resp.Data)
	if err != nil {
		return nil, fmt.Errorf("转换响应失败: %v", err)
	}

	// 解析data.code
	code := gjson.GetBytes(respBytes, "code")
	if !code.Exists() {
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "身份信息异常"},
		}, nil
	}

	codeStr := code.String()
	switch codeStr {
	case "1000":
		// 一致
		return &VerificationResult{Passed: true, Err: nil}, nil
	case "1001":
		// 不一致
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "姓名、证件号、手机号信息不一致"},
		}, nil
	default:
		// 其他异常
		return &VerificationResult{
			Passed: false,
			Err:    &ValidationError{Message: "身份信息异常"},
		}, nil
	}
}

// GetWechatH5OpenID 通过code获取微信H5 OpenID
func (r *VerificationService) GetWechatH5OpenID(ctx context.Context, code string) (string, error) {
	appID := r.c.WechatH5.AppID
	appSecret := r.c.WechatH5.AppSecret
	url := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appID, appSecret, code)
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	var data struct {
		Openid string `json:"openid"`
	}
	if err := json.Unmarshal(body, &data); err != nil {
		return "", err
	}
	if data.Openid == "" {
		return "", fmt.Errorf("openid为空")
	}
	return data.Openid, nil
}

// GetWechatMiniOpenID 通过code获取微信小程序 OpenID
func (r *VerificationService) GetWechatMiniOpenID(ctx context.Context, code string) (string, error) {
	appID := r.c.WechatMini.AppID
	appSecret := r.c.WechatMini.AppSecret
	url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appID, appSecret, code)
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	var data struct {
		Openid string `json:"openid"`
	}
	if err := json.Unmarshal(body, &data); err != nil {
		return "", err
	}
	if data.Openid == "" {
		return "", fmt.Errorf("openid为空")
	}
	return data.Openid, nil
}
