package com.tashow.cloud.trade.convert.order;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.tashow.cloud.common.pojo.PageResult;
import com.tashow.cloud.common.util.collection.CollectionUtils;
import com.tashow.cloud.common.util.date.LocalDateTimeUtils;
import com.tashow.cloud.common.util.ip.AreaUtils;
import com.tashow.cloud.common.util.string.StrUtils;
import com.tashow.cloud.excel.dict.core.DictFrameworkUtils;
import com.tashow.cloud.userapi.api.address.dto.MemberAddressRespDTO;
import com.tashow.cloud.userapi.api.user.dto.UserMemberRespDTO;
import com.tashow.cloud.payapi.api.order.dto.PayOrderCreateReqDTO;
import com.tashow.cloud.payapi.enums.DictTypeConstants;
import com.tashow.cloud.productapi.api.product.dto.ProdDO;
import com.tashow.cloud.trade.controller.admin.base.member.user.MemberUserRespVO;
import com.tashow.cloud.trade.controller.admin.order.vo.*;
import com.tashow.cloud.trade.controller.app.order.vo.*;
import com.tashow.cloud.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
import com.tashow.cloud.trade.convert.order.dto.ProductSkuRespDTO;
import com.tashow.cloud.trade.convert.order.dto.ProductSkuUpdateStockReqDTO;
import com.tashow.cloud.trade.convert.order.dto.ProductSpuRespDTO;
import com.tashow.cloud.trade.dal.dataobject.cart.CartDO;
import com.tashow.cloud.trade.dal.dataobject.delivery.DeliveryExpressDO;
import com.tashow.cloud.trade.dal.dataobject.order.TradeOrderDO;
import com.tashow.cloud.trade.dal.dataobject.order.TradeOrderItemDO;
import com.tashow.cloud.trade.dal.dataobject.order.TradeOrderLogDO;
import com.tashow.cloud.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
import com.tashow.cloud.trade.framework.order.config.TradeOrderProperties;
import com.tashow.cloud.trade.service.brokerage.bo.BrokerageAddReqBO;
import com.tashow.cloud.trade.service.price.bo.TradePriceCalculateReqBO;
import com.tashow.cloud.trade.service.price.bo.TradePriceCalculateRespBO;
import com.tashow.cloud.tradeapi.api.order.dto.TradeOrderRespDTO;
import com.tashow.cloud.tradeapi.enums.order.TradeOrderStatusEnum;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.tashow.cloud.common.util.collection.CollectionUtils.convertMap;
import static com.tashow.cloud.common.util.collection.CollectionUtils.convertMultiMap;
import static com.tashow.cloud.common.util.date.LocalDateTimeUtils.addTime;


@Mapper
public interface TradeOrderConvert {

    TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class);

    //region  分页结果
    default PageResult<TradeOrderPageRespVO> convertPage(PageResult<TradeOrderDO> pageResult, List<TradeOrderItemDO> orderItems,Map<Long, UserMemberRespDTO> userMap) {
        Map<Long, List<TradeOrderItemDO>> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId);
        // 转化 List
        List<TradeOrderPageRespVO> orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> {
            TradeOrderPageRespVO orderPageRespVO = convertOrder(order,userMap.get(order.getUserId()));

            List<TradeOrderPageRespVO.Item> items = new ArrayList<>();
            List<TradeOrderItemDO> itemDO = orderItemMap.get(order.getId());
            for (TradeOrderItemDO tradeOrderItemDO : itemDO) {
                TradeOrderPageRespVO.Item item = convertItem(tradeOrderItemDO);
                item.setHandedPrice(tradeOrderItemDO.getPrice() - tradeOrderItemDO.getDiscountPrice());
                orderPageRespVO.setShopName(tradeOrderItemDO.getShopName());
                orderPageRespVO.setShopLogo(tradeOrderItemDO.getShopLogo());
                orderPageRespVO.setOrderCategoryName(tradeOrderItemDO.getOrderCategoryName());
                //支付剩余时间 单位miao
                orderPageRespVO.setPayLastTime(LocalDateTimeUtils.betweenWithNow(order.getPayTime()));
                items.add(item);
            }
            orderPageRespVO.setItems(items);

            return orderPageRespVO;
        });
        return new PageResult<>(orderVOs, pageResult.getTotal());
    }

    @Mappings({
            @Mapping(source = "order.id", target = "id"),
            @Mapping(source = "order.userId", target = "userId"),
            @Mapping(source = "order.createTime", target = "createTime"),
            @Mapping(source = "user.nickname", target = "userNickName"),
            @Mapping(source = "user.avatar", target = "userAvatar"),
    })
    TradeOrderPageRespVO convertOrder(TradeOrderDO order,UserMemberRespDTO user);

    TradeOrderPageRespVO.Item convertItem(TradeOrderItemDO item);
    //endregion

    //region 订单详情
    default TradeOrderDetailRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,Map<Long, UserMemberRespDTO> userMap, List<TradeOrderLogDO> orderLogs) {
        //订单基本信息
        TradeOrderDetailRespVO orderVO = convertDetail(order,userMap.get(order.getUserId()), orderItems, orderLogs);
        //计算商品到手价
        orderVO.getItems().stream().forEach(item -> {
            item.setHandedPrice(item.getPrice() - item.getDiscountPrice());
            item.setTotalPrice(item.getPrice() * item.getCount() - item.getDiscountPrice());
            //产品类目在订单详情里
            orderVO.setOrderCategoryId(item.getOrderCategoryId());
            orderVO.setOrderCategoryName(item.getOrderCategoryName());
            //todo 服务保障列表  properties 服务内容 serveContent
        });
        //服务信息
        orderItems.stream().filter(a->StrUtil.isNotBlank(a.getServeInfo())).findAny().ifPresent(a -> {
            orderVO.setTradeServeInfo(JSON.parseObject(a.getServeInfo()));
            orderVO.setTradeExtendServeInfo(JSON.parseArray(a.getServeExtInfo()));
            orderVO.setTradeExtendCostInfo(JSON.parseArray(a.getPriceExtInfo()));
        });

        //保障时间  保障状态 如果状态是已完成 则
        if (Objects.equals(order.getOrderStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
            LocalDateTime finishTime = order.getFinishTime();
            Long between = LocalDateTimeUtils.between(finishTime);

            orderVO.setPropertyStatus(between >= 7 ? 0 : 1);
            orderVO.setPropertyTime(LocalDateTimeUtils.getPlusDay(7));
        }
        return orderVO;
    }
    @Mappings({
            @Mapping(target = "id",source = "order.id"),
            @Mapping(target = "createTime",source = "order.createTime"),
            @Mapping(source = "userMemberRespDTO.nickname", target = "userNickName"),
            @Mapping(source = "userMemberRespDTO.avatar", target = "userAvatar"),
    })
    TradeOrderDetailRespVO convertDetail(TradeOrderDO order,UserMemberRespDTO userMemberRespDTO,List<TradeOrderItemDO> items, List<TradeOrderLogDO> statusList);
    //endregion


    //region修改订单
    @Mappings({
        @Mapping(target = "merchantRemark",source = "remark")
    })
    TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
    //endregion


    //region 订单快照
    TradeOrderFastPhotoRespVo convert(TradeOrderItemDO itemDO, ProdDO prodDO);
    //endregion


    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(source = "userId", target = "userId"),
            @Mapping(target = "merchantRemark", ignore = true),
            @Mapping(source = "createReqVO.remark", target = "userRemark"),
    })
    TradeOrderDO convert(Long userId, AppTradeOrderCreateReqVO createReqVO);

    TradeOrderRespDTO convert(TradeOrderDO orderDO);

    default List<TradeOrderItemDO> convertList(TradeOrderDO tradeOrderDO) {
        return null;//CollectionUtils.convertList(calculateRespBO.getItems(), item -> {
//            TradeOrderItemDO orderItem = convert(item);
//            orderItem.setOrderId(tradeOrderDO.getId());
//            orderItem.setUserId(tradeOrderDO.getUserId());
//            orderItem.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
//            orderItem.setCommentStatus(false);
//            return orderItem;
//        });
    }

    TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item);

    default ProductSkuUpdateStockReqDTO convert(List<TradeOrderItemDO> list) {
        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(item.getCount()));
        return new ProductSkuUpdateStockReqDTO(items);
    }

    default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) {
        List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
                new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
        return new ProductSkuUpdateStockReqDTO(items);
    }

    default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
                                         TradeOrderProperties orderProperties) {
        PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
                .setAppKey(orderProperties.getPayAppKey()).setUserIp(order.getUserIp());
        // 商户相关字段
        createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
        String subject = orderItems.get(0).getSpuName();
        subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位
        createReqDTO.setSubject(subject);
        createReqDTO.setBody(subject); // TODO 芋艿：临时写死
        // 订单相关字段
        createReqDTO.setPrice(order.getPayPrice()).setExpireTime(addTime(orderProperties.getPayExpireTime()));
        return createReqDTO;
    }

    MemberUserRespVO convert(UserMemberRespDTO bean);

    default PageResult<AppTradeOrderPageItemRespVO> convertPage02(PageResult<TradeOrderDO> pageResult,
                                                                  List<TradeOrderItemDO> orderItems) {
        Map<Long, List<TradeOrderItemDO>> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId);
        // 转化 List
        List<AppTradeOrderPageItemRespVO> orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> {
            List<TradeOrderItemDO> xOrderItems = orderItemMap.get(order.getId());
            return convert02(order, xOrderItems);
        });
        return new PageResult<>(orderVOs, pageResult.getTotal());
    }

    AppTradeOrderPageItemRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> items);

    default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
                                                TradeOrderProperties tradeOrderProperties,
                                                DeliveryExpressDO express) {
        AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
        orderVO.setPayExpireTime(order.getCreateTime().plus(tradeOrderProperties.getPayExpireTime()));
        if (order.getPayChannelCode() == null) {
            orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE, order.getPayChannelCode()));
        }
        // 处理收货地址
        orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
        if (express != null) {
            orderVO.setLogisticsId(express.getId()).setLogisticsName(express.getName());
        }
        return orderVO;
    }

    AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List<TradeOrderItemDO> items);

    AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);

    @Mappings({
            @Mapping(target = "skuId", source = "tradeOrderItemDO.skuId"),
            @Mapping(target = "orderId", source = "tradeOrderItemDO.orderId"),
            @Mapping(target = "orderItemId", source = "tradeOrderItemDO.id"),
            @Mapping(target = "descriptionScores", source = "createReqVO.descriptionScores"),
            @Mapping(target = "benefitScores", source = "createReqVO.benefitScores"),
            @Mapping(target = "content", source = "createReqVO.content"),
            @Mapping(target = "picUrls", source = "createReqVO.picUrls"),
            @Mapping(target = "anonymous", source = "createReqVO.anonymous"),
            @Mapping(target = "userId", source = "tradeOrderItemDO.userId")
    })
    default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
                                             List<CartDO> cartList) {
        TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO().setUserId(userId)
                .setItems(new ArrayList<>(settlementReqVO.getItems().size()))
                .setCouponId(settlementReqVO.getCouponId()).setPointStatus(settlementReqVO.getPointStatus())
                // 物流信息
                .setDeliveryType(settlementReqVO.getDeliveryType()).setAddressId(settlementReqVO.getAddressId())
                .setPickUpStoreId(settlementReqVO.getPickUpStoreId())
                // 各种活动
                .setSeckillActivityId(settlementReqVO.getSeckillActivityId())
                .setBargainRecordId(settlementReqVO.getBargainRecordId())
                .setCombinationActivityId(settlementReqVO.getCombinationActivityId())
                .setCombinationHeadId(settlementReqVO.getCombinationHeadId())
                .setPointActivityId(settlementReqVO.getPointActivityId());
        // 商品项的构建
        Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId);
        for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) {
            // 情况一：skuId + count
            if (item.getSkuId() != null) {
                reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(item.getSkuId()).setCount(item.getCount())
                        .setSelected(true)); // true 的原因，下单一定选中
                continue;
            }
            // 情况二：cartId
            CartDO cart = cartMap.get(item.getCartId());
            if (cart == null) {
                continue;
            }
            reqBO.getItems().add(new TradePriceCalculateReqBO.Item().setSkuId(cart.getSkuId()).setCount(cart.getCount())
                    .setCartId(item.getCartId()).setSelected(true)); // true 的原因，下单一定选中
        }
        return reqBO;
    }

    //
    default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, MemberAddressRespDTO address) {
        AppTradeOrderSettlementRespVO respVO = convert0(calculate, address);
        if (address != null) {
            respVO.getAddress().setAreaName(AreaUtils.format(address.getAreaId()));
        }
        return respVO;
    }

    //
    AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, MemberAddressRespDTO address);

    List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list);

    TradeOrderDO convert(TradeOrderUpdateAddressReqVO reqVO);

    TradeOrderDO convert(TradeOrderUpdatePriceReqVO reqVO);



    default BrokerageAddReqBO convert(UserMemberRespDTO user, TradeOrderItemDO item,
                                      ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
        BrokerageAddReqBO bo = new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
                .setBasePrice(item.getPayPrice())
                .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuId()))
                .setFirstFixedPrice(0).setSecondFixedPrice(0);
        if (BooleanUtil.isTrue(spu.getSubCommissionType())) {
            bo.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
        }
        return bo;
    }

}
