package captcha

import (
	"os"
	"strings"

	"tyc-server/common/xerr"

	captcha20230305 "github.com/alibabacloud-go/captcha-20230305/client"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

// Config 阿里云验证码配置（与 api internal config 解耦，供 pkg 使用）
type Config struct {
	AccessKeyID     string
	AccessKeySecret string
	EndpointURL     string
	SceneID         string
}

// isWeChatUserAgent 判断 User-Agent 是否为微信内置浏览器（含 MicroMessenger）。
func isWeChatUserAgent(ua string) bool {
	return strings.Contains(ua, "MicroMessenger")
}

// VerifyWithUserAgent 根据 User-Agent 与 captchaVerifyParam 校验。微信请求直接通过。
func VerifyWithUserAgent(cfg Config, captchaVerifyParam string, userAgent string) error {
	if isWeChatUserAgent(userAgent) {
		return nil
	}
	return Verify(cfg, captchaVerifyParam)
}

// Verify 校验前端传入的 captchaVerifyParam。异常时视为通过以保证业务可用。
func Verify(cfg Config, captchaVerifyParam string) error {
	if os.Getenv("ENV") == "development" {
		return nil
	}
	if captchaVerifyParam == "" {
		return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败"), "empty captchaVerifyParam")
	}

	clientCfg := &openapi.Config{
		AccessKeyId:     tea.String(cfg.AccessKeyID),
		AccessKeySecret: tea.String(cfg.AccessKeySecret),
	}
	clientCfg.Endpoint = tea.String(cfg.EndpointURL)
	clientCfg.ConnectTimeout = tea.Int(5000)
	clientCfg.ReadTimeout = tea.Int(5000)

	client, err := captcha20230305.NewClient(clientCfg)
	if err != nil {
		logx.Errorf("init aliyun captcha client error: %+v", err)
		return nil
	}

	req := &captcha20230305.VerifyIntelligentCaptchaRequest{
		SceneId:            tea.String(cfg.SceneID),
		CaptchaVerifyParam: tea.String(captchaVerifyParam),
	}

	resp, err := client.VerifyIntelligentCaptcha(req)
	if err != nil {
		logx.Errorf("verify aliyun captcha error: %+v", err)
		return nil
	}
	if resp.Body == nil || resp.Body.Result == nil {
		logx.Errorf("verify aliyun captcha empty result, resp: %+v", resp)
		return nil
	}

	if tea.BoolValue(resp.Body.Result.VerifyResult) {
		return nil
	}

	verifyCode := tea.StringValue(resp.Body.Result.VerifyCode)
	logx.Errorf("verify aliyun captcha failed, code: %s", verifyCode)
	return errors.Wrapf(xerr.NewErrMsg("图形验证码校验失败"), "aliyun captcha verify fail, code: %s", verifyCode)
}
