package com.bs.tm.controller;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bs.common.annotation.Log;
import com.bs.common.core.controller.BaseController;
import com.bs.common.core.domain.AjaxResult;
import com.bs.common.core.page.TableDataInfo;
import com.bs.common.enums.BusinessType;
import com.bs.common.utils.DateUtils;
import com.bs.common.utils.poi.ExcelUtil;
import com.bs.cw.domain.CwAmortizeCost;
import com.bs.cw.service.ICwAmortizeCostService;
import com.bs.tm.domain.*;
import com.bs.tm.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hpsf.Decimal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 承运订单Controller
 *
 * @author bs
 * @date 2024-02-07
 */
@Api(tags = "承运订单")
@RestController
@RequestMapping("/tm/order")
public class TmOrderController extends BaseController {
    @Resource
    private ITmDriverService tmDriverService;
    @Resource
    private ITmOrderService tmOrderService;

    @Resource
    private ITmOrderCargoService tmOrderCargoService;

    @Resource
    private ITmOrderTransService tmOrderTransService;

    @Resource
    private ITmOrderTransCargoService tmOrderTransCargoService;

    @Resource
    private ICwAmortizeCostService cwAmortizeCostService;
    /**
     * 分页查询承运订单列表
     */
    @ApiOperation("分页查询承运订单列表")
    @GetMapping("/pageList")
    public TableDataInfo pageList(TmOrder tmOrder) {
        startPage();
        LambdaQueryWrapper<TmOrder> queryWrapper = new LambdaQueryWrapper();
        condition(queryWrapper,tmOrder);
        List<TmOrder> list = tmOrderService.list(queryWrapper);
        List<TmOrderTransCargo> cargoList = tmOrderTransCargoService.list();
        Map<Long, BigDecimal> cargoMap = new HashMap<>();
        for (TmOrderTransCargo cargo : cargoList) {
            Long orderId = cargo.getOrderId();
            BigDecimal realTransWt = cargo.getRealTransWt();
            if (cargoMap.containsKey(orderId)) {
                BigDecimal oldRealTransWt = cargoMap.get(orderId);
                cargoMap.put(orderId, oldRealTransWt.add(realTransWt));
            } else {
                cargoMap.put(orderId, realTransWt);
            }
        }
        for (TmOrder order : list) {
            Long orderId = order.getId();
            if (cargoMap.containsKey(orderId)) {
                BigDecimal realTransWt = cargoMap.get(orderId);
                order.setTotalNet(String.valueOf(realTransWt));
            }
        }
        return getDataTable(list);
    }

    /**
     * 查询承运订单列表
     */
    @ApiOperation("查询承运订单列表")
    @GetMapping("/list")
    public AjaxResult list(TmOrder tmOrder) {
        LambdaQueryWrapper<TmOrder> queryWrapper = new LambdaQueryWrapper();
        condition(queryWrapper,tmOrder);
        List<TmOrder> list = tmOrderService.list(queryWrapper);
        return success(list);
    }

    /**
     * 导出承运订单列表
     */
    @ApiOperation("导出承运订单列表")
    @Log(title = "承运订单导出", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TmOrder tmOrder) {
        LambdaQueryWrapper<TmOrder> queryWrapper = new LambdaQueryWrapper();
        condition(queryWrapper,tmOrder);
        List<TmOrder> list = tmOrderService.list(queryWrapper);
        ExcelUtil<TmOrder> util = new ExcelUtil<TmOrder>(TmOrder. class);
        util.exportExcel(response, list, "承运订单数据");
    }

    /**
     * 获取承运订单详细信息
     */
    @ApiOperation("获取承运订单详细信息")
    @GetMapping(value = "/{ID}")
    public AjaxResult getInfo(@PathVariable("ID") Long ID) {
        TmOrder tmOrder = tmOrderService.getById(ID);
        List<TmOrderCargo> list = tmOrderCargoService.list(new LambdaQueryWrapper<TmOrderCargo>().eq(TmOrderCargo::getOrderId, ID));
        tmOrder.setOrderCargoList(list);
        return success(tmOrder);
    }

    /**
     * 新增承运订单
     */
    @ApiOperation("新增承运订单")
    @Log(title = "承运订单新增", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody TmOrder tmOrder) {
        tmOrderService.save(tmOrder);
        List<TmOrderCargo> orderCargoList = tmOrder.getOrderCargoList();
        if (null != orderCargoList) {
            orderCargoList.forEach(ele -> {
                ele.setOrderId(tmOrder.getId());
            });
            tmOrderCargoService.saveBatch(orderCargoList);
        }
        return success();
    }

    /**
     * 修改承运订单
     */
    @ApiOperation("修改承运订单")
    @Log(title = "承运订单修改", businessType = BusinessType.UPDATE)
    @PutMapping
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult edit(@RequestBody TmOrder tmOrder) {
        tmOrderService.updateById(tmOrder);
        List<TmOrderCargo> orderCargoList = tmOrder.getOrderCargoList();
        List<TmOrderCargo> lsInsert = new ArrayList<>();
        List<TmOrderCargo> lsUpdate = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        if (null != orderCargoList && orderCargoList.size() > 0) {
            orderCargoList.forEach(item -> {
                item.setOrderId(tmOrder.getId());
                if (Validator.isNotEmpty(item.getId())) {
                    lsUpdate.add(item);
                    ids.add(item.getId());
                } else {
                    lsInsert.add(item);
                }
            });
        }
        //获取id集合
        tmOrderCargoService.remove(new LambdaQueryWrapper<TmOrderCargo>().notIn(ids.size() > 0, TmOrderCargo::getId, ids)
                .eq(TmOrderCargo::getOrderId, tmOrder.getId()));
        if (lsInsert.size() > 0) {
            tmOrderCargoService.saveBatch(lsInsert);
        }
        if (lsUpdate.size() > 0) {
            tmOrderCargoService.updateBatchById(lsUpdate);
        }
        return success();
    }

    @ApiOperation("批量新增订单运输计划")
    @Log(title = "批量新增订单运输计划", businessType = BusinessType.INSERT)
    @PostMapping("/addBatchTrans")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addBatchTrans(@RequestBody TmOrder tmOrder) {
        List<TmOrderTrans> lsInsert = new ArrayList<>();
        List<TmOrderTransCargo> lsCargo = new ArrayList<>();
        if (null != tmOrder && null != tmOrder.getId()) {
            if (null == tmOrder.getOrderCargoList() || tmOrder.getOrderCargoList().size() == 0) {
                List<TmOrderCargo> lsOrderCargo = tmOrderCargoService.list(new LambdaQueryWrapper<TmOrderCargo>().eq(TmOrderCargo::getOrderId, tmOrder.getId()));
                tmOrder.setOrderCargoList(lsOrderCargo);
            }
            // 输入车辆列表lsVehicle、运输重量cargoWt、计划单车运输量singleWt、开始运输日期beginDate、一天平均车次trainNumber
            if (null != tmOrder.getLsVehicle() && tmOrder.getLsVehicle().size() > 0) {
                if (null == tmOrder.getCargoWt() || tmOrder.getCargoWt().equals(0)) {
                    return warn("请输入运输重量");
                }
                if (null == tmOrder.getSingleWt() || tmOrder.getSingleWt().equals(0)) {
                    return warn("请输入正确单次重量");
                }
                if (Validator.isEmpty(tmOrder.getBeginDate())) {
                    tmOrder.setBeginDate(new Date());
                }
                if (null == tmOrder.getTrainNumber() || tmOrder.getTrainNumber().equals(0)) {
                    tmOrder.setTrainNumber(new BigDecimal(1));
                }
                int vehicleTimes = tmOrder.getCargoWt().divide(tmOrder.getSingleWt(), RoundingMode.UP).intValue();
                //int totalDay = tmOrder.getCargoWt().divide(tmOrder.getSingleWt().multiply(tmOrder.getTrainNumber()), RoundingMode.UP).intValue();
                Map<Long, TmOrderTrans> transMap = new HashMap<>();
                for (int i = 0; i < vehicleTimes; i++) {
                    // 第几次
                    int circle = i / tmOrder.getLsVehicle().size();
                    // 第几辆车
                    int remainder = i % tmOrder.getLsVehicle().size();
                    TmOrderTrans trans = transMap.get(tmOrder.getLsVehicle().get(remainder).getId());
                    if (null == trans) {
                        trans = getOrderTrans(tmOrder, circle, remainder);
                    }
                    //tmOrderTransService.save(trans);
                    List<TmOrderTransCargo> cargos = getOrderTransCargo(tmOrder, trans, circle, remainder);
                    List<TmOrderTransCargo> tmp = trans.getLsCargos();
                    if (null == tmp) {
                        tmp = new ArrayList<>();
                    }
                    tmp.addAll(cargos);
                    trans.setLsCargos(tmp);
                    transMap.put(tmOrder.getLsVehicle().get(remainder).getId(), trans);
                    //lsCargo.addAll(cargos);
                }
                if (lsCargo.size() > 0) {
                    //tmOrderTransCargoService.saveBatch(lsCargo);
                }
                transMap.forEach((id, trans) -> {
                    lsInsert.add(trans);
                });
            } else {
                return warn("请选择运输车辆");
            }
        } else {
            return warn("请选择承运订单");
        }
        return success(lsInsert);
    }

    private TmOrderTrans getOrderTrans(TmOrder tmOrder, int circle, int remainder) {
        TmOrderTrans trans = new TmOrderTrans();
        TmVehicle vehicle = tmOrder.getLsVehicle().get(remainder);
        trans.setOrderId(tmOrder.getId());
        trans.setVehicleId(vehicle.getId());
        trans.setVehicleNumber(vehicle.getVehicleNumber());
        trans.setDriverId(vehicle.getDriverId());
        trans.setDriverName(vehicle.getDriverName());
        trans.setVehicleBrand(vehicle.getVehicleBrand());
        trans.setVehicleLoad(vehicle.getVehicleLoad());
        trans.setVehicleVol(vehicle.getVehicleVol());
        if (Validator.isNotEmpty(vehicle.getDriverId())) {
            TmDriver driver = tmDriverService.getById(vehicle.getDriverId());
            trans.setDriverMobile(driver.getMobileNumber());
        }
        trans.setDepartTime(DateUtils.addHours(tmOrder.getBeginDate(), (new BigDecimal(circle * 24).divide(tmOrder.getTrainNumber())).intValue()));
        return trans;
    }

    private List<TmOrderTransCargo> getOrderTransCargo(TmOrder tmOrder, TmOrderTrans trans, int circle, int remainder) {
        List<TmOrderTransCargo> cargos = new ArrayList<>();
        if (null != tmOrder.getOrderCargoList() && tmOrder.getOrderCargoList().size() > 0) {
            for (TmOrderCargo tmOrderCargo : tmOrder.getOrderCargoList()) {
                TmOrderTransCargo tmp = new TmOrderTransCargo();
                tmp.setTransId(trans.getId());
                tmp.setOrderCargoId(tmOrderCargo.getId());
                tmp.setCargoName(tmOrderCargo.getCargoInfo());
                tmp.setLoadWt(tmOrder.getSingleWt());
                tmp.setDepartTime(DateUtils.addHours(tmOrder.getBeginDate(), (new BigDecimal(circle * 24).divide(tmOrder.getTrainNumber())).intValue()));
                tmp.setArrivalTime(DateUtils.addHours(tmOrder.getBeginDate(), (new BigDecimal((circle + 1) * 24).divide(tmOrder.getTrainNumber())).intValue()));
                cargos.add(tmp);
            }
        }
        return cargos;
    }

    @ApiOperation("撤销承运订单")
    @Log(title = "撤销承运订单", businessType = BusinessType.UPDATE)
    @PostMapping("/revokeOrder")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult revoke(@RequestBody TmOrder tmOrder) {
        if (null != tmOrder && null != tmOrder.getId()) {
            List<CwAmortizeCost> lsCost = cwAmortizeCostService.list(new LambdaQueryWrapper<CwAmortizeCost>().eq(CwAmortizeCost::getOrderType, "1").eq(CwAmortizeCost::getOrderId, tmOrder.getId()));
            if (null != lsCost && lsCost.size() > 0) {
                return warn("该承运单已计算生成费用，不能撤销");
            } else {
                TmOrder order = tmOrderService.getById(tmOrder.getId());
                order.setStatus("0");
                return success(tmOrderService.updateById(order));
            }
        } else {
            return warn("请选择承运单!");
        }
    }

    /**
     * 删除承运订单
     */
    @ApiOperation("删除承运订单")
    @Log(title = "承运订单删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{IDs}")
    public AjaxResult remove(@PathVariable List<Long> IDs) {
        return toAjax(tmOrderService.removeBatchByIds(IDs));
    }

    /**
      * 条件设置
      */
    private void condition (LambdaQueryWrapper<TmOrder> queryWrapper,TmOrder tmOrder){


        //id
        if(Validator.isNotEmpty(tmOrder.getId())){
            queryWrapper.eq(TmOrder::getId,tmOrder.getId());
        }

        //订单流水号
        if(Validator.isNotEmpty(tmOrder.getOrderSeq())){
            queryWrapper.like(TmOrder::getOrderSeq,tmOrder.getOrderSeq());
        }

        if(Validator.isNotEmpty(tmOrder.getCargoInfo())){
            queryWrapper.like(TmOrder::getCargoInfo,tmOrder.getCargoInfo());
        }

        if (Validator.isNotEmpty(tmOrder.getCustId())) {
            queryWrapper.eq(TmOrder::getCustId, tmOrder.getCustId());
        }

        //成单日期
        if(Validator.isNotEmpty(tmOrder.getOrderDate())){
            queryWrapper.eq(TmOrder::getOrderDate,tmOrder.getOrderDate());
        }

        if (Validator.isNotEmpty(tmOrder.getBeginDate())) {
            queryWrapper.ge(TmOrder::getOrderDate, tmOrder.getBeginDate());
        }

        if (Validator.isNotEmpty(tmOrder.getEndDate())) {
            queryWrapper.le(TmOrder::getOrderDate, tmOrder.getEndDate());
        }

        //订单货主
        if(Validator.isNotEmpty(tmOrder.getCargoOwner())){
            queryWrapper.eq(TmOrder::getCargoOwner,tmOrder.getCargoOwner());
        }

        //订单车主
        if(Validator.isNotEmpty(tmOrder.getVehicleOwner())){
            queryWrapper.eq(TmOrder::getVehicleOwner,tmOrder.getVehicleOwner());
        }

        //是否正本回单
        if(Validator.isNotEmpty(tmOrder.getIsReceipt())){
            queryWrapper.eq(TmOrder::getIsReceipt,tmOrder.getIsReceipt());
        }

        //回单方式
        if(Validator.isNotEmpty(tmOrder.getReceiptWay())){
            queryWrapper.eq(TmOrder::getReceiptWay,tmOrder.getReceiptWay());
        }

        //发票类型
        if(Validator.isNotEmpty(tmOrder.getInvoiceType())){
            queryWrapper.eq(TmOrder::getInvoiceType,tmOrder.getInvoiceType());
        }

        //开票信息
        if(Validator.isNotEmpty(tmOrder.getInvoiceInfo())){
            queryWrapper.eq(TmOrder::getInvoiceInfo,tmOrder.getInvoiceInfo());
        }

        //支付方式
        if(Validator.isNotEmpty(tmOrder.getPayWay())){
            queryWrapper.eq(TmOrder::getPayWay,tmOrder.getPayWay());
        }

        //提货方式
        if(Validator.isNotEmpty(tmOrder.getDeliveryMethod())){
            queryWrapper.eq(TmOrder::getDeliveryMethod,tmOrder.getDeliveryMethod());
        }

        //提货时间
        if(Validator.isNotEmpty(tmOrder.getDeliveryTime())){
            queryWrapper.eq(TmOrder::getDeliveryTime,tmOrder.getDeliveryTime());
        }

        //送货方式
        if(Validator.isNotEmpty(tmOrder.getDeliveryMode())){
            queryWrapper.eq(TmOrder::getDeliveryMode,tmOrder.getDeliveryMode());
        }

        //是否保险
        if(Validator.isNotEmpty(tmOrder.getIsInsurance())){
            queryWrapper.eq(TmOrder::getIsInsurance,tmOrder.getIsInsurance());
        }

        //保险金额
        if(Validator.isNotEmpty(tmOrder.getInsuranceAmount())){
            queryWrapper.eq(TmOrder::getInsuranceAmount,tmOrder.getInsuranceAmount());
        }

        //保险受益人
        if(Validator.isNotEmpty(tmOrder.getBeneficiary())){
            queryWrapper.eq(TmOrder::getBeneficiary,tmOrder.getBeneficiary());
        }

        //状态
        if(Validator.isNotEmpty(tmOrder.getStatus())){
            queryWrapper.eq(TmOrder::getStatus,tmOrder.getStatus());
        }

        //备注
        if(Validator.isNotEmpty(tmOrder.getRemark())){
            queryWrapper.eq(TmOrder::getRemark,tmOrder.getRemark());
        }

        //运价
        if(Validator.isNotEmpty(tmOrder.getFreightRates())){
            queryWrapper.eq(TmOrder::getFreightRates,tmOrder.getFreightRates());
        }

        //实际付款
        if(Validator.isNotEmpty(tmOrder.getRealPayment())){
            queryWrapper.eq(TmOrder::getRealPayment,tmOrder.getRealPayment());
        }

        //船舶名称
        if(Validator.isNotEmpty(tmOrder.getShipName())){
            queryWrapper.eq(TmOrder::getShipName,tmOrder.getShipName());
        }

        //航次
        if(Validator.isNotEmpty(tmOrder.getVoyage())){
            queryWrapper.eq(TmOrder::getVoyage,tmOrder.getVoyage());
        }

        //提单号
        if(Validator.isNotEmpty(tmOrder.getOrderNo())){
            queryWrapper.like(TmOrder::getOrderNo,tmOrder.getOrderNo());
        }

        //作业号
        if(Validator.isNotEmpty(tmOrder.getJobNo())){
            queryWrapper.eq(TmOrder::getJobNo,tmOrder.getJobNo());
        }

        //创建人
        if(Validator.isNotEmpty(tmOrder.getCreateBy())){
            queryWrapper.eq(TmOrder::getCreateBy,tmOrder.getCreateBy());
        }

        //创建时间
        if(Validator.isNotEmpty(tmOrder.getCreateTime())){
            queryWrapper.eq(TmOrder::getCreateTime,tmOrder.getCreateTime());
        }

        //修改人
        if(Validator.isNotEmpty(tmOrder.getUpdateBy())){
            queryWrapper.eq(TmOrder::getUpdateBy,tmOrder.getUpdateBy());
        }

        //修改时间
        if(Validator.isNotEmpty(tmOrder.getUpdateTime())){
            queryWrapper.eq(TmOrder::getUpdateTime,tmOrder.getUpdateTime());
        }

        //删除标志（0代表存在 2代表删除）
        if(Validator.isNotEmpty(tmOrder.getDelFlag())){
            queryWrapper.eq(TmOrder::getDelFlag,tmOrder.getDelFlag());
        }

        }

}
