package biz

import (
	"context"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	"strings"
	"time"
	v1 "voucher/api/v1"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/vo"
	"voucher/internal/pkg/lock"
)

func (this *VoucherBiz) CmbQuery(ctx context.Context, orderNo string) (resp *v1.CmbQueryReply, err error) {

	c := vo.CmbQueryLockKey.BuildCache([]string{orderNo})

	err = lock.NewMutex(this.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {

		order, err3 := this.OrderRepo.GetByOrderNo(ctx, orderNo)
		if err3 != nil {
			return err3
		}

		if err = this.Query(ctx, order); err != nil {
			return err
		}

		status, err3 := order.Status.GetCmbStatusText()
		if err3 != nil {
			return err3
		}

		resp = &v1.CmbQueryReply{
			Ticket:    order.OrderNo,
			Status:    status.GetValue(),
			TransDate: time.Now().Format("20060102150405"),
			OrgNo:     this.bc.Cmb.OrgNo,
			Ext:       "",
		}

		return nil
	})

	return
}

func (this *VoucherBiz) Query(ctx context.Context, order *bo.OrderBo) error {

	status, err := this.WechatCpnRepo.Query(ctx, order)
	if err != nil {
		return err
	}

	if order.Status == status {
		log.Warnf("券状态未改变:%s，忽略不处理,orderNo:%s", order.Status.GetText(), order.OrderNo)
		return nil
	}

	if err = this.UpdateOrderStatus(ctx, order.ID, status); err != nil {
		return err
	}

	order.Status = status

	return nil
}

func (this *VoucherBiz) QueryOrder(ctx context.Context, orderNo, isNotice string) (string, error) {

	order, err3 := this.OrderRepo.GetByOrderNo(ctx, orderNo)
	if err3 != nil {
		return "", err3
	}

	status, err := this.WechatCpnRepo.Query(ctx, order)
	if err != nil {
		return "", err
	}

	notifyStr := ""
	if isNotice == "YES" {
		notify, err := this.Cmb.Notify(ctx, order)
		if err != nil {
			return "", fmt.Errorf("查询通知招行失败:%s,orderNo:%s", err, order.OrderNo)
		}
		notifyStr = fmt.Sprintf("通知招行成功:notify_id:%d", notify.ID)
	}

	if order.Status != status {
		if err = this.UpdateOrderStatus(ctx, order.ID, status); err != nil {
			return "", err
		}
	}

	return this.ToTextDescription(order, status, notifyStr), nil
}

func (this *VoucherBiz) ToTextDescription(bo *bo.OrderBo, orderStatus vo.OrderStatus, notifyStr string) string {

	var parts []string

	// 拼接每个字段的描述（根据业务重要性调整顺序）
	parts = append(parts, fmt.Sprintf("订单ID：%d", bo.ID))
	parts = append(parts, fmt.Sprintf("订单编号：%s", bo.OrderNo))
	parts = append(parts, fmt.Sprintf("外部交易号：%s", bo.OutBizNo))
	parts = append(parts, fmt.Sprintf("券ID：%s", bo.VoucherNo))
	parts = append(parts, fmt.Sprintf("商品编号：%s", bo.ProductNo))
	parts = append(parts, fmt.Sprintf("批次号：%s", bo.BatchNo))
	parts = append(parts, fmt.Sprintf("活动ID：%s", bo.ActivityId))
	parts = append(parts, fmt.Sprintf("充值账号：%s", bo.Account))
	parts = append(parts, fmt.Sprintf("订单类型：%s", bo.Type.GetText())) // 假设 Type 有 GetText() 方法返回文字描述
	parts = append(parts, fmt.Sprintf("账号类型：%s", bo.AccountType.GetText()))
	parts = append(parts, fmt.Sprintf("appid：%s", bo.AppID))
	parts = append(parts, fmt.Sprintf("制券商户：%s", bo.MerchantNo))
	parts = append(parts, fmt.Sprintf("回调地址：%s", bo.NotifyUrl))
	parts = append(parts, fmt.Sprintf("渠道：%s", bo.Channel.GetText()))
	parts = append(parts, fmt.Sprintf("附加信息：%s", bo.Attach))
	parts = append(parts, fmt.Sprintf("备注：%s", bo.Remark))
	parts = append(parts, fmt.Sprintf("交易ID：%s", bo.TransactionId))
	parts = append(parts, fmt.Sprintf("订单状态：%s", bo.Status.GetText()))
	parts = append(parts, fmt.Sprintf("微信查询返回状态：%s", orderStatus.GetText()))

	// 时间字段特殊处理（避免 nil 指针报错）
	if bo.ReceiveSuccessTime != nil {
		parts = append(parts, fmt.Sprintf("到账时间：%s", bo.ReceiveSuccessTime.Format("2006-01-02 15:04:05")))
	} else {
		parts = append(parts, "到账时间：未到账")
	}

	if bo.LastUseTime != nil {
		parts = append(parts, fmt.Sprintf("最后使用时间：%s", bo.LastUseTime.Format("2006-01-02 15:04:05")))
	} else {
		parts = append(parts, "最后使用时间：未使用")
	}

	if bo.CreateTime != nil {
		parts = append(parts, fmt.Sprintf("创建时间：%s", bo.CreateTime.Format("2006-01-02 15:04:05")))
	} else {
		parts = append(parts, "创建时间：未知")
	}

	if bo.UpdateTime != nil {
		parts = append(parts, fmt.Sprintf("更新时间：%s", bo.UpdateTime.Format("2006-01-02 15:04:05")))
	} else {
		parts = append(parts, "更新时间：未更新")
	}

	if notifyStr != "" {
		parts = append(parts, fmt.Sprintf("通知结果：%s", notifyStr))
	}

	// 用换行符拼接所有片段，形成最终描述
	return strings.Join(parts, "\n")
}
