package com.jeesharp.business.modules.food.application.support;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jeesharp.business.modules.food.entity.FoodBookingOrder;
import com.jeesharp.business.modules.food.entity.FoodPackage;
import com.jeesharp.business.modules.food.entity.FoodRestaurant;
import com.jeesharp.business.modules.food.service.FoodPackageService;
import com.jeesharp.business.modules.food.service.FoodRestaurantService;
import com.jeesharp.business.modules.food.vo.FoodBookingResultVO;
import com.jeesharp.business.modules.food.vo.FoodPayPrepareVO;
import com.jeesharp.business.modules.food.vo.FoodPayStatusVO;
import com.jeesharp.business.modules.pay.support.VerticalPayPrepareSupport;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;

/**
 * 美食团购预支付 VO 组装（Application 层，依赖门店/套餐领域服务补全展示与金额）。
 *
 * @author jeesharp
 * @since 2026-06-09
 */
@Component
@AllArgsConstructor
public class FoodBookingPayAssembler {

    private static final String EMPTY_JSON_OBJECT = "{}";
    private static final String ATTACH_BIZ_TYPE = "food";
    private static final DateTimeFormatter DT_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final FoodPackageService foodPackageService;
    private final FoodRestaurantService foodRestaurantService;

    public FoodPayPrepareVO buildPrepareVo(FoodBookingOrder entity, String payChannel) {
        FoodRestaurant restaurant = foodRestaurantService.get(entity.getRestaurantId());
        FoodPackage pkg = foodPackageService.get(entity.getPackageId());
        FoodPayPrepareVO vo = new FoodPayPrepareVO();
        VerticalPayPrepareSupport.fillPrepareVo(
                vo,
                ATTACH_BIZ_TYPE,
                entity.getId(),
                entity.getTradeOrderId(),
                entity.getPayOrderId(),
                payChannel,
                entity.getPayStatus(),
                VerticalPayPrepareSupport.formatDateTime(entity.getExpireTime(), DT_FMT),
                entity.getTenantId(),
                buildPayDescription(restaurant, pkg),
                calcAmountFen(entity, pkg));
        return vo;
    }

    public FoodPayStatusVO buildPayStatusVo(FoodBookingOrder entity) {
        FoodPayStatusVO vo = new FoodPayStatusVO();
        vo.setOrderId(entity.getId());
        vo.setTradeOrderId(entity.getTradeOrderId());
        vo.setPayOrderId(entity.getPayOrderId());
        vo.setPayChannel(entity.getPayChannel());
        vo.setPayStatus(entity.getPayStatus());
        vo.setBookingStatus(entity.getBookStatus());
        vo.setExpireTime(entity.getExpireTime() == null ? "" : entity.getExpireTime().format(DT_FMT));
        return vo;
    }

    public static String newPayOrderId() {
        return VerticalPayPrepareSupport.newPayOrderId();
    }

    private static String buildPayDescription(FoodRestaurant restaurant, FoodPackage pkg) {
        String restName = restaurant == null ? "美食团购" : StrUtil.blankToDefault(restaurant.getName(), "美食团购");
        String pkgName = pkg == null ? "" : StrUtil.blankToDefault(pkg.getName(), "");
        return VerticalPayPrepareSupport.joinDescription(restName, pkgName);
    }

    private long calcAmountFen(FoodBookingOrder entity, FoodPackage pkg) {
        return VerticalPayPrepareSupport.yuanToFen(resolvePayAmount(entity, pkg));
    }

    private BigDecimal resolvePayAmount(FoodBookingOrder entity, FoodPackage pkg) {
        if (entity != null && StrUtil.isNotBlank(entity.getResultPayloadJson())
                && !EMPTY_JSON_OBJECT.equals(entity.getResultPayloadJson().trim())) {
            try {
                FoodBookingResultVO parsed = JSONUtil.toBean(entity.getResultPayloadJson(), FoodBookingResultVO.class);
                if (parsed != null && parsed.getAmount() != null) {
                    return parsed.getAmount();
                }
            } catch (Exception ignored) {
                // fall through
            }
        }
        if (pkg != null && pkg.getPrice() != null && entity != null && entity.getQuantity() != null) {
            return pkg.getPrice().multiply(BigDecimal.valueOf(entity.getQuantity()));
        }
        return BigDecimal.ZERO;
    }
}
