package query

import (
	"context"
	"database/sql"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"os"
	"time"
	"tyc-server/app/main/api/internal/service"
	"tyc-server/app/main/model"
	"tyc-server/common/ctxdata"
	"tyc-server/common/globalkey"
	"tyc-server/common/xerr"
	"tyc-server/pkg/captcha"
	"tyc-server/pkg/lzkit/crypto"
	"tyc-server/pkg/lzkit/validator"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/stores/redis"

	"tyc-server/app/main/api/internal/svc"
	"tyc-server/app/main/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type QueryServiceLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewQueryServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServiceLogic {
	return &QueryServiceLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *QueryServiceLogic) QueryService(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) {
	if req.AgentIdentifier != "" {
		l.ctx = context.WithValue(l.ctx, "agentIdentifier", req.AgentIdentifier)
	} else if req.App {
		l.ctx = context.WithValue(l.ctx, "app", req.App)
	}
	return l.PreprocessLogic(req, req.Product)
}

// queryHandlerFunc 通用查询 handler：解密后的数据 + 产品名 -> 校验并返回待缓存的 params
// 新增产品时只需在 productHandlers 里加一行并选用已有 handler 类型即可，无需再写 ProcessXxx
type queryHandlerFunc func(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error)

var productHandlers = map[string]queryHandlerFunc{
	"marriage":               runMarriageReq,
	"homeservice":            runMarriageReq,
	"riskassessment":         runMarriageReq,
	"companyinfo":            runMarriageReq,
	"rentalinfo":             runMarriageReq,
	"preloanbackgroundcheck": runMarriageReq,
	"backgroundcheck":        runMarriageReq,
	"personalData":           runMarriageReq,
	"toc_PersonalBadRecord":  runPersonalBadRecordReq,
	"toc_PersonalLawsuit":    runMarriageReq,
	"toc_EnterpriseLawsuit":  runEntLawsuitReq,
	// 人企关系加强版：仅身份证号
	"toc_PersonEnterprisePro": runPersonEnterpriseProReq,
	// 新司法涉诉类产品
	"toc_EnterpriseLawsuitQYGL66SL":       runEnterpriseLawsuitSimpleReq,
	"toc_LimitHighExecuted":               runLimitHighExecutedReq,
	"toc_DishonestExecutedPerson":         runDishonestExecutedReq,
	"toc_Marriage":                        runMarriageReq,
	"toc_PersonalMarriageStatus":          runMarriageReq,
	"toc_MarriageStatusRegisterTime":      runMarriageReq,
	"toc_MarriageStatusSupplement":        runMarriageReq,
	"toc_MarriageStatusVerify":            runMarriageReq,
	"toc_DualMarriageStatusRegisterTime":  runDualMarriageReq,
	"toc_VehiclesUnderName":               runMarriageReq,
	"toc_VehiclesUnderNamePlate":          runMarriageReq,
	"toc_PersonVehicleVerification":       runPersonVehicleVerificationReq,
	"toc_PersonVehicleVerificationDetail": runPersonVehicleVerificationReq,
	// 车辆类产品（按 md 传参）
	"toc_VehiclesUnderNameCount":   runVehiclesUnderNameCountReq,
	"toc_VehicleStaticInfo":        runVehicleVinCodeReq,
	"toc_VehicleMileageMixed":      runVehicleMileageMixedReq,
	"toc_VehicleVinValuation":      runVehicleVinValuationReq,
	"toc_VehicleTransferSimple":    runVehicleTransferSimpleReq,
	"toc_VehicleTransferDetail":    runVehicleVinCodeReq,
	"toc_VehicleMaintenanceSimple": runVehicleMaintenanceSimpleReq,
	"toc_VehicleMaintenanceDetail": runVehicleMaintenanceDetailReq,
	"toc_VehicleClaimDetail":       runVehicleClaimDetailReq,
	"toc_VehicleClaimVerify":       runVehicleClaimVerifyReq,
	// 核验工具（verify feature.md）
	"toc_PoliceTwoFactors":                 runVerifyAuthTwoReq,
	"toc_PoliceThreeFactors":               runVerifyAuthThreeReq,
	"toc_ProfessionalCertificate":          runVerifyCertReq,
	"toc_PersonalConsumptionCapacityLevel": runVerifyConsumptionReq, // 个人消费能力（沿用现有 product_en）
	"toc_OperatorTwoFactors":               runVerifyYysTwoReq,
	"toc_MobileThreeFactors":               runVerifyYysThreeReq,
	"toc_NumberRecycle":                    runVerifyMobileOnlyReq,
	"toc_MobileEmptyCheck":                 runVerifyMobileOnlyReq,
	"toc_MobilePortability":                runVerifyMobileOnlyReq,
	"toc_MobileOnlineStatus":               runVerifyMobileOnlyReq,
	"toc_MobileOnlineDuration":             runVerifyMobileOnlyReq,
	"toc_MobileAttribution":                runVerifyMobileOnlyReq,
	"toc_MobileConsumptionRange":           runVerifyYysConsumptionReq,
	"toc_EnterpriseRelation":               runVerifyEntRelationReq,
	"toc_BankcardFourFactors":              runVerifyBankFourReq,
	"toc_BankcardBlacklist":                runVerifyBankBlackReq,
}

// productHasSmsCode 表示该 product 解密后的请求结构体中是否包含必填短信验证码 Code。
// 有 Code 的产品在「获取验证码」时已经做了滑块，这里不再强制要求 CaptchaVerifyParam。
// 其他产品（无 Code）在查询时必须传并校验 CaptchaVerifyParam，防止跳过图形验证。
func productHasSmsCode(product string) bool {
	switch product {
	case "marriage",
		"homeservice",
		"riskassessment",
		"companyinfo",
		"rentalinfo",
		"preloanbackgroundcheck",
		"backgroundcheck",
		"personalData",
		"toc_PersonalLawsuit",
		"toc_EnterpriseLawsuit",
		"toc_Marriage",
		"toc_PersonalMarriageStatus",
		"toc_MarriageStatusRegisterTime",
		"toc_MarriageStatusSupplement",
		"toc_MarriageStatusVerify",
		"toc_DualMarriageStatusRegisterTime",
		"toc_VehiclesUnderName",
		"toc_VehiclesUnderNamePlate":
		return true
	default:
		return false
	}
}

func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product string) (*types.QueryServiceResp, error) {
	// 无短信验证码 Code 的 product：查询前必须传并校验滑块，否则不允许跳过
	if !productHasSmsCode(product) {
		if req.CaptchaVerifyParam == "" {
			return nil, errors.Wrapf(xerr.NewErrMsg("请完成图形验证"), "product %s requires captcha", product)
		}
		cfg := l.svcCtx.Config.Captcha
		if err := captcha.Verify(captcha.Config{
			AccessKeyID:     cfg.AccessKeyID,
			AccessKeySecret: cfg.AccessKeySecret,
			EndpointURL:     cfg.EndpointURL,
			SceneID:         cfg.SceneID,
		}, req.CaptchaVerifyParam); err != nil {
			return nil, err
		}
	}

	decryptData, err := l.DecryptData(req.Data)
	if err != nil {
		return nil, err
	}
	handler, exists := productHandlers[product]
	if !exists {
		return nil, errors.New("未找到相应的处理程序")
	}
	params, err := handler(l, decryptData, product)
	if err != nil {
		return nil, err
	}
	return l.commonQueryTail(params, product)
}

// commonQueryTail 通用收尾：写缓存、生成 token 并返回
func (l *QueryServiceLogic) commonQueryTail(params map[string]interface{}, product string) (*types.QueryServiceResp, error) {
	userID, err := l.GetOrCreateUser()
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 处理用户失败: %v", err)
	}
	cacheNo, cacheDataErr := l.CacheData(params, product, userID)
	if cacheDataErr != nil {
		return nil, cacheDataErr
	}
	token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
	}
	now := time.Now().Unix()
	return &types.QueryServiceResp{
		Id:           cacheNo,
		AccessToken:  token,
		AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
		RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
	}, nil
}

// runMarriageReq 姓名+身份证+手机+验证码 类产品（婚恋、家政、司法涉诉、婚姻状况、名下车辆等）
func runMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.MarriageReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
		return nil, verifyCodeErr
	}
	if verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile); verifyErr != nil {
		return nil, verifyErr
	}
	return map[string]interface{}{
		"name":    data.Name,
		"id_card": data.IDCard,
		"mobile":  data.Mobile,
	}, nil
}

// runEntLawsuitReq 企业司法涉诉：企业名称+统一社会信用代码+手机+验证码
func runEntLawsuitReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.EntLawsuitReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
		return nil, verifyCodeErr
	}
	return map[string]interface{}{
		"ent_name": data.EntName,
		"ent_code": data.EntCode,
		"mobile":   data.Mobile,
	}, nil
}

// 企业司法涉诉简版 QYGL66SL：仅企业名称，auth_date 与授权文件编码由后端自动生成
func runEnterpriseLawsuitSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.EnterpriseLawsuitSimpleReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	now := time.Now()
	start := now.AddDate(0, 0, -7)
	end := now.AddDate(0, 0, 7)
	authDate := fmt.Sprintf("%s-%s", start.Format("20060102"), end.Format("20060102"))
	return map[string]interface{}{
		"ent_name":                 data.EntName,
		"auth_date":                authDate,
		"auth_authorize_file_code": "AUTHTYC0001",
	}, nil
}

// 限高被执行人 FLXG3A9B
func runLimitHighExecutedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.LimitHighExecutedReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	auth := data.Authorized
	if auth == "" {
		auth = "1"
	}
	return map[string]interface{}{
		"name":       data.Name,
		"id_card":    data.IDCard,
		"mobile_no":  data.Mobile,
		"authorized": auth,
	}, nil
}

// 本人不良 FLXGDEA9：姓名 + 身份证（授权由 ApiRequest 默认传 1）
func runPersonalBadRecordReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.PersonalBadRecordReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	return map[string]interface{}{
		"name":    data.Name,
		"id_card": data.IDCard,
	}, nil
}

// 失信被执行人 QYGL2S0W
func runDishonestExecutedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.DishonestExecutedReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	tp := data.Type
	if tp == "" {
		tp = "per"
	}
	return map[string]interface{}{
		"type":    tp,
		"name":    data.Name,
		"id_card": data.IDCard,
	}, nil
}

// runDualMarriageReq 双人婚姻状态：男方/女方姓名+身份证+手机+验证码
func runDualMarriageReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocDualMarriageReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
		return nil, verifyCodeErr
	}
	if verifyErr := l.VerifyTwo(data.NameMan, data.IDCardMan); verifyErr != nil {
		return nil, verifyErr
	}
	if verifyErr := l.VerifyTwo(data.NameWoman, data.IDCardWoman); verifyErr != nil {
		return nil, verifyErr
	}
	return map[string]interface{}{
		"name":          data.NameMan,
		"id_card":       data.IDCardMan,
		"mobile":        data.Mobile,
		"name_man":      data.NameMan,
		"id_card_man":   data.IDCardMan,
		"name_woman":    data.NameWoman,
		"id_card_woman": data.IDCardWoman,
	}, nil
}

// runPersonVehicleVerificationReq 人车核验简版：姓名+号牌类型+车牌号
func runPersonVehicleVerificationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocPersonVehicleVerification
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}

	return map[string]interface{}{
		"name":          data.Name,
		"plate_no":      data.CarLicense,
		"carplate_type": data.CarType,
	}, nil
}

// runVehiclesUnderNameCountReq 名下车辆(数量) QCXG4D2E：仅 user_type + id_card
func runVehiclesUnderNameCountReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehiclesUnderNameCountReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	userType := data.UserType
	if userType == "" {
		userType = "1"
	}
	return map[string]interface{}{
		"user_type": userType,
		"id_card":   data.IDCard,
	}, nil
}

// runVehicleVinCodeReq 仅 vin_code（车辆静态信息、过户详版等）
func runVehicleVinCodeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleVinCodeReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	return map[string]interface{}{
		"vin_code": data.VinCode,
	}, nil
}

// runVehicleMileageMixedReq 车辆里程记录(混合) QCXG1U4U
func runVehicleMileageMixedReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleMileageMixedReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	// 回调地址由后端在 ApiRequestService 中统一生成，此处不再下发 return_url
	return map[string]interface{}{
		"vin_code":  data.VinCode,
		"image_url": data.ImageURL,
	}, nil
}

// runVehicleVinValuationReq 二手车VIN估值 QCXGY7F2（仅必填）
func runVehicleVinValuationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleVinValuationReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	return map[string]interface{}{
		"vin_code":               data.VinCode,
		"vehicle_location":       data.VehicleLocation,
		"first_registrationdate": data.FirstRegistrationDate,
	}, nil
}

// runVehicleTransferSimpleReq 车辆过户简版 QCXG1H7Y（仅必填 vin_code）
func runVehicleTransferSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleTransferSimpleReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	return map[string]interface{}{"vin_code": data.VinCode}, nil
}

// runVehicleMaintenanceSimpleReq 车辆维保简版 QCXG3Y6B（仅必填 vin_code；回调地址后端自动生成）
func runVehicleMaintenanceSimpleReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleMaintenanceSimpleReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	// 回调地址由后端在 ApiRequestService 中统一生成，此处不再下发 return_url
	return map[string]interface{}{
		"vin_code": data.VinCode,
	}, nil
}

// runVehicleMaintenanceDetailReq 车辆维保详细版 QCXG3Z3L（仅必填 vin_code；回调地址后端自动生成）
func runVehicleMaintenanceDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleMaintenanceDetailReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	// 回调地址由后端在 ApiRequestService 中统一生成，此处不再下发 return_url
	return map[string]interface{}{
		"vin_code": data.VinCode,
	}, nil
}

// runVehicleClaimDetailReq 车辆出险详版 QCXGP00W（仅必填 vin_code, vlphoto_data；回调地址后端自动生成），vlphoto_data 由 API 层加密为 data
func runVehicleClaimDetailReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleClaimDetailReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	// 回调地址由后端在 ApiRequestService 中统一生成，此处不再下发 return_url
	return map[string]interface{}{
		"vin_code":     data.VinCode,
		"vlphoto_data": data.VlphotoData,
	}, nil
}

// runVehicleClaimVerifyReq 车辆出险记录核验 QCXG6B4E
func runVehicleClaimVerifyReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVehicleClaimVerifyReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	if data.Mobile != "" && data.Code != "" {
		if verifyCodeErr := l.VerifyCode(data.Mobile, data.Code); verifyCodeErr != nil {
			return nil, verifyCodeErr
		}
	}
	auth := data.Authorized
	if auth == "" {
		auth = "1"
	}
	return map[string]interface{}{
		"vin_code":   data.VINCode,
		"authorized": auth,
	}, nil
}

// runPersonEnterpriseProReq 人企关系加强版预查询：仅身份证号
func runPersonEnterpriseProReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocPersonEnterpriseProReq
	if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", unmarshalErr)
	}
	if validatorErr := validator.Validate(data); validatorErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "查询服务, 参数不正确: %+v", validatorErr)
	}
	return map[string]interface{}{
		"id_card": data.IDCard,
	}, nil
}

// --------------- 核验工具 handlers ---------------
func runVerifyAuthTwoReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyAuthTwoReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil
}

func runVerifyAuthThreeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyAuthThreeReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"photo_data": data.PhotoData, "id_card": data.IDCard, "name": data.Name}, nil
}

func runVerifyCertReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyCertReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"id_card": data.IDCard, "name": data.Name}, nil
}

func runVerifyConsumptionReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyConsumptionReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil
}

func runVerifyYysTwoReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyYysTwoReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo, "name": data.Name}, nil
}

func runVerifyYysThreeReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyYysThreeReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo, "id_card": data.IDCard, "name": data.Name}, nil
}

func runVerifyMobileOnlyReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyMobileOnlyReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo}, nil
}

func runVerifyYysConsumptionReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyYysConsumptionReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{"mobile_no": data.MobileNo, "authorized": data.Authorized}, nil
}

func runVerifyEntRelationReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyEntRelationReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	out := map[string]interface{}{}
	if data.IDCard != "" {
		out["id_card"] = data.IDCard
	}
	return out, nil
}

func runVerifyBankFourReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyBankFourReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{
		"mobile_no": data.MobileNo,
		"id_card":   data.IDCard,
		"bank_card": data.BankCard,
		"name":      data.Name,
	}, nil
}

func runVerifyBankBlackReq(l *QueryServiceLogic, decryptData []byte, product string) (map[string]interface{}, error) {
	var data types.TocVerifyBankBlackReq
	if err := json.Unmarshal(decryptData, &data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %+v", err)
	}
	if err := validator.Validate(data); err != nil {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, err.Error()), "查询服务, 参数不正确: %+v", err)
	}
	return map[string]interface{}{
		"mobile_no": data.MobileNo,
		"id_card":   data.IDCard,
		"name":      data.Name,
		"bank_card": data.BankCard,
	}, nil
}

func (l *QueryServiceLogic) DecryptData(data string) ([]byte, error) {
	secretKey := l.svcCtx.Config.Encrypt.SecretKey
	key, decodeErr := hex.DecodeString(secretKey)
	if decodeErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "密钥获取失败: %+v", decodeErr)
	}
	decryptData, aesDecryptErr := crypto.AesDecrypt(data, key)
	if aesDecryptErr != nil || len(decryptData) == 0 {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密失败: %+v", aesDecryptErr)
	}
	return decryptData, nil
}

// 校验验证码（开发环境 ENV=development 可跳过）
func (l *QueryServiceLogic) VerifyCode(mobile string, code string) error {
	if os.Getenv("ENV") == "development" {
		return nil
	}
	secretKey := l.svcCtx.Config.Encrypt.SecretKey
	encryptedMobile, err := crypto.EncryptMobile(mobile, secretKey)
	if err != nil {
		return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "加密手机号失败: %+v", err)
	}
	codeRedisKey := fmt.Sprintf("%s:%s", "query", encryptedMobile)
	cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
	if err != nil {
		if errors.Is(err, redis.Nil) {
			return errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "验证码过期: %s", mobile)
		}
		return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "读取验证码redis缓存失败, mobile: %s, err: %+v", mobile, err)
	}
	if cacheCode != code {
		return errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "验证码不正确: %s", mobile)
	}
	return nil
}

func (l *QueryServiceLogic) IsAgentQuery() bool {
	agentID, _ := l.ctx.Value("agentIdentifier").(string)
	return agentID != ""
}

// 二要素验证（仅姓名+身份证号）（开发环境不调用验证 API）
func (l *QueryServiceLogic) VerifyTwo(Name string, IDCard string) error {
	if os.Getenv("ENV") == "development" {
		return nil
	}
	twoVerification := service.TwoFactorVerificationRequest{
		Name:   Name,
		IDCard: IDCard,
	}
	verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
	if err != nil {
		return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %v", err)
	}
	if !verification.Passed {
		return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %v", err)
	}
	return nil
}

// 按代理/非代理切换要素验证：代理走三要素；非代理走二要素（开发环境不调用验证 API）
func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) error {
	if os.Getenv("ENV") == "development" {
		return nil
	}
	if !l.IsAgentQuery() {
		twoVerification := service.TwoFactorVerificationRequest{
			Name:   Name,
			IDCard: IDCard,
		}
		verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %v", err)
		}
		if !verification.Passed {
			return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %v", err)
		}
	} else {
		// 三要素验证
		if Mobile == "" {
			return errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, "手机号不能为空"), "三要素验证参数不正确: mobile为空")
		}
		threeVerification := service.ThreeFactorVerificationRequest{
			Name:   Name,
			IDCard: IDCard,
			Mobile: Mobile,
		}
		verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
		if err != nil {
			return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %v", err)
		}
		if !verification.Passed {
			return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err)
		}
	}
	return nil
}

// 缓存
func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product string, userID int64) (string, error) {
	agentIdentifier, _ := l.ctx.Value("agentIdentifier").(string)
	secretKey := l.svcCtx.Config.Encrypt.SecretKey
	key, decodeErr := hex.DecodeString(secretKey)
	if decodeErr != nil {
		return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr)
	}
	paramsMarshal, marshalErr := json.Marshal(params)
	if marshalErr != nil {
		return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 序列化参数失败: %+v", marshalErr)
	}
	encryptParams, aesEncryptErr := crypto.AesEncrypt(paramsMarshal, key)
	if aesEncryptErr != nil {
		return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 加密参数失败: %+v", aesEncryptErr)
	}
	queryCache := types.QueryCacheLoad{
		Params:          encryptParams,
		Product:         Product,
		AgentIdentifier: agentIdentifier,
	}
	jsonData, marshalErr := json.Marshal(queryCache)
	if marshalErr != nil {
		return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 序列化参数失败: %+v", marshalErr)
	}
	outTradeNo := "Q_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
	redisKey := fmt.Sprintf(types.QueryCacheKey, userID, outTradeNo)
	cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
	if cacheErr != nil {
		return "", cacheErr
	}

	// 写入 query_user_record，用于后台按被查询人姓名/身份证/手机号追溯订单（见 query_user_record.sql 说明 1）
	nameStr, _ := params["name"].(string)
	idCardStr, _ := params["id_card"].(string)
	mobileStr, _ := params["mobile"].(string)
	if nameStr != "" || idCardStr != "" || mobileStr != "" {
		var encName, encIdCard, encMobile string
		if nameStr != "" {
			encName, _ = crypto.AesEcbEncrypt([]byte(nameStr), key)
		}
		if idCardStr != "" {
			encIdCard, _ = crypto.EncryptIDCard(idCardStr, key)
		}
		if mobileStr != "" {
			encMobile, _ = crypto.EncryptMobile(mobileStr, secretKey)
		}
		agentIdent := sql.NullString{}
		if agentIdentifier != "" {
			agentIdent = sql.NullString{String: agentIdentifier, Valid: true}
		}
		rec := &model.QueryUserRecord{
			DeleteTime:      sql.NullTime{},
			DelState:        globalkey.DelStateNo,
			Version:         0,
			UserId:          userID,
			Name:            encName,
			IdCard:          encIdCard,
			Mobile:          encMobile,
			Product:         Product,
			QueryNo:         outTradeNo,
			OrderId:         0,
			PlatformOrderId: sql.NullString{},
			AgentIdentifier: agentIdent,
		}
		_, insertErr := l.svcCtx.QueryUserRecordModel.Insert(l.ctx, nil, rec)
		if insertErr != nil {
			logx.WithContext(l.ctx).Errorf("CacheData 写入 query_user_record 失败: %v", insertErr)
		}
	}

	return outTradeNo, nil
}

// GetOrCreateUser 获取或创建用户
// 1. 如果上下文中已有用户ID，直接返回
// 2. 如果是代理查询或APP请求，创建新用户
// 3. 其他情况返回未登录错误
func (l *QueryServiceLogic) GetOrCreateUser() (int64, error) {
	// 尝试获取用户ID
	claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
	if err != nil {
		return 0, err
	}
	userID := claims.UserId
	return userID, nil

	// // 如果不是未登录错误，说明是其他错误，直接返回
	// if !ctxdata.IsNoUserIdError(err) {
	// 	return 0, err
	// }

	// // 检查是否是代理查询或APP请求
	// isAgentQuery := false
	// if agentID, ok := l.ctx.Value("agentIdentifier").(string); ok && agentID != "" {
	// 	isAgentQuery = true
	// }
	// if app, ok := l.ctx.Value("app").(bool); ok && app {
	// 	isAgentQuery = true
	// }

	// // 如果不是代理查询或APP请求，返回未登录错误
	// if !isAgentQuery {
	// 	return 0, ctxdata.ErrNoUserIdInCtx
	// }

	// // 创建新用户
	// return l.svcCtx.UserService.RegisterUUIDUser(l.ctx)
}
