package com.clx.performance.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dto.CancelOrderGoodsWeightDTO;
import com.clx.performance.dto.OrderGoodsNotCancelChildDTO;
import com.clx.performance.dto.OrderGoodsTodaySumDTO;
import com.clx.performance.dto.linewarn.LineWarnOrderChildStatisticsDTO;
import com.clx.performance.model.OrderChild;
import com.clx.performance.param.app.PageOrderChildOfDriverParam;
import com.clx.performance.param.app.PageOrderChildOfDriverSearchParam;
import com.clx.performance.param.pc.*;
import com.clx.performance.sqlProvider.OrderChildSqlProvider;
import com.clx.performance.vo.MonthInComeAndOrderedVO;
import com.clx.performance.vo.app.OrderChildVO;
import com.clx.performance.vo.pc.PageCarrierOrderChildVO;
import com.clx.performance.vo.pc.PageOrderChildPoundAuditVO;
import org.apache.ibatis.annotations.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;


@Mapper
public interface OrderChildMapper extends BaseMapper<OrderChild> {
    String TABLE = "order_child";

    /**
     * 司机运单列表
     * @see OrderChildSqlProvider#pageOrderChildOfDriver(Page, PageOrderChildOfDriverParam)
     */
    @SelectProvider(type = OrderChildSqlProvider.class, method = "pageOrderChildOfDriver")
    IPage<OrderChildVO> pageOrderChildOfDriver(@Param("page") Page<OrderChildVO> page, @Param("param") PageOrderChildOfDriverParam param);

    /**
     * 搜索司机运单列表
     * @see OrderChildSqlProvider#pageSearchOrderChildOfDriver(Page, PageOrderChildOfDriverSearchParam)
     */
    @SelectProvider(type = OrderChildSqlProvider.class, method = "pageSearchOrderChildOfDriver")
    IPage<OrderChildVO> pageSearchOrderChildOfDriver(@Param("page") Page<OrderChildVO> page, @Param("param") PageOrderChildOfDriverSearchParam param);


    @SelectProvider(type = OrderChildSqlProvider.class, method = "pagePoundAuditList")
    IPage<PageOrderChildPoundAuditVO> pagePoundAuditList(@Param("page") Page<PageOrderChildPoundAuditVO> page, @Param("param") PagePoundAuditParam param);

    @SelectProvider(type = OrderChildSqlProvider.class, method = "pageCarrierOrderChildList")
    IPage<PageCarrierOrderChildVO> pageCarrierOrderChildList(@Param("page") Page<PageCarrierOrderChildVO> page, @Param("param") PageCarrierOrderChildParam param);

    @Select("select count(1) from order_child where order_goods_no = #{orderGoodsNo} and status < 110")
    int countValidByOrderGoodsNo(String orderGoodsNo);

    @UpdateProvider(type = OrderChildSqlProvider.class, method = "batchUpdateOrderChildStatus")
    Integer updateOrderGoodsSetResidueWeight(@Param(value = "status") Integer status, @Param(value = "remark") String remark, @Param(value = "ids") List<Integer> ids);

    @SelectProvider(type = OrderChildSqlProvider.class, method = "listAfterArrayReceiveChild")
    BigDecimal listAfterArrayReceiveChild(@Param(value = "orderNo")String orderNo);
    Integer updateOrderGoodsSetResidueWeight(@Param(value = "status") Integer status, @Param(value = "ids") List<Integer> ids);

    @Select("select AVG((load_net-unload_net)/load_net) from order_child " +
            " where send_system_address_id = #{sendSystemAddressId} " +
            " and receive_system_address_id = #{receiveSystemAddressId} " +
            " and status >= 90 and status <= 100 " +
            " and pay_time >= #{beginTime}")
    BigDecimal getLinePoundDifferenceRatioAvg(@Param("sendSystemAddressId") Integer sendSystemAddressId,
                                              @Param("receiveSystemAddressId") Integer receiveSystemAddressId,
                                              @Param("beginTime") String beginTime);

    @Select("select AVG(TIMESTAMPDIFF(SECOND, arrive_send_time, unload_time)) from order_child " +
            " where send_system_address_id = #{sendSystemAddressId} " +
            " and receive_system_address_id = #{receiveSystemAddressId} " +
            " and status >= 90 and status <= 100 " +
            " and pay_time >= #{beginTime}")
    Integer getLineArriveSendAddressToUnloadTimeAvg(@Param("sendSystemAddressId") Integer sendSystemAddressId,
                                         @Param("receiveSystemAddressId") Integer receiveSystemAddressId,
                                         @Param("beginTime") String beginTime);

    Integer updateOrderGoodsSetResidueWeight(@Param(value = "status") Integer status, @Param(value = "remark") String remark,
                                             @Param(value = "cancelTime") String cancelTime, @Param(value = "finishTime") String finishTime,
                                             @Param(value = "childNoList") List<String> childNoList);


    @SelectProvider(type = OrderChildSqlProvider.class, method = "findArtificialCancelOrder")
    OrderChildVO findArtificialCancelOrder(@Param("param") ArtificialCancelOrderQueryParam param);

    @SelectProvider(type = OrderChildSqlProvider.class, method = "orderChildCancelRecord")
    IPage<OrderChildVO> orderChildCancelRecord(@Param("page")Page<OrderChildVO> page, @Param(value = "param") OrderChildCancelRecordParam param);

    @SelectProvider(type = OrderChildSqlProvider.class, method = "getLossNet")
    List<Double> getLossNet(@Param("param") OrderChildReportParam param);

    @Select("<script>" +
            "select avg(TIMESTAMPDIFF(SECOND,arrive_send_time,load_time)) from " + TABLE +
            " where load_time is not null and pay_time &gt;= #{beginTime} " +
            " <if test = 'sendSystemAddressId != null'>and send_system_address_id = #{sendSystemAddressId} </if> " +
            " <if test = 'receiveSystemAddressId != null'>and receive_system_address_id = #{receiveSystemAddressId} </if> " +

            " <if test = 'sendSystemAddressId == null'>and send_address_id = #{sendAddressId} </if> " +
            " <if test = 'receiveSystemAddressId == null'>and receive_address_id = #{receiveAddressId} </if> " +
            " </script>")

    Integer loadTimeAvg(Integer sendAddressId, Integer receiveAddressId,
                        Integer sendSystemAddressId, Integer receiveSystemAddressId,
                        String beginTime);

    @Select("<script>" +
            "select avg(TIMESTAMPDIFF(SECOND,arrive_receive_time,unload_time)) from " + TABLE +
            " where unload_time is not null and pay_time &gt;= #{beginTime} " +
            " <if test = 'sendSystemAddressId != null'>and send_system_address_id = #{sendSystemAddressId} </if> " +
            " <if test = 'receiveSystemAddressId != null'>and receive_system_address_id = #{receiveSystemAddressId} </if> " +

            " <if test = 'sendSystemAddressId == null'>and send_address_id = #{sendAddressId} </if> " +
            " <if test = 'receiveSystemAddressId == null'>and receive_address_id = #{receiveAddressId} </if> " +
            " </script>")

    Integer unloadTimeAvg(Integer sendAddressId, Integer receiveAddressId,
                          Integer sendSystemAddressId, Integer receiveSystemAddressId,
                          String beginTime);


    @SelectProvider(type = OrderChildSqlProvider.class, method = "statisticsTruckMonth")
    MonthInComeAndOrderedVO statisticsTruckMonth(@Param("startTime")LocalDateTime startTime, @Param("endTime")LocalDateTime endTime,  @Param("truckNo")String truckNo);


    @Select("select sum(if (status>=50, load_net, #{defaultWeight})) from order_child " +
            " where order_goods_no=#{orderGoodsNo} and status in(10,20,30,40,50,60,70,80,90,100)")
    BigDecimal sumTakeWeightByOrderGoodsNo(String orderGoodsNo, BigDecimal defaultWeight);

    @Select("select sum(load_net) from order_child " +
            " where order_goods_no=#{orderGoodsNo} and status in(50,60,70,80,90,100)")
    BigDecimal sumLoadWeightByOrderGoodsNo(String orderGoodsNo);

    @Select("select sum(if (unload_net>load_net, load_net, unload_net)) from order_child " +
            " where order_goods_no=#{orderGoodsNo} and status in(80,90,100)")
    BigDecimal sumUnloadWeightByOrderGoodsNo(String orderGoodsNo);


    @Select("<script>select order_goods_no, count(*) num from order_child " +
            " where  status in(10,20,30,40,50,60,70,80,90,100) " +
            " and order_goods_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<LineWarnOrderChildStatisticsDTO>sumTakeNumByOrderGoodsNoList(List<String> orderGoodsNoList);
    @Select("<script>select order_goods_no, count(*) num from order_child where  status in(40,50,60,70,80,90,100) " +
            " and order_goods_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<LineWarnOrderChildStatisticsDTO>sumArriveSendNumByOrderGoodsNoList(List<String> orderGoodsNoList);
    @Select("<script>select order_goods_no, count(*) num from order_child where  status in(50,60,70,80,90,100) " +
            " and order_goods_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<LineWarnOrderChildStatisticsDTO>sumLoadNumByOrderGoodsNoList(List<String> orderGoodsNoList);
    @Select("<script>select order_goods_no, count(*) num from order_child where  status in(70,80,90,100) " +
            " and order_goods_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<LineWarnOrderChildStatisticsDTO>sumArriveRecieveNumByOrderGoodsNoList(List<String> orderGoodsNoList);
    @Select("<script>select order_goods_no, count(*) num from order_child where  status in(80,90,100) " +
            " and order_goods_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<LineWarnOrderChildStatisticsDTO>sumUnloadNumByOrderGoodsNoList(List<String> orderGoodsNoList);


    @Select("<script>select order_goods_no orderGoodsNo, sum(weight) cancelWeight from order_child  " +
            " where child_no " +
            " in <foreach collection='list' item='item' open='(' separator=',' close=')'>#{item}</foreach> " +
            " group by order_goods_no " +
            "</script>")
    List<CancelOrderGoodsWeightDTO> statisticsCancelOrderGoodsWeight(@Param("list") List<String> childNos);


    @SelectProvider(type = OrderChildSqlProvider.class, method = "countValidByOrderGoodsNoList")
    List<OrderGoodsNotCancelChildDTO> countValidByOrderGoodsNoList(@Param("orderGoodsList") List<String> orderGoodsList);



    @UpdateProvider(type = OrderChildSqlProvider.class, method = "batchUpdateCancel")
    void batchUpdateCancel(List<OrderChild> canCancelOrderChildList);

    @Select("select count(*) from order_child " +
            " where order_goods_no=#{orderGoodsNo} and status in(10,20,30,40,50,60,70,80,90,100)")
    int countTakeByOrderGoodsNo(@Param("orderGoodsNo") String orderGoodsNo);

    @Select("select count(*) from order_child " +
            " where order_goods_no=#{orderGoodsNo} and status in(50,60,70,80,90,100)")
    int countLoadByOrderGoodsNo(@Param("orderGoodsNo") String orderGoodsNo);

    @Select("select count(*) AS todayOrderGoodsSum, IFNULL(SUM(freight),0) AS todayEstimateProfit from order_child " +
            " where user_no=#{userNo} and status in(10,20,30,40,50,60,70,80,90,100,110,111,112,113) AND create_time >= CURDATE()" +
            "  AND create_time <= CURDATE() + INTERVAL 1 DAY - INTERVAL 1 SECOND")
    OrderGoodsTodaySumDTO countTodayOrderGoodsSumByUserNo(Long userNo);

    /**
     * 统计司机今日的订单数和运费
     *
     * 50、60、70 取装车吨数（load_net）* 运费单价
     * 80、90、100 取装车吨数（weight）* 运费单价
     *
     * @param driverUserNo
     * @return
     */
    @Select("SELECT COUNT(*) AS todayOrderGoodsSum, IFNULL( SUM( freight), 0 ) AS todayEstimateProfit " +
            "FROM( SELECT COUNT(*) AS todayOrderGoodsSum, IFNULL( SUM( CONVERT ( load_net * freight_price, DECIMAL ( 10, 0 ))), 0 ) AS freight " +
            "FROM order_child WHERE user_no = #{driverUserNo} AND STATUS IN ( 50, 60, 70 ) AND create_time >= CURDATE() AND create_time <= CURDATE() + INTERVAL 1 DAY - INTERVAL 1 SECOND " +
            "UNION ALL " +
            "SELECT COUNT(*) AS todayOrderGoodsSum, IFNULL( SUM( CONVERT ( weight * freight_price, DECIMAL ( 10, 0 ))), 0 ) AS freight " +
            "FROM order_child WHERE user_no = #{driverUserNo} AND STATUS IN ( 80, 90, 100 ) AND create_time >= CURDATE() AND create_time <= CURDATE() + INTERVAL 1 DAY - INTERVAL 1 SECOND ) " +
            "AS temp")
    OrderGoodsTodaySumDTO sumOrderChildFreightByDriverUserNo(Long driverUserNo);
}