/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.bizorder.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhs.trans.service.impl.TransService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
import vip.xiaonuo.biz.modular.bizorderconfig.entity.BizOrderConfig;
import vip.xiaonuo.biz.modular.bizorderconfig.service.BizOrderConfigService;
import vip.xiaonuo.biz.modular.bizsaleorder.entity.BizSaleOrder;
import vip.xiaonuo.biz.modular.bizsaleorder.service.BizSaleOrderService;
import vip.xiaonuo.biz.modular.customer.entity.BizCustomer;
import vip.xiaonuo.biz.modular.customer.service.BizCustomerService;
import vip.xiaonuo.biz.modular.bizorder.param.*;
import vip.xiaonuo.biz.modular.goodsConf.entity.BizGoodsConf;
import vip.xiaonuo.biz.modular.goodsConf.service.BizGoodsConfService;
import vip.xiaonuo.biz.modular.record.entity.BizRecord;
import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
import vip.xiaonuo.biz.modular.bizorder.mapper.BizOrderMapper;
import vip.xiaonuo.biz.modular.bizorder.service.BizOrderService;

import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单管理Service接口实现类
 *
 * @author fanzherong
 * @date  2025/03/21 17:16
 **/
@Service
public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> implements BizOrderService {

    @Resource
    private BizCustomerService bizCustomerService;

    @Resource
    private TransService transService;

    @Resource
    private BizGoodsConfService bizGoodsConfService;

    @Resource
    private BizOrderConfigService orderConfigService;

    @Resource
    private BizConfigService bizConfigService;

    @Resource
    private BizSaleOrderService bizSaleOrderService;

    @Resource(name = "loginUserApi")
    private SaBaseLoginUserApi loginUserApi;

    @Override
    public Page<BizOrder> page(BizOrderPageParam bizOrderPageParam) {
        QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
        return this.getBaseMapper().getPage(CommonPageRequest.defaultPage(), queryWrapper);
    }

    public QueryWrapper<BizOrder> getQueryWrapper(BizOrderPageParam bizOrderPageParam){
        QueryWrapper<BizOrder> queryWrapper = new QueryWrapper<BizOrder>().checkSqlInjection();
        //订单名称查询
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderName())){
            queryWrapper.like("bo.order_name",bizOrderPageParam.getOrderName());
        }
        //订单编号查询
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderNumber())){
            queryWrapper.like("bo.order_number",bizOrderPageParam.getOrderNumber());
        }
        //客户名称查询
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getCustomerName())){
            queryWrapper.like("bc.name",bizOrderPageParam.getCustomerName());
        }
        //货品名称查询
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getGoodsName())){
            queryWrapper.like("bg.`GOODS_NAME`",bizOrderPageParam.getGoodsName());
        }
        //状态查询
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderStatus())){
            queryWrapper.eq("bo.order_status",bizOrderPageParam.getOrderStatus());
        }
        //订单来源
        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderSource())){
            queryWrapper.eq("bo.order_source",bizOrderPageParam.getOrderSource());
        }
        // 校验数据范围
        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
        if(ObjectUtil.isEmpty(loginUserDataScope)) {
            queryWrapper.eq("bo.customer_id", StpLoginUserUtil.getLoginUser().getCustomerId());
        }
        queryWrapper.eq("bo.delete_flag","NOT_DELETE");
        queryWrapper.orderByDesc("bo.create_time");
        return queryWrapper;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(BizOrderAddParam bizOrderAddParam) {
        //查询时间段内货品重量
        BizGoodsConf bizGoodsConf = bizGoodsConfService.getById(bizOrderAddParam.getDeliveryTimeId());
        if(ObjectUtil.isNull(bizGoodsConf)){
            throw new CommonException("未查询到时间段信息！");
        }
        if(bizOrderAddParam.getOrderWeight().multiply(new BigDecimal(1000)).compareTo(new BigDecimal(bizGoodsConf.getLastWeight())) > 0 ){
            throw new CommonException("当前时间段货品余量不足！");
        }
        BizOrder bizOrder = BeanUtil.toBean(bizOrderAddParam, BizOrder.class);
        bizOrder.setGoodId(bizGoodsConf.getGoodsId());
        //数据库默认存KG，页面展示用吨
        bizOrder.setOrderWeight(bizOrder.getOrderWeight().multiply(new BigDecimal(1000)));
        //来源，手动新增
        bizOrder.setOrderSource("2");
        bizOrder.setOrderStatus("0");
        this.save(bizOrder);

        //修改时段配置内物品重量
        bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrderAddParam.getOrderWeight().multiply(new BigDecimal(1000)).doubleValue());

        //修改销售订单状态
        if(ObjectUtil.isNotEmpty(bizOrderAddParam.getSaleOrderInfo())){
            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrderAddParam.getSaleOrderInfo());
            if(ObjectUtil.isNotNull(bizSaleOrder)){
                bizSaleOrder.setSaleStatus("2");
                bizSaleOrderService.updateById(bizSaleOrder);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(BizOrderEditParam bizOrderEditParam) {
        //查询时间段内货品重量
        BizGoodsConf bizGoodsConf = bizGoodsConfService.getById(bizOrderEditParam.getDeliveryTimeId());
        if(ObjectUtil.isNull(bizGoodsConf)){
            throw new CommonException("未查询到时间段信息！");
        }
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        if(bizOrder.getOrderWeight().compareTo(bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000))) != 0 ){
            if(bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)).
                    compareTo(new BigDecimal(bizGoodsConf.getLastWeight()).add(bizOrder.getOrderWeight())) > 0 ){
                throw new CommonException("当前时间段货品余量不足！");
            }

            //修改了提货时段，原来时段的货物重量还原，新的提货时段货物扣减
            //旧的提货时段
            BizGoodsConf goodsConf = bizGoodsConfService.getById(bizOrder.getDeliveryTimeId());
            //修改时段配置内物品重量
            bizGoodsConfService.editUsedWeight(goodsConf.getId(),bizOrder.getOrderWeight().negate().doubleValue());

            //修改新时段
            bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)).doubleValue());

        }else{
            if(!StringUtils.equals(bizOrderEditParam.getDeliveryTimeId(),bizOrder.getDeliveryTimeId())){
                //修改了提货时段，原来时段的货物重量还原，新的提货时段货物扣减
                //旧的提货时段
                BizGoodsConf goodsConf = bizGoodsConfService.getById(bizOrder.getDeliveryTimeId());
                //修改时段配置内物品重量
                bizGoodsConfService.editUsedWeight(goodsConf.getId(),bizOrder.getOrderWeight().negate().doubleValue());

                //修改新时段
                bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)).doubleValue());
            }
        }
        //判断是否修改订单
        if(!StringUtils.equals(bizOrder.getSaleOrderInfo(),bizOrderEditParam.getSaleOrderInfo())){
            long count = this.count(new QueryWrapper<BizOrder>().lambda().eq(BizOrder::getSaleOrderInfo, bizOrderEditParam.getSaleOrderInfo()));
            if(count>0){
                throw new CommonException("销售订单已经添加过！");
            }
            //修改之前订单状态
            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
            if(ObjectUtil.isNotNull(bizSaleOrder)){
                bizSaleOrder.setSaleStatus("1");
                bizSaleOrderService.updateById(bizSaleOrder);
            }

            //修改现在订单状态
            BizSaleOrder saleOrder = bizSaleOrderService.getById(bizOrderEditParam.getSaleOrderInfo());
            if(ObjectUtil.isNotNull(saleOrder)){
                saleOrder.setSaleStatus("2");
                bizSaleOrderService.updateById(saleOrder);
            }
        }
        BeanUtil.copyProperties(bizOrderEditParam, bizOrder);
        bizOrder.setGoodId(bizGoodsConf.getGoodsId());
        //设置订单重量
        if(bizOrder.getOrderWeight().compareTo(bizOrderEditParam.getOrderWeight()) != 0){
            bizOrder.setOrderWeight(bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)));
        }else{
            bizOrder.setOrderWeight(bizOrder.getOrderWeight().multiply(new BigDecimal(1000)));
        }
        this.updateById(bizOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizOrderIdParam> bizOrderIdParamList) {
        //执行删除操作前，将重量回写
        for(BizOrderIdParam bizOrderIdParam : bizOrderIdParamList){
            BizOrder bizOrder = this.queryEntity(bizOrderIdParam.getId());
            BizGoodsConf bizGoodsConf = bizGoodsConfService.getById(bizOrder.getDeliveryTimeId());
            if(ObjectUtil.isNotNull(bizGoodsConf)){
                //修改时段配置内物品重量
                bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrder.getOrderWeight().negate().doubleValue());
            }

            //查询销售订单信息
            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
            if(ObjectUtil.isNotNull(bizSaleOrder)){
                bizSaleOrder.setSaleStatus("1");
                bizSaleOrderService.updateById(bizSaleOrder);
            }
        }
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(bizOrderIdParamList, BizOrderIdParam::getId));
    }

    @Override
    public BizOrder detail(BizOrderIdParam bizOrderIdParam) {
        return this.queryEntity(bizOrderIdParam.getId());
    }

    @Override
    public BizOrder queryEntity(String id) {
        BizOrder bizOrder = this.getById(id);
        if(ObjectUtil.isEmpty(bizOrder)) {
            throw new CommonException("订单管理不存在，id值为：{}", id);
        }
        return bizOrder;
    }

    @Override
    public List<BizCustomer> getCustomerById(BizOrderIdParam bizOrderIdParam) {
        if(ObjectUtil.isNotEmpty(bizOrderIdParam.getId())){
            List<BizCustomer> customerList = bizCustomerService.list(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getId, bizOrderIdParam.getId()));
            return customerList;
        }
        return null;
    }

    @Override
    public void bindCustomerId(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        if(ObjectUtil.isNotEmpty(bizOrderEditParam.getCustomerIdList())){
            bizOrder.setCustomerId(bizOrderEditParam.getCustomerIdList().get(0));
        }
        this.updateById(bizOrder);
    }

    @Override
    public void exportRecord(BizOrderPageParam bizOrderPageParam, HttpServletResponse response) throws IOException {
        QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
        List<BizOrder> orderList = this.getBaseMapper().getPage(queryWrapper);
        String fileName = "订单报表.xlsx";
        List<BizOrderExportResult> list = Lists.newArrayList();
        transService.transBatch(orderList);
        for(BizOrder bizOrder : orderList){
            BizOrderExportResult bizOrderExportResult = new BizOrderExportResult();
            BeanUtil.copyProperties(bizOrder, bizOrderExportResult);
            //bizOrderExportResult.setOrderSourceName((String) bizOrder.getTransMap().get("orderSourceName"));
            bizOrderExportResult.setOrderStatusName((String) bizOrder.getTransMap().get("orderStatusName"));
            list.add(bizOrderExportResult);
        }
        CommonExportUtil.export(fileName, BizOrderExportResult.class,list,response,"订单报表");
    }

    @Override
    public void endOrder(BizOrderIdParam bizOrderIdParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderIdParam.getId());
        bizOrder.setOrderStatus("2");
        this.updateById(bizOrder);
    }

    @Override
    public List<BizOrder> getList() {
        return this.list(new QueryWrapper<BizOrder>().lambda().in(BizOrder::getOrderStatus,"3","4"));
    }

    @Override
    public void updateOrderSign(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        if(ObjectUtil.isEmpty(bizOrderEditParam.getOrderSign())){
            throw new CommonException("签名不能为空！");
        }
        String orderSign = bizOrderEditParam.getOrderSign();
        if(bizOrderEditParam.getOrderSign().contains(StrUtil.COMMA)) {
            orderSign = StrUtil.split(orderSign, StrUtil.COMMA).get(1);
        }
        String base64 = ImgUtil.toBase64DataUri(ImgUtil.scale(ImgUtil.toImage(orderSign),
                100, 50, null), ImgUtil.IMAGE_TYPE_PNG);

        bizOrder.setOrderSign(base64);
        bizOrder.setOrderStatus("2");
        this.updateById(bizOrder);
    }

    @Transactional
    @Override
    public void orderConfirm(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        bizOrder.setOrderStatus("3");
        this.updateById(bizOrder);

        //存取预约次数配置
        BizOrderConfig bizOrderConfig = new BizOrderConfig();
        bizOrderConfig.setOrderId(bizOrder.getId());
        BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
        if(ObjectUtil.isNotNull(bizConfig)){
            bizOrderConfig.setApplyNumber(bizConfig.getApplyCount());
        }
        orderConfigService.save(bizOrderConfig);
    }

    @Override
    public void endOrder(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        if(bizOrder.getNetWeight().compareTo(BigDecimal.ZERO) != 0){
            BigDecimal orderBalance = bizOrder.getOrderWeight().subtract(bizOrder.getNetWeight());
            BigDecimal result = orderBalance.divide(bizOrder.getOrderWeight()).multiply(new BigDecimal(100));
            if(result.compareTo(new BigDecimal(20)) <= 0){
                //大于80%不需要审核
                bizOrder.setOrderStatus("7");

                //销售订单结束
                BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
                if(ObjectUtil.isNotNull(bizSaleOrder)){
                    bizSaleOrder.setSaleStatus("3");
                    bizSaleOrderService.updateById(bizSaleOrder);
                }
            }else{
                bizOrder.setOrderStatus("5");
            }
        }else{
            bizOrder.setOrderStatus("5");
        }
        bizOrder.setEndReason(bizOrderEditParam.getEndReason());
        this.updateById(bizOrder);
    }

    @Override
    public void auditOrder(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        if(ObjectUtil.isNotEmpty(bizOrderEditParam.getAuditFlag())){
            if(StringUtils.equals(bizOrderEditParam.getAuditFlag(),"true")){
                //驳回
                bizOrder.setOrderStatus("4");
                bizOrder.setOrderReason(bizOrderEditParam.getOrderReason());
            }else{
                bizOrder.setOrderStatus("7");

                //销售订单结束
                BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
                if(ObjectUtil.isNotNull(bizSaleOrder)){
                    bizSaleOrder.setSaleStatus("3");
                    bizSaleOrderService.updateById(bizSaleOrder);
                }
            }
            this.updateById(bizOrder);
        }
    }

    @Override
    public void submit(BizOrderEditParam bizOrderEditParam) {
        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
        bizOrder.setOrderStatus("1");
        this.updateById(bizOrder);
    }

    public static void main(String[] args) {
        String result = "";
        try {
            URL url = new URL("http://web.duanxinwang.cc/asmx/smsservice.aspx");
            StringBuilder params = new StringBuilder();
            params.append("name=").append("13375207977dxw");
            params.append("&pwd=").append("4AD0C7ED32CDD49C4CC2940B4095");
            params.append("&mobile=").append("15896183719");
            params.append("&content=").append("您的登陆密码为：14817030请尽快登录！");
            params.append("&sign=").append("淮安市保障房建设管理中心");
            params.append("&type=").append("pt");
            URLConnection connection = url.openConnection();
            connection.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "utf-8");
            out.write(params.toString()); //post的关键所在！
            out.flush();
            out.close();
            String temp = "";
            InputStream is = connection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            while (( temp = br.readLine()) != null) {
                result += temp;
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        System.out.printf("result:"+result);
    }
}
