package com.yc.ship.module.trade.service.otc.impl;

import com.alibaba.excel.util.DateUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.security.core.LoginUser;
import com.yc.ship.module.infra.api.config.ConfigApi;
import com.yc.ship.module.product.api.ProductApi;
import com.yc.ship.module.product.api.dto.VoyageRespDTO;
import com.yc.ship.module.trade.api.dto.TradeOrderRespDTO;
import com.yc.ship.module.trade.controller.admin.order.vo.order.*;
import com.yc.ship.module.trade.controller.app.otc.vo.AppTradeOrderPageReqVO;
import com.yc.ship.module.trade.controller.app.otc.vo.AppTradeOrderRespVO;
import com.yc.ship.module.trade.convert.order.TradeOrderConvert;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderRoomModelDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderTotalDO;
import com.yc.ship.module.trade.dal.mysql.order.TradeOrderRoomModelMapper;
import com.yc.ship.module.trade.dal.mysql.order.TradeOrderTotalMapper;
import com.yc.ship.module.trade.enums.PayAccountTypeEnum;
import com.yc.ship.module.trade.enums.SellMethodEnum;
import com.yc.ship.module.trade.service.order.TradeOrderService;
import com.yc.ship.module.trade.service.otc.AppOtcTradeOrderService;
import com.yc.ship.module.trade.service.otc.OtcTradeOrderService;
import com.yc.ship.module.trade.service.pay.TradeOrderPayService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import static com.yc.ship.module.trade.enums.ErrorCodeConstants.ORDER_PAY_TENAND_FAIL;


/**
 * &#064;Description 旅行社订单交易service实现
 * &#064;Date 2025/8/12 08:34
 *
 * @author qsl
 */
@Service
@Slf4j
public class AppOtcTradeOrderServiceImpl implements AppOtcTradeOrderService {

    @Resource
    private ConfigApi configApi;
    @Resource
    private TradeOrderService tradeOrderService;
    @Resource
    private TradeOrderPayService tradeOrderPayService;
    @Resource
    private OtcTradeOrderService otcTradeOrderService;
    @Resource
    private ProductApi productApi;

    @Resource
    private TradeOrderTotalMapper tradeOrderTotalMapper;
    @Resource
    private TradeOrderRoomModelMapper tradeOrderRoomModelMapper;


    @Override
    public CommonResult<OtcTradeOrderCreateRespVO> miniAppCreateOrder(LoginUser loginUser, MiniTradeOrderCreateReqVO createVO) {
        ShipTradeOrderCreateReqVO shipTradeOrderCreateReqVO = BeanUtils.toBean(createVO, ShipTradeOrderCreateReqVO.class);
        shipTradeOrderCreateReqVO.setGroupNo(createVO.getGroupNo());
        shipTradeOrderCreateReqVO.setConfirmType(0);
        shipTradeOrderCreateReqVO.setAmount(createVO.getSummary().getOrderMoney());
        shipTradeOrderCreateReqVO.setPayAmount(createVO.getSummary().getOrderMoney());
        shipTradeOrderCreateReqVO.setRealMoney(createVO.getSummary().getRealMoney());
        shipTradeOrderCreateReqVO.setOtherMoney(createVO.getSummary().getOtherMoney());
        shipTradeOrderCreateReqVO.setDiscountId(createVO.getSummary().getDiscountId());
        if (createVO.getSummary().getRealOrderMoney() != null) {
            shipTradeOrderCreateReqVO.setPayAmount(createVO.getSummary().getRealOrderMoney());
        }
        ShipTradeOrderCreateReqVO.OrderUser orderUser = new ShipTradeOrderCreateReqVO.OrderUser();
        orderUser.setContactName(createVO.getLinkMan());
        orderUser.setMobile(createVO.getLinkMobile());
        orderUser.setEmail(createVO.getLinkEmail());
        shipTradeOrderCreateReqVO.setOrderUser(orderUser);
        shipTradeOrderCreateReqVO.setRemark(createVO.getRemark());
        shipTradeOrderCreateReqVO.setIsYd(createVO.getIsYd());

        shipTradeOrderCreateReqVO.setTravelDate(createVO.getBoardingTime());
        VoyageRespDTO voyage = productApi.getVoyage(createVO.getVoyageId());
        String date = DateUtils.format(new Date(), "yyyyMMddmmss");
        String orderNo = "MINI" + "-" + voyage.getCode() + "-" + date;
        shipTradeOrderCreateReqVO.setOrderNo(orderNo);

        ShipTradeOrderCreateReqVO.OrderProperty orderProperty = new ShipTradeOrderCreateReqVO.OrderProperty();
        orderProperty.setSellMethod(SellMethodEnum.OTC.getType());
        orderProperty.setSourceId(createVO.getUserId());
        orderProperty.setMemberId(loginUser.getId().toString());
        orderProperty.setSourceName("小程序用户");
        orderProperty.setSellMethod(SellMethodEnum.MINI_APP.getType());

        shipTradeOrderCreateReqVO.setOrderProperty(orderProperty);

        ShipTradeOrderCreateReqVO.OrderItem orderItem = new ShipTradeOrderCreateReqVO.OrderItem();
        List<ShipTradeOrderCreateReqVO.OrderDetail> detailList = new ArrayList<>();
        ShipTradeOrderCreateReqVO.OrderDetail orderDetail = new ShipTradeOrderCreateReqVO.OrderDetail();
        List<ShipTradeOrderCreateReqVO.Visitor> visitorList = new ArrayList<>();
        for (TradeVistorReqVO tradeVistorReqVO : createVO.getTourist()) {
            ShipTradeOrderCreateReqVO.Visitor visitor = getVisitor1(tradeVistorReqVO);
            visitorList.add(visitor);
        }
        orderDetail.setVisitorList(visitorList);
        orderDetail.setCount(visitorList.size());

        BigDecimal spuMoney = new BigDecimal(0);
        for (TradeSpuReqVO tradeSpuReqVO : createVO.getSpuList()) {
            ShipTradeOrderCreateReqVO.OrderDetail orderDetail1 = new ShipTradeOrderCreateReqVO.OrderDetail();
            //0 游船产品 1 附加产品 2：赠票
            if (tradeSpuReqVO.getProductId() != null && !tradeSpuReqVO.getTourist().isEmpty()) {
                orderDetail1.setProductType(1);
            } else if (tradeSpuReqVO.getProductId() != null && tradeSpuReqVO.getRequired() != null && tradeSpuReqVO.getRequired() == 1) {
                orderDetail1.setProductType(2);
            } else {
                if (tradeSpuReqVO.getProductId() != null) {
                    //有产品ID没有游客信息跳过
                    continue;
                }
                orderDetail1.setProductType(0);
            }
            List<ShipTradeOrderCreateReqVO.Visitor> visitorList1 = new ArrayList<>();
            if (orderDetail1.getProductType() == 0 || orderDetail1.getProductType() == 1) {
                for (String touristId : tradeSpuReqVO.getTourist()) {
                    TradeVistorReqVO tradeVistorReqVO = createVO.getTourist().stream().filter(v -> v.getId().equals(touristId)).findFirst().orElseGet(TradeVistorReqVO::new);
                    ShipTradeOrderCreateReqVO.Visitor visitor = new ShipTradeOrderCreateReqVO.Visitor();
                    visitor.setName(tradeVistorReqVO.getName());
                    visitor.setVid(tradeVistorReqVO.getId());
                    visitor.setMobile(tradeVistorReqVO.getMobile());
                    visitor.setGender(tradeVistorReqVO.getGender());
                    visitor.setCredentialNo(tradeVistorReqVO.getCardNo());
                    visitor.setCredentialType(tradeVistorReqVO.getCardType());
                    visitor.setYczz(tradeVistorReqVO.getYichang());
                    visitor.setCqzz(tradeVistorReqVO.getChongqing());
                    visitor.setNationality(tradeVistorReqVO.getNationality());
                    visitor.setRoomId(tradeVistorReqVO.getRoomId());
                    visitor.setCohabitation(tradeVistorReqVO.getCohabitation());
                    visitor.setRoomIndexId(tradeVistorReqVO.getRoomIndexId());
                    visitor.setRoomModelId(tradeVistorReqVO.getRoomModelId());
                    visitor.setFloor(tradeVistorReqVO.getFloor());
                    visitorList1.add(visitor);
                    spuMoney = spuMoney.add(tradeSpuReqVO.getPrice());
                }
                orderDetail1.setVisitorList(visitorList1);
                orderDetail1.setProductId(tradeSpuReqVO.getProductId() + "");
                orderDetail1.setPrice(tradeSpuReqVO.getPrice());
                orderDetail1.setOriginPrice(tradeSpuReqVO.getPrice());
            } else {
                for (TradeVistorReqVO tradeVistorReqVO : createVO.getTourist()) {
                    ShipTradeOrderCreateReqVO.Visitor visitor = new ShipTradeOrderCreateReqVO.Visitor();
                    visitor.setName(tradeVistorReqVO.getName());
                    visitor.setMobile(tradeVistorReqVO.getMobile());
                    visitor.setCredentialNo(tradeVistorReqVO.getCardNo());
                    visitor.setCredentialType(tradeVistorReqVO.getCardType());
                    visitor.setYczz(tradeVistorReqVO.getYichang());
                    visitor.setCqzz(tradeVistorReqVO.getChongqing());
                    visitor.setRoomId(tradeVistorReqVO.getRoomId());
                    visitor.setNationality(tradeVistorReqVO.getNationality());
                    visitor.setCohabitation(tradeVistorReqVO.getCohabitation());
                    visitor.setRoomIndexId(tradeVistorReqVO.getRoomIndexId());
                    visitor.setRoomModelId(tradeVistorReqVO.getRoomModelId());
                    visitor.setFloor(tradeVistorReqVO.getFloor());
                    visitorList1.add(visitor);
                }
                orderDetail1.setVisitorList(visitorList1);
                orderDetail1.setProductId(tradeSpuReqVO.getProductId() + "");
                orderDetail1.setPrice(BigDecimal.ZERO);
                orderDetail1.setOriginPrice(BigDecimal.ZERO);
            }
            orderDetail1.setCount(visitorList1.size());
            detailList.add(orderDetail1);
        }
        BigDecimal price;
        if (createVO.getSummary().getOrderMoney() != null && createVO.getSummary().getOrderMoney().compareTo(new BigDecimal(0)) > 0) {
            price = createVO.getSummary().getOrderMoney().subtract(spuMoney).divide(new BigDecimal(visitorList.size()), 2, RoundingMode.HALF_UP);
        } else {
            price = new BigDecimal(0);
        }
        orderDetail.setPrice(price);
        orderDetail.setOriginPrice(price);

        orderDetail.setProductType(0);
        detailList.add(orderDetail);


        orderItem.setDetailList(detailList);

        shipTradeOrderCreateReqVO.setItemlList(Collections.singletonList(orderItem));

        shipTradeOrderCreateReqVO.setSpuAmount(spuMoney);

        CommonResult<TradeOrderRespDTO> result = doShipCreateOrder(loginUser, shipTradeOrderCreateReqVO);
        if (result.isError()) {
            return CommonResult.error(result);
        }
        TradeOrderTotalVO summary = createVO.getSummary();
        TradeOrderTotalDO tradeOrderTotalDO = BeanUtils.toBean(summary, TradeOrderTotalDO.class);
        Long orderId = result.getCheckedData().getOrderId();
        tradeOrderTotalDO.setOrderId(IdWorker.getId());
        tradeOrderTotalDO.setOldOrderId(orderId);
        tradeOrderTotalMapper.insert(tradeOrderTotalDO);

        // 创建订单房型数据
        List<TradeOrderRoomModelDO> tradeOrderRoomList = new ArrayList<>();
        List<TradeOrderRoomModelVO> roomModelList = createVO.getRoomModelList();
        roomModelList.forEach(roomModel -> {
            TradeOrderRoomModelDO tradeOrderRoomDO = BeanUtils.toBean(roomModel, TradeOrderRoomModelDO.class);
            tradeOrderRoomDO.setOrderId(orderId);
            tradeOrderRoomList.add(tradeOrderRoomDO);
        });
        tradeOrderRoomModelMapper.insertBatch(tradeOrderRoomList);

        OtcTradeOrderCreateRespVO respVO = TradeOrderConvert.INSTANCE.convert(result.getData());
        return CommonResult.success(respVO);

    }

    private CommonResult<TradeOrderRespDTO> doShipCreateOrder(LoginUser loginUser, ShipTradeOrderCreateReqVO otcTradeOrderCreateReqVO) {
        ShipTradeOrderCreateReqVO.OrderProperty orderProperty = otcTradeOrderCreateReqVO.getOrderProperty();
        if (orderProperty == null) {
            orderProperty = new ShipTradeOrderCreateReqVO.OrderProperty();
        }
        setShipOrderPropertyFromLoginUser(loginUser, orderProperty);
        otcTradeOrderCreateReqVO.setOrderProperty(orderProperty);
        return tradeOrderService.createShipOrder(otcTradeOrderCreateReqVO);
    }

    private void setShipOrderPropertyFromLoginUser(LoginUser loginUser, ShipTradeOrderCreateReqVO.OrderProperty orderProperty) {
        orderProperty.setSellerId(loginUser.getId().toString());
        orderProperty.setSellMethod(SellMethodEnum.MINI_APP.getType());
    }

    private static ShipTradeOrderCreateReqVO.@NotNull Visitor getVisitor1(TradeVistorReqVO tradeVistorReqVO) {
        ShipTradeOrderCreateReqVO.Visitor visitor = new ShipTradeOrderCreateReqVO.Visitor();
        visitor.setName(tradeVistorReqVO.getName());
        visitor.setMobile(tradeVistorReqVO.getMobile());
        visitor.setCredentialNo(tradeVistorReqVO.getCardNo());
        visitor.setCredentialType(tradeVistorReqVO.getCardType());
        visitor.setYczz(tradeVistorReqVO.getYichang());
        visitor.setCqzz(tradeVistorReqVO.getChongqing());
        visitor.setRoomId(tradeVistorReqVO.getRoomId());
        visitor.setNationality(tradeVistorReqVO.getNationality());
        visitor.setRoomIndexId(tradeVistorReqVO.getRoomIndexId());
        visitor.setRoomModelId(tradeVistorReqVO.getRoomModelId());
        visitor.setFloor(tradeVistorReqVO.getFloor());
        return visitor;
    }

    @Override
    public CommonResult<PayOrderRespVO> miniAppPayOrder(LoginUser loginUser, PayOrderReqVO payOrderReqVO) {
        if (loginUser == null) {
            return CommonResult.error(ORDER_PAY_TENAND_FAIL);
        }
        payOrderReqVO.setAccountType(PayAccountTypeEnum.OTC.getType());
        return tradeOrderPayService.payOrder(payOrderReqVO);
    }

    @Override
    public CommonResult<PageResult<AppTradeOrderRespVO>> miniTradeOrderPage(AppTradeOrderPageReqVO pageReqVO) {
        PageResult<TradeOrderRespVO> pageResult = otcTradeOrderService.getMiniTradeOrderPage(pageReqVO);
        PageResult<AppTradeOrderRespVO> appPageResult = BeanUtils.toBean(pageResult, AppTradeOrderRespVO.class);
        return CommonResult.success(appPageResult);
    }

    @Override
    public CommonResult<AppTradeOrderRespVO> miniOrderInfoById(Long id) {
        TradeOrderRespVO tradeOrderRespVO = otcTradeOrderService.getOrderInfo(id);
        AppTradeOrderRespVO appTradeOrderRespVO = BeanUtils.toBean(tradeOrderRespVO, AppTradeOrderRespVO.class);
        appTradeOrderRespVO.setRemark("");
        return CommonResult.success(appTradeOrderRespVO);
    }


    @Override
    public String getConfigValue(String key) {
        return configApi.getConfigValueByKey(key);
    }

    @Override
    public CommonResult<?> miniAppCancelOrder(LoginUser loginUser, Long orderId) {
        return tradeOrderPayService.cancelOrder(orderId);
    }

}
