package com.zhongshu.card.server.core.service.openAPI.order;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.types.OrderModeType;
import com.github.microservice.types.OrderState;
import com.github.microservice.types.deviceUse.OrderFromType;
import com.github.microservice.types.payment.ChargeableType;
import com.zhongshu.card.client.model.payment.CreateOrderParam;
import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
import com.zhongshu.card.client.openApi.model.ExpenseFlowOpenApiModel;
import com.zhongshu.card.client.openApi.model.order.MarkPaidParam;
import com.zhongshu.card.client.openApi.model.order.OrderCreateParam;
import com.zhongshu.card.client.openApi.params.CloseOrderParam;
import com.zhongshu.card.client.openApi.params.ExpenseFlowOpenApiSearch;
import com.zhongshu.card.client.openApi.params.OrderNoParam;
import com.zhongshu.card.client.openApi.params.PaymentNoParam;
import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
import com.zhongshu.card.server.core.dao.org.UserCountDao;
import com.zhongshu.card.server.core.dao.payment.ExpenseFlowDao;
import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
import com.zhongshu.card.server.core.domain.org.UserAccount;
import com.zhongshu.card.server.core.domain.payment.ExpenseFlow;
import com.zhongshu.card.server.core.service.base.CommonService;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.payment.ExpenseFlowServiceImpl;
import com.zhongshu.card.server.core.util.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 订单相关的 openAPI
 *
 * @author TRX
 * @date 2024/11/12
 */
@Slf4j
@Service
public class OrderOpenApiService extends SuperService {

    @Autowired
    private ExpenseFlowDao expenseFlowDao;

    @Autowired
    private CommonService commonService;

    @Autowired
    private DeviceInfoDao deviceInfoDao;

    @Autowired
    private ExpenseFlowServiceImpl expenseFlowService;

    @Autowired
    private UserCountDao userCountDao;

    /**
     * 创建订单
     * @param param
     * @return
     */
    public ResultContent createOrder(OrderCreateParam param) {
        String projectCode = param.getProjectCode();
        ResultContent<String> resultContent = commonService.checkProjectCanUserByCode(projectCode);
        if (resultContent.isFailed()) {
            return ResultContent.buildFail(resultContent.getMsg());
        }
        if (StringUtils.isEmpty(param.getOrderNo())) {
            return ResultContent.buildFail("orderNo不能为空");
        }
        if (StringUtils.isEmpty(param.getDeviceId())) {
            return ResultContent.buildFail("deviceId不能为空");
        }
        DeviceInfo deviceInfo = deviceInfoDao.findTopByDeviceId(param.getDeviceId());
        if (ObjectUtils.isEmpty(deviceInfo)) {
            return ResultContent.buildFail("设备不存在");
        }
        if (!deviceInfo.getProjectInfoCode().equals(projectCode)) {
            return ResultContent.buildFail(String.format("设备不属定项目：%s", projectCode));
        }
        if (param.getAmount() == null || BigDecimal.ZERO.compareTo(param.getAmount()) >= 0) {
            return ResultContent.buildFail("消费金额不能为空或小于等于0");
        }
        ExpenseFlow temp = expenseFlowDao.findTopByOrderNoOrderByCreateTimeDesc(param.getOrderNo());
        if (ObjectUtils.isNotEmpty(temp)) {
            return ResultContent.buildFail(String.format("订单已存在：%s", param.getOrderNo()));
        }
        String mqttDataId = param.getOrderNo();
        ExpenseFlow expenseFlow = expenseFlowService.init(mqttDataId);
        if (ObjectUtils.isEmpty(expenseFlow)) {
            return ResultContent.buildFail("订单生成失败，请稍后再试");
        }
        String projectOid = resultContent.getContent();
        UserAccount userAccount = null;
        if (StringUtils.isNotEmpty(param.getCreateUserId())) {
            userAccount = userCountDao.findTopByUserId(param.getCreateUserId());
            if (ObjectUtils.isEmpty(userAccount)) {
                return ResultContent.buildFail("创建订单用户不存在");
            }
        }
        ExpenseFlow tempOrderNo = expenseFlowDao.findTopByOrderNoOrderByCreateTimeDesc(param.getOrderNo());
        if (ObjectUtils.isNotEmpty(tempOrderNo)) {
            return ResultContent.buildFail(String.format("消费号已存在：%s", param.getOrderNo()));
        }
        String amount = param.getAmount().toPlainString();

        CreateOrderParam orderParam = new CreateOrderParam();
        orderParam.setDeviceId(deviceInfo.getDeviceId());
        if (userAccount != null) {
            orderParam.setUserId(userAccount.getUserId());
        }
        orderParam.setOrderNo(param.getOrderNo());
        orderParam.setAmount(amount);
        // 扫码下单
        orderParam.setOrderFromType(OrderFromType.OpenApi);
        // 是否可以匿名消费
        orderParam.setIsAnonymous(Boolean.TRUE);
        // 是否是浮动计费 计费方式
        orderParam.setChargeableType(ChargeableType.Specified);
        // 不指定支付方式
        orderParam.setAppointPaymentType(Boolean.FALSE);
        // 创建订单 （判断是否创建成功）
        ResultContent<ExpenseFlow> content = expenseFlowService.createOrder(orderParam, expenseFlow);
        expenseFlow = expenseFlowService.saveInfo(expenseFlow);
        if (!expenseFlow.getVerifyParamIsSuccess()) {
            expenseFlowService.deleteOrderByOrderNo(expenseFlow.getOrderNo());
            return ResultContent.buildFail(expenseFlow.getVerifyParamMsg());
        }
        return expenseFlowService.getOrderPayDetail(expenseFlow.getId());
    }

    /**
     * 订单列表
     *
     * @param apiSearch
     * @return
     */
    public ResultContent<Page<ExpenseFlowOpenApiModel>> page(ExpenseFlowOpenApiSearch apiSearch) {
        // 检查项目信息
        ResultContent<String> resultContent = commonService.checkProjectCanUserByCode(apiSearch.getProjectCode());
        if (resultContent.isFailed()) {
            return ResultContent.buildFail(resultContent.getMsg());
        }
        String projectOid = resultContent.getContent();

        ExpenseFlowSearch param = new ExpenseFlowSearch();
        BeanUtils.copyProperties(apiSearch, param);
        param.setOrderModeType(OrderModeType.Consume);
        param.setProjectOid(projectOid);

        Pageable pageable = PageRequest.of(apiSearch.getNumber(), apiSearch.getSize());
        Page<ExpenseFlow> page = expenseFlowDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    /**
     * 根据订单号 查询详情
     *
     * @param param
     * @return
     */
    public ResultContent<ExpenseFlowOpenApiModel> getDetailByPaymentNo(PaymentNoParam param) {
        if (StringUtils.isEmpty(param.getPaymentNo())) {
            return ResultContent.buildFail("paymentNo不能为空");
        }
        ExpenseFlow expenseFlow = expenseFlowDao.findTopByPaymentNo(param.getPaymentNo());
        if (ObjectUtils.isEmpty(expenseFlow)) {
            return ResultContent.buildFail("订单不存在");
        }
        return ResultContent.buildSuccess(toModel(expenseFlow));
    }

    /**
     * 订单号查询详情
     * @param param
     * @return
     */
    public ResultContent<ExpenseFlowOpenApiModel> getDetailByOrderNo(OrderNoParam param) {
        if (StringUtils.isEmpty(param.getOrderNo())) {
            return ResultContent.buildFail("orderNo不能为空");
        }
        ExpenseFlow expenseFlow = expenseFlowDao.findTopByOrderNoOrderByCreateTimeDesc(param.getOrderNo());
        if (ObjectUtils.isEmpty(expenseFlow)) {
            return ResultContent.buildFail("订单不存在");
        }
        return ResultContent.buildSuccess(toModel(expenseFlow));
    }

    /**
     * 关闭订单
     *
     * @param param
     * @return
     */
    public ResultContent closeOrderByPaymentNo(PaymentNoParam param) {
        if (StringUtils.isEmpty(param.getPaymentNo())) {
            return ResultContent.buildFail("paymentNo不能为空");
        }
        ExpenseFlow expenseFlow = expenseFlowDao.findTopByPaymentNo(param.getPaymentNo());
        return closeOrder(expenseFlow, param);
    }

    public ResultContent closeOrderByOrderNo(OrderNoParam param) {
        if (StringUtils.isEmpty(param.getOrderNo())) {
            return ResultContent.buildFail("orderNo不能为空");
        }
        ExpenseFlow expenseFlow = expenseFlowDao.findTopByOrderNoOrderByCreateTimeDesc(param.getOrderNo());
        return closeOrder(expenseFlow, param);
    }

    public ResultContent closeOrder(ExpenseFlow expenseFlow, CloseOrderParam param) {
        if (ObjectUtils.isEmpty(expenseFlow)) {
            return ResultContent.buildFail("订单不存在");
        }
        OrderState orderType = expenseFlow.getOrderState();
        if (orderType == OrderState.CLOSED) {
            return ResultContent.buildFail("订单已关闭");
        }
        if (expenseFlow.getIsPaySuccess() != null && expenseFlow.getIsPaySuccess()) {
            return ResultContent.buildFail("订单已支付成功，不能关闭");
        }
        expenseFlow.setOrderState(OrderState.CLOSED);
        expenseFlow.setCloseTime(System.currentTimeMillis());
        if (param != null) {
            expenseFlow.setCloseUserId(param.getCloseUserId());
            expenseFlow.setCloseReason(param.getCloseReason());
        }
        expenseFlowDao.save(expenseFlow);
        return ResultContent.buildSuccess();
    }

    /**
     * 标记订单已支付
     * @return
     */
    public ResultContent markOrderPaid(MarkPaidParam param) {
        if (StringUtils.isEmpty(param.getOrderNo())) {
            return ResultContent.buildFail("orderNo不能为空");
        }
        if (StringUtils.isEmpty(param.getUserId())) {
            return ResultContent.buildFail("userId不能为空");
        }
        ExpenseFlow expenseFlow = expenseFlowDao.findTopByOrderNoOrderByCreateTimeDesc(param.getOrderNo());
        if (ObjectUtils.isEmpty(expenseFlow)) {
            return ResultContent.buildFail(String.format("订单不存在：%s", param.getOrderNo()));
        }
        if (expenseFlow.getOrderState() != OrderState.WAIT_PAYMENT) {
            String stateStr = "";
            if (expenseFlow.getOrderState() != null) {
                stateStr = expenseFlow.getOrderState().getRemark();
            }
            return ResultContent.buildFail(String.format("订单不能支付：%s", stateStr));
        }
        if (expenseFlow.getVerifyParamIsSuccess() == null || !expenseFlow.getVerifyParamIsSuccess()) {
            return ResultContent.buildFail(String.format("订单不能支付：%s", expenseFlow.getVerifyParamMsg()));
        }

        expenseFlow.setOrderState(OrderState.HAVE_PAID);
        expenseFlow.setPayRemark(param.getPayRemark());
        expenseFlow.setIsPaySuccess(Boolean.TRUE);
        expenseFlow.setPaymentStatus("已支付");
        expenseFlow.setPayUserId(param.getUserId());
        expenseFlow.setIsPaid(Boolean.TRUE);

        expenseFlowDao.save(expenseFlow);
        return ResultContent.buildSuccess();
    }

    //----------------------------数据默认转换 start-----------------

    public ExpenseFlowOpenApiModel toModel(ExpenseFlow entity) {
        ExpenseFlowOpenApiModel model = new ExpenseFlowOpenApiModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

}
