package com.hzs.sale.deliver.controller.manage;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.constant.SystemFieldConstants;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.constant.msg.SaOrderMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.sale.deliver.SaDeliver;
import com.hzs.common.domain.sale.deliver.SaDeliverBarCode;
import com.hzs.common.security.service.UserTokenService;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.common.core.utils.TransactionUtils;
import com.hzs.sale.deliver.param.DeliverConfirmParam;
import com.hzs.sale.deliver.param.DeliverTemplateParam;
import com.hzs.sale.deliver.param.DeliverParam;
import com.hzs.sale.deliver.service.ISaDeliverBarCodeService;
import com.hzs.sale.deliver.service.ISaDeliverService;
import com.hzs.sale.deliver.vo.DeliverTemplateVO;
import com.hzs.sale.deliver.vo.DeliverVO;
import com.hzs.sale.util.OrderUtil;
import com.hzs.system.base.IAreaServiceApi;
import com.hzs.system.sys.IUserServiceApi;
import com.hzs.system.sys.dto.UserAuthorityDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 发货清单立即发货控制器
 * @Author: jiang chao
 * @Time: 2022/11/7 17:20
 * @Classname: SaDeliverController
 * @PackageName: com.hzs.sale.deliver.controller.manage
 */
@RestController
@RequestMapping("/manage/deliver")
public class SaDeliverController extends BaseController {

    @Autowired
    private ISaDeliverService iSaDeliverService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;
    @Autowired
    private ISaDeliverBarCodeService iSaDeliverBarCodeService;
    @Autowired
    private UserTokenService userTokenService;

    @DubboReference
    private IAreaServiceApi iAreaServiceApi;
    @DubboReference
    private IUserServiceApi iUserServiceApi;


    /**
     * 列表
     *
     * @param param 立即发货列表查询入参
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.SELECT)
    @GetMapping("/list")
    public TableDataInfo list(DeliverParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getPayTime());
        DateUtils.handTimeStartAndEnd(param.getPrintTime());
        DateUtils.handTimeStartAndEnd(param.getDeliverTime());

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverVO> resultList = new ArrayList<>();

        // 立即发货列表只显示已打印的发货单
        param.setPrintStatus(EPrintStatus.PRINT.getValue());

        if (StringUtils.isNotEmpty(param.getBarCode())) {
            // 追溯条码处理
            QueryWrapper<SaDeliverBarCode> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(SystemFieldConstants.PK_COUNTRY, pkCountry);
            queryWrapper.eq("BAR_CODE", param.getBarCode());
            List<SaDeliverBarCode> barCodeList = iSaDeliverBarCodeService.list(queryWrapper);
            if (CollectionUtil.isEmpty(barCodeList)) {
                // 带有追溯码查询条件，并没有查出来追溯码，则直接返回空数据
                return getDataTable(resultList);
            }
            param.setPkDeliver(barCodeList.get(0).getPkDeliver());
            param.setPkDeliverItems(barCodeList.get(0).getPkDeliverItems());
        }

        // 获取管理员权限（角色地区范围、体系列表、团队列表）
        UserAuthorityDTO userAuthorityDTO = iUserServiceApi.getUserAuthority(SecurityUtils.getUserId()).getData();
        param.setAreaScopeList(userAuthorityDTO.getRoleAreaScopeList());
        param.setVertexIdList(userAuthorityDTO.getVertexIdList());
        param.setTeamList(userAuthorityDTO.getUserTeamList());

        startPage();
        resultList = iSaDeliverService.deliverList(param, pkCountry);

        // 当查询有数据才进行处理
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

            // 发货单明细ID
            List<Long> deliverItemsIdList = resultList.stream().map(DeliverVO::getDeliverItemsId).collect(Collectors.toList());
            // 根据发货单明细ID，查询对应绑定条码数据
            Map<Long, SaDeliverBarCode> barCodeMap = iSaDeliverBarCodeService.queryListByDeliverItems(deliverItemsIdList, pkCountry);

            for (DeliverVO deliver : resultList) {
                // 省市区处理
                OrderUtil.handleOrderAddress(areaMap, deliver);

                // 处理追溯编号
                SaDeliverBarCode deliverBarCode = barCodeMap.get(deliver.getDeliverItemsId());
                if (null != deliverBarCode) {
                    deliver.setBarCode(deliverBarCode.getBarCode());
                }
            }
        }
        return getDataTable(resultList);
    }


    /**
     * 导出
     *
     * @param response
     * @param param    立即发货列表查询入参
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DeliverParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getPayTime());
        DateUtils.handTimeStartAndEnd(param.getPrintTime());
        DateUtils.handTimeStartAndEnd(param.getDeliverTime());

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverVO> resultList = new ArrayList<>();

        // 立即发货列表只显示已打印的发货单
        param.setPrintStatus(EPrintStatus.PRINT.getValue());

        if (StringUtils.isNotEmpty(param.getBarCode())) {
            // 追溯条码处理
            QueryWrapper<SaDeliverBarCode> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(SystemFieldConstants.PK_COUNTRY, pkCountry);
            queryWrapper.eq("BAR_CODE", param.getBarCode());
            List<SaDeliverBarCode> barCodeList = iSaDeliverBarCodeService.list(queryWrapper);
            if (CollectionUtil.isEmpty(barCodeList)) {
                // 带有追溯码查询条件，并没有查出来追溯码，则直接返回空数据
                ExcelUtil<DeliverVO> util = new ExcelUtil<>(DeliverVO.class);
                util.exportExcel(response, resultList, "发货清单立即发货导出");
            }
            param.setPkDeliver(barCodeList.get(0).getPkDeliver());
            param.setPkDeliverItems(barCodeList.get(0).getPkDeliverItems());
        }

        // 获取管理员权限（角色地区范围、体系列表、团队列表）
        UserAuthorityDTO userAuthorityDTO = iUserServiceApi.getUserAuthority(SecurityUtils.getUserId()).getData();
        param.setAreaScopeList(userAuthorityDTO.getRoleAreaScopeList());
        param.setVertexIdList(userAuthorityDTO.getVertexIdList());
        param.setTeamList(userAuthorityDTO.getUserTeamList());

        resultList = iSaDeliverService.deliverList(param, pkCountry);

        // 当查询有数据才进行处理
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

            // 获取需要翻译的枚举翻译
            Map<String, String> transactionMap = iTransactionCommonService.exportEnumTransaction(EDeliveryStatus.values(), EDelivery.values(), ESupplyWay.values(), ETransportType.values(), EOrderType.values());

            for (DeliverVO deliver : resultList) {
                // 省市区处理
                OrderUtil.handleOrderAddress(areaMap, deliver);

                // 发货单明细ID
                List<Long> deliverItemsIdList = resultList.stream().map(DeliverVO::getDeliverItemsId).collect(Collectors.toList());
                // 根据发货单明细ID，查询对应绑定条码数据
                Map<Long, SaDeliverBarCode> barCodeMap = iSaDeliverBarCodeService.queryListByDeliverItems(deliverItemsIdList, pkCountry);

                deliver.setDeliverStatusVal(transactionMap.get(EnumsPrefixConstants.DELIVERY_STATUS + deliver.getDeliverStatus()));
                deliver.setDeliveryWayVal(transactionMap.get(EnumsPrefixConstants.DELIVERY + deliver.getDeliveryWay()));
                deliver.setOperateScopeVal(transactionMap.get(EnumsPrefixConstants.SUPPLY_WAY + deliver.getOperateScope()));
                deliver.setOrderTypeVal(transactionMap.get(EnumsPrefixConstants.ORDER_TYPE + deliver.getOrderType()));
                deliver.setSecondDeliverVal(transactionMap.get(EnumsPrefixConstants.DEALER_YES_NO + deliver.getSecondDeliver()));
                deliver.setTranTypeVal(transactionMap.get(EnumsPrefixConstants.ENU_TRA + deliver.getTranType()));

                // 处理追溯编号
                SaDeliverBarCode deliverBarCode = barCodeMap.get(deliver.getDeliverItemsId());
                if (null != deliverBarCode) {
                    deliver.setBarCode(deliverBarCode.getBarCode());
                }
            }
        }
        ExcelUtil<DeliverVO> util = new ExcelUtil<>(DeliverVO.class);
        util.exportExcel(response, resultList, "发货清单立即发货导出");
    }

    /**
     * 立即发货数据
     *
     * @param param 立即发货入参
     * @return
     */
    @GetMapping("/immediate-data")
    public AjaxResult batchDeliverData(DeliverParam param) {
        // 立即发货列表只显示已打印的发货单
        param.setPrintStatus(EPrintStatus.PRINT.getValue());

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverVO> resultList = iSaDeliverService.deliverList(param, pkCountry);

        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

            for (DeliverVO deliverVO : resultList) {
                if (EDeliveryStatus.NOT_DELIVERY.getValue() != deliverVO.getDeliverStatus()) {
                    // 发货单已发货
                    return AjaxResult.error(deliverVO.getDeliverCode() + TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_SHIPPED));
                }

                // 省市区处理
                OrderUtil.handleOrderAddress(areaMap, deliverVO);
            }
        }

        return AjaxResult.success(resultList);
    }


    /**
     * 模板下载
     *
     * @param response
     */
    @PostMapping("/template-export")
    public void batchDeliverExport(HttpServletResponse response) {
        ExcelUtil<DeliverTemplateVO> util = new ExcelUtil<>(DeliverTemplateVO.class);
        util.exportExcel(response, null, "物流模板");
    }

    /**
     * 立即发货导入
     *
     * @param file   导入文件
     * @param idList 发货单ID列表
     * @return
     * @throws Exception
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.IMPORT)
    @PostMapping("/immediate-import")
    public AjaxResult batchDeliverImport(MultipartFile file, @RequestParam("idList") List<Long> idList) throws Exception {
        ExcelUtil<DeliverTemplateParam> util = new ExcelUtil<>(DeliverTemplateParam.class);
        List<DeliverTemplateParam> deliverTemplateParamList = util.importExcel(file.getInputStream());

        // 返回数据
        List<DeliverTemplateVO> resultList = new ArrayList<>(idList.size());

        // 查询发货单信息
        List<SaDeliver> saDeliverList = iSaDeliverService.listByIds(idList);

        for (SaDeliver saDeliver : saDeliverList) {
            // 处理地址
//            String address = StringUtils.isNotEmpty(saDeliver.getRecAddress()) ? saDeliver.getRecAddress() : "";

            // 遍历导入数据，匹配发货单发货数据，如果相同则封装返回发货信息
            for (DeliverTemplateParam deliverTemplate : deliverTemplateParamList) {
                if (saDeliver.getRecName().equals(deliverTemplate.getRecName())
                        && saDeliver.getRecPhone().equals(deliverTemplate.getRecPhone())
                        // 2023.09.26 与供应链确认需求，只匹配收货人和联系方式
//                        && (deliverTemplate.getRecAddress().contains(address))
                ) {
                    // 收货人相同、收货电话相同、收货地址相同，则进行返回
                    resultList.add(DeliverTemplateVO.builder()
                            .pkId(saDeliver.getPkId())
                            .logisticsCompany(deliverTemplate.getLogisticsCompany().trim())
                            .logisticsCode(deliverTemplate.getLogisticsCode().trim())
                            .build());
                    break;
                }
            }
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 确认发货
     *
     * @return
     */
    @RepeatSubmitSimple
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.CONFIRM, remark = "确认发货")
    @PutMapping("/confirm")
    public AjaxResult confirm(@RequestBody List<DeliverConfirmParam> paramList) {
        if (CollectionUtils.isEmpty(paramList)) {
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }
        // 入库操作数据
        List<SaDeliver> deliverList = new ArrayList<>();
        // 发货单ID列表
        List<Long> deliverIdList = new ArrayList<>();

        // 当前用户ID
        Long userId = SecurityUtils.getUserId();
        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        for (DeliverConfirmParam deliverConfirmParam : paramList) {
            SaDeliver saDeliver = new SaDeliver();
            if (null == deliverConfirmParam.getPkId() || StringUtils.isAnyEmpty(deliverConfirmParam.getLogisticsCompany(), deliverConfirmParam.getLogisticsCode())) {
                continue;
            }

            saDeliver.setPkId(deliverConfirmParam.getPkId());
            saDeliver.setLogisticsCompany(deliverConfirmParam.getLogisticsCompany());
            saDeliver.setLogisticsCode(deliverConfirmParam.getLogisticsCode().trim().replaceAll("，", ","));
            saDeliver.setDeliverStatus(EDeliveryStatus.DELIVERED.getValue());
            deliverList.add(saDeliver);

            deliverIdList.add(deliverConfirmParam.getPkId());
        }
        if (deliverList.size() == 0) {
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }
        return toAjax(iSaDeliverService.batchDeliver(deliverList, deliverIdList, userId, pkCountry, userTokenService.getLoginUser()));
    }

    /**
     * 确认发货新
     *
     * @return
     */
    @RepeatSubmitSimple
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.CONFIRM, remark = "确认发货")
    @PutMapping("/confirm-new")
    public AjaxResult confirmNew(@RequestBody List<DeliverConfirmParam> paramList) {
        if (CollectionUtils.isEmpty(paramList)) {
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }
        // 入库操作数据
        List<SaDeliver> deliverList = new ArrayList<>();
        // 发货单ID列表
        List<Long> deliverIdList = new ArrayList<>();

        // 当前用户ID
        Long userId = SecurityUtils.getUserId();
        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        for (DeliverConfirmParam deliverConfirmParam : paramList) {
            SaDeliver saDeliver = new SaDeliver();
            if (null == deliverConfirmParam.getPkId()) {
                continue;
            }

            saDeliver.setPkId(deliverConfirmParam.getPkId());
            saDeliver.setDeliverStatus(EDeliveryStatus.DELIVERED.getValue());
            deliverList.add(saDeliver);

            deliverIdList.add(deliverConfirmParam.getPkId());
        }
        if (deliverList.size() == 0) {
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }
        return toAjax(iSaDeliverService.batchDeliverNew(deliverList, deliverIdList, userId, pkCountry, userTokenService.getLoginUser()));
    }

    /**
     * 修改单号数据
     *
     * @param deliverId 发货单ID
     * @return
     */
    @GetMapping("/change-code-data/{deliverId}")
    public AjaxResult changeCodeData(@PathVariable("deliverId") Long deliverId) {
        DeliverVO deliverVO = new DeliverVO();

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverVO> resultList = iSaDeliverService.deliverList(DeliverParam.builder()
                .deliverIdList(Collections.singletonList(deliverId))
                .build(), pkCountry);
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAreaMap(pkCountry).getData();

            deliverVO = resultList.get(0);

            if (EDeliveryStatus.DELIVERED.getValue() != deliverVO.getDeliverStatus()) {
                // 发货单未发货或已收货，不能修改物流单号
                return AjaxResult.error("发货单未发货或已收货，不能修改物流单号");
            }
            // 省市区处理
            OrderUtil.handleOrderAddress(areaMap, deliverVO);
        }

        return AjaxResult.success(deliverVO);
    }

    /**
     * 修改单号
     *
     * @param param 修改数据
     * @return
     */
    @RepeatSubmitSimple
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.IMMEDIATE_DELIVER, method = EOperationMethod.CONFIRM, remark = "修改单号")
    @PostMapping("/change-code")
    public AjaxResult changeCode(@RequestBody DeliverConfirmParam param) {
        if (null == param.getPkId() || StringUtils.isAnyEmpty(param.getLogisticsCode(), param.getLogisticsCompany())) {
            // 缺少参数
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }

        return toAjax(iSaDeliverService.simpleDeliver(param, SecurityUtils.getUserId(), SecurityUtils.getPkCountry()));
    }

}
