package com.yh.saas.plugin.yiliangyiyun.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.winsea.svc.base.base.entity.CommonRoleResource;
import com.winsea.svc.base.base.service.ICommonRoleResourceService;
import com.winsea.svc.base.security.entity.User;
import com.winsea.svc.base.security.util.AuthSecurityUtils;
import com.yh.saas.common.support.util.IdGenerator;
import com.yh.saas.plugin.yiliangyiyun.constant.NumberConstant;
import com.yh.saas.plugin.yiliangyiyun.constant.StatusEnum;
import com.yh.saas.plugin.yiliangyiyun.entity.*;
import com.yh.saas.plugin.yiliangyiyun.mapper.TranSettlementReportMapper;
import com.yh.saas.plugin.yiliangyiyun.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 汽运结算报表 服务实现类
 * </p>
 *
 * @author Gongdc
 * @since 2021-08-27
 */
@Service
public class TranSettlementReportServiceImpl extends ServiceImpl<TranSettlementReportMapper, TranSettlementReport> implements ITranSettlementReportService {

    @Autowired
    private INewWorkflowService workflowService;
    @SofaReference
    private ICommonRoleResourceService roleResourceService;
    @Autowired
    private IDriverPayeeInfoService driverPayeeInfoService;
    @Autowired
    private IDriverViewInfoService driverViewInfoService;
    @Autowired
    private IContractManagementInfoService contractManagementInfoService;
    @Autowired
    private ITranPriceApproveService tranPriceApproveService;
    @Autowired
    private ITranCarInfoService tranCarInfoService;
    @Autowired
    private ITranProcessInfoService tranProcessInfoService;

    /**
     * 汽运结算统计列表
     *
     * @param tranSettlementReport
     * @return
     */
    @Override
    public Page<TranSettlementReport> selectTranSettlementReport(TranSettlementReport tranSettlementReport) {
        Map<String, Object> pageView = new HashMap<>();
        pageView.put("startRecord", (tranSettlementReport.getCurrentPage() - 1)
                * tranSettlementReport.getPageSize());
        List<String> businessKeys = null;
        if ("1".equals(tranSettlementReport.getSearchType())) {
            businessKeys = workflowService.getTaskBusinessKeysByCode("TRANSPORTATION-SETTLEMENT-REPORT");
        }
        List<String> statusSet = new ArrayList<>();
        List<String> resourceIdList = this.getResourceIdList();
        if (resourceIdList.contains("transportationReport-Edit")) { // 填写，提交    权限做完以后替换
            List<String> statusList = Lists.newArrayList(StatusEnum.PUR_RETURN.getFlag());
            statusSet.addAll(statusList);
        }
        //公司id
        pageView.put("compId", tranSettlementReport.getCompId());
        pageView.put("searchKeyWord", tranSettlementReport.getSearchKeyWord());
        pageView.put("searchType", tranSettlementReport.getSearchType());
        pageView.put("pageSize", tranSettlementReport.getPageSize());
        pageView.put("currentPage", tranSettlementReport.getCurrentPage());
        pageView.put("tranTypeKey", tranSettlementReport.getTranTypeKey());
        pageView.put("taskNo", tranSettlementReport.getTaskNo());
        pageView.put("processNo", tranSettlementReport.getProcessNo());
        pageView.put("carId", tranSettlementReport.getCarId());
        pageView.put("contractNo", tranSettlementReport.getContractNo());
        pageView.put("roleFlag", tranSettlementReport.getRoleFlag());
        pageView.put("statusFlag", tranSettlementReport.getStatusFlag());
        pageView.put("businessKeys", businessKeys);
        pageView.put("statusSet", statusSet);
        // 查询结算统计信息总数
        Integer dataCount = baseMapper.getCountByCondition(pageView);
        List<TranSettlementReport> dataList = baseMapper.getListByCondition(pageView);
        if (!CollectionUtils.isEmpty(dataList)) {
            for (TranSettlementReport tranSettlementReport1 : dataList) {
                //查看修改结算重量记录
                List<TranPriceApprove> tranPriceApproveList = tranPriceApproveService.selectList(new EntityWrapper<TranPriceApprove>()
                        .eq(TranPriceApprove.QueryFiles.PROCESS_ID, tranSettlementReport1.getId())
                        .eq("record_type", "2").eq(TranPriceApprove.QueryFiles.DELETE_FLAG, NumberConstant.CONSTANT0));
                if (!CollectionUtils.isEmpty(tranPriceApproveList)) {
                    tranSettlementReport1.setTranPriceApproveList(tranPriceApproveList);
                }
                //查询账户信息
                List<DriverViewInfo> driverViewInfoList = driverViewInfoService.selectList(new EntityWrapper<DriverViewInfo>()
                        .eq("driver_name", tranSettlementReport1.getName())
                        .eq("delete_flag", "0"));
                if (!CollectionUtils.isEmpty(driverViewInfoList)) {
                    for (DriverViewInfo driverViewInfo : driverViewInfoList) {
                        List<DriverPayeeInfo> driverPayeeInfoList = driverPayeeInfoService.selectList(new EntityWrapper<DriverPayeeInfo>()
                                .eq("driver_id", driverViewInfo.getId())
                                .eq("delete_flag", "0"));
                        tranSettlementReport1.setDriverPayeeInfoList(driverPayeeInfoList);
                    }
                }
                String taskId = "";
                // 只有待审核状态才有taskId
                if (StringUtils.isNotBlank(tranSettlementReport1.getWorkflowId())) {
                    JSONObject jsonObject = workflowService.getActiveTask(Lists.newArrayList(tranSettlementReport1.getWorkflowId()), tranSettlementReport1.getId());
                    taskId = jsonObject.getString("taskId");
                    tranSettlementReport1.setTaskId(taskId);
                }
            }
        }
        Page<TranSettlementReport> page = new Page<>();
        page.setRecords(dataList == null ? Lists.newArrayList() : dataList);
        page.setTotal(dataCount == null ? 0 : dataCount);
        page.setCurrent(tranSettlementReport.getCurrentPage());
        page.setSize(tranSettlementReport.getPageSize());
        return page;
    }


    private List<String> getResourceIdList() {
        User currentUser = AuthSecurityUtils.getCurrentUserInfo();
        // 当前登录人主要角色
        return roleResourceService.getBindResourcesByUserId(currentUser.getUserId()).stream()
                .map(CommonRoleResource::getResourceId).collect(Collectors.toList());

    }

    /**
     * 修改结算重量0修改扣款1修改已开发票2设置本次账户3
     *
     * @param tranSettlementReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String editTranSettlementReport(TranSettlementReport tranSettlementReport) {
        //查询汽运结算信息
        TranSettlementReport tranSettlementReport1 = this.selectById(tranSettlementReport.getId());
        if (tranSettlementReport1 != null) {
            //0 修改结算重量
            if (tranSettlementReport.getFlag() == 0) {
                //生成记录
                TranPriceApprove tranPriceApprove = new TranPriceApprove();
                tranPriceApprove.setProcessId(tranSettlementReport1.getId());
                tranPriceApprove.setId(IdGenerator.generateUUID());
                tranPriceApprove.setReviewer(tranSettlementReport.getReviewer());
                tranPriceApprove.setResult(tranSettlementReport1.getCarNo());
                tranPriceApprove.setBeforeModification(tranSettlementReport1.getSettlementWeight());
                tranPriceApprove.setAfterModification(tranSettlementReport.getSettlementWeight());
                tranPriceApprove.setTranPrice(tranSettlementReport1.getTransportPrice());
                tranPriceApprove.setRecordType("2");
                tranPriceApproveService.insert(tranPriceApprove);
                tranSettlementReport1.setSettlementWeight(tranSettlementReport.getSettlementWeight());
                tranSettlementReport1.setManualFlag("1");
                //应付=单价x结算重量-扣款
                tranSettlementReport1.setAmountIngPayable(tranSettlementReport1.getTransportPrice() * tranSettlementReport.getSettlementWeight() - Float.valueOf(tranSettlementReport1.getDeductionAmount() != null ? tranSettlementReport1.getDeductionAmount() : "0"));
                //更改汽运结算信息
                this.updateById(tranSettlementReport1);
                return "OK";
            }
            //1 修改扣款
            else if (tranSettlementReport.getFlag() == 1) {
                tranSettlementReport1.setDeductionAmount(tranSettlementReport.getDeductionAmount());
                tranSettlementReport1.setAmountIngPayable(tranSettlementReport1.getAmountIngPayable()-Float.valueOf(tranSettlementReport.getDeductionAmount()));
                tranSettlementReport1.setAmountNotPayable(tranSettlementReport1.getAmountNotPayable()-Float.valueOf(tranSettlementReport.getDeductionAmount()));
                //更改汽运结算信息
                this.updateById(tranSettlementReport1);
                return "OK";
            }
            //3 设置本次账户
            else if (tranSettlementReport.getFlag() == 3) {
                tranSettlementReport1.setCardNo(tranSettlementReport.getCardNo());
                //更改汽运结算信息
                this.updateById(tranSettlementReport1);
                return "OK";
            }
            //2 修改已开发票
            else {
                tranSettlementReport1.setAlreadyInvoice(tranSettlementReport1.getAlreadyInvoice() + tranSettlementReport.getAlreadyInvoice());
                //更改汽运结算信息
                this.updateById(tranSettlementReport1);
                return "OK";
            }
        }
        return "NG";
    }

    /**
     * 合同编号下拉列表
     *
     * @param compId
     */
    @Override
    public List<ContractManagementInfo> selectContractNoList(String compId) {
        //查我方承运的合同
        List<ContractManagementInfo> contractManagementInfoList = contractManagementInfoService.selectList(new EntityWrapper<ContractManagementInfo>()
                .eq("comp_id", compId)
                .eq("deliver_type", "1")
                .eq("delete_flag", "0")
                .orderBy("update_date", false));
        for (ContractManagementInfo contractManagementInfo : contractManagementInfoList) {
            Float money = 0.0f;
            //查汽运结算报表
            List<TranSettlementReport> tranSettlementReportList = this.selectList(new EntityWrapper<TranSettlementReport>()
                    .eq("contract_no", contractManagementInfo.getContractNo())
                    .eq("delete_flag", "0"));
            if (!CollectionUtils.isEmpty(tranSettlementReportList)) {
                for (TranSettlementReport tranSettlementReport : tranSettlementReportList) {
                    money = money + tranSettlementReport.getAmountNotPayable();
                }
                //有未付金额
                if (money > 0) {
                    contractManagementInfo.setReportStatus("待结算");
                } else {
                    contractManagementInfo.setReportStatus("已结算");
                }
            }
        }
        return contractManagementInfoList;
    }

    /**
     * 出纳付款
     *
     * @param tranSettlementReport
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String payMoney(TranSettlementReport tranSettlementReport) {
        List<TranSettlementReport> tranSettlementReportList = tranSettlementReport.getTranSettlementReportList();
        Float money = tranSettlementReport.getMoney();
        //付款多条
        if (!CollectionUtils.isEmpty(tranSettlementReportList)) {
            //汽运
            if ("1".equals(tranSettlementReportList.get(0).getTranTypeKey())){
                for (TranSettlementReport tranSettlementReport1 : tranSettlementReportList) {
                    TranSettlementReport tranSettlementReport2=this.selectById(tranSettlementReport1.getId());
                    //付款金额大于本次循环未付金额
                    if (money >= tranSettlementReport1.getAmountNotPayable()) {
                        money = money - tranSettlementReport1.getAmountNotPayable();
                        //全部付款
                        tranSettlementReport1.setStatus(StatusEnum.PUR_PAYaLL.getName());
                        tranSettlementReport1.setStatusFlag(StatusEnum.PUR_PAYaLL.getFlag());
                        tranSettlementReport1.setPaymentDate(tranSettlementReport.getPaymentDate());
                        tranSettlementReport1.setPaymentScreenshot(tranSettlementReport2.getPaymentScreenshot()!=null?tranSettlementReport2.getPaymentScreenshot()+'$'+tranSettlementReport.getPaymentScreenshot():tranSettlementReport.getPaymentScreenshot());
                        tranSettlementReport1.setAmountEdPayable(tranSettlementReport1.getAmountEdPayable() + tranSettlementReport1.getAmountNotPayable());
                        tranSettlementReport1.setAmountNotPayable(0.0f);
                        this.updateById(tranSettlementReport1);
                    } else if (money > 0) {
                        Float moneyTmp = money - tranSettlementReport1.getAmountNotPayable();
                        //部分付款
                        tranSettlementReport1.setStatus(StatusEnum.PUR_PAY.getName());
                        tranSettlementReport1.setStatusFlag(StatusEnum.PUR_PAY.getFlag());
                        tranSettlementReport1.setPaymentDate(tranSettlementReport.getPaymentDate());
                        tranSettlementReport1.setPaymentScreenshot(tranSettlementReport2.getPaymentScreenshot()!=null?tranSettlementReport2.getPaymentScreenshot()+'$'+tranSettlementReport.getPaymentScreenshot():tranSettlementReport.getPaymentScreenshot());
                        tranSettlementReport1.setAmountEdPayable(tranSettlementReport1.getAmountEdPayable() + money);
                        tranSettlementReport1.setAmountNotPayable(tranSettlementReport1.getAmountNotPayable() - money);
                        this.updateById(tranSettlementReport1);
                        money = moneyTmp;
                    } else {
                        break;
                    }
                }
            }
            //非汽运
            else{
                //付款金额大于未付金额
                if (money >= tranSettlementReportList.get(0).getAmountNotPayable()) {
                    for (TranSettlementReport tranSettlementReport1 : tranSettlementReportList) {
                        //全部付款
                        tranSettlementReport1.setStatus(StatusEnum.PUR_PAYaLL.getName());
                        tranSettlementReport1.setStatusFlag(StatusEnum.PUR_PAYaLL.getFlag());
                        tranSettlementReport1.setPaymentDate(tranSettlementReport.getPaymentDate());
                        tranSettlementReport1.setPaymentScreenshot(tranSettlementReport.getPaymentScreenshot());
                        tranSettlementReport1.setAmountEdPayable(tranSettlementReport1.getAmountEdPayable() + tranSettlementReport1.getAmountNotPayable());
                        tranSettlementReport1.setAmountNotPayable(0.0f);
                        this.updateById(tranSettlementReport1);
                    }
                }else{
                    for (TranSettlementReport tranSettlementReport1 : tranSettlementReportList) {
                        //部分付款
                        tranSettlementReport1.setStatus(StatusEnum.PUR_PAY.getName());
                        tranSettlementReport1.setStatusFlag(StatusEnum.PUR_PAY.getFlag());
                        tranSettlementReport1.setPaymentDate(tranSettlementReport.getPaymentDate());
                        tranSettlementReport1.setPaymentScreenshot(tranSettlementReport.getPaymentScreenshot());
                        tranSettlementReport1.setAmountEdPayable(tranSettlementReport1.getAmountEdPayable() + money);
                        tranSettlementReport1.setAmountNotPayable(tranSettlementReport1.getAmountNotPayable() - money);
                        this.updateById(tranSettlementReport1);
                    }
                }
            }
        }
        return "ok";
    }

    /**
     * 批量开发票
     *
     * @param tranSettlementReport
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String openInvoiceList(TranSettlementReport tranSettlementReport) {
        List<TranSettlementReport> tranSettlementReportList = tranSettlementReport.getTranSettlementReportList();
        //批量
        if (!CollectionUtils.isEmpty(tranSettlementReportList)) {
            for (TranSettlementReport tranSettlementReport1 : tranSettlementReportList) {
                //已开发票金额等于已付金额
                tranSettlementReport1.setAlreadyInvoice(tranSettlementReport1.getAmountEdPayable());
                this.updateById(tranSettlementReport1);
            }
        }
        return "ok";
    }

    /**
     * 查看
     * @param id
     * @return
     */
    @Override
    public TranSettlementReport getInfo(String id) {
        TranSettlementReport tranSettlementReport=this.selectById(id);
        TranCarInfo tranCarInfo=tranCarInfoService.selectById(tranSettlementReport.getCarId());
        if (tranCarInfo!=null){
            TranProcessInfo tranProcessInfo=tranProcessInfoService.selectById(tranCarInfo.getProcessId());
            if (tranProcessInfo!=null){
                tranSettlementReport.setSend(tranProcessInfo.getSendPrivate()+tranProcessInfo.getSendCity()+tranProcessInfo.getSendArea()+tranProcessInfo.getSendDetailedAddress());
                tranSettlementReport.setReceive(tranProcessInfo.getReceivePrivate()+tranProcessInfo.getReceiveCity()+tranProcessInfo.getReceiveArea()+tranProcessInfo.getReceiveDetailedAddress());
            }
        }
      ContractManagementInfo contractManagementInfo = contractManagementInfoService.selectOne(new EntityWrapper<ContractManagementInfo>()
                .eq("comp_id", tranSettlementReport.getCompId())
                .eq("contract_no", tranSettlementReport.getContractNo())
                .eq("delete_flag", "0"));
        //销售
        if ("1".equals(contractManagementInfo.getContractType())){
            tranSettlementReport.setCustomer(contractManagementInfo.getBuyer());
        }
        else{
            tranSettlementReport.setCustomer(contractManagementInfo.getSeller());
        }
        return tranSettlementReport;
    }

}
