package com.artfess.yhxt.contract.manager.impl;

import com.artfess.base.context.BaseContext;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.FileUtil;
import com.artfess.base.util.HttpUtil;
import com.artfess.base.util.ZipUtil;
import com.artfess.file.util.CheckFileFormatUtil;
import com.artfess.file.util.MinioUtil;
import com.artfess.sysConfig.persistence.manager.SysIdentityManager;
import com.artfess.uc.dao.OrgDao;
import com.artfess.uc.model.Org;
import com.artfess.yhxt.basedata.manager.AccessoryManager;
import com.artfess.yhxt.basedata.manager.RoadManager;
import com.artfess.yhxt.basedata.model.Accessory;
import com.artfess.yhxt.basedata.model.BizRoadsideFacilities;
import com.artfess.yhxt.basedata.model.Road;
import com.artfess.yhxt.budget.manager.YearBudgetDetailedManager;
import com.artfess.yhxt.budget.manager.YearBudgetManager;
import com.artfess.yhxt.budget.model.YearBudget;
import com.artfess.yhxt.budget.model.YearBudgetDetailed;
import com.artfess.yhxt.check.regular.model.BridgeOftenCheck;
import com.artfess.yhxt.contract.dao.ContractItemDao;
import com.artfess.yhxt.contract.dao.ContractPaymentDao;
import com.artfess.yhxt.contract.manager.BillOfQuantitiesManager;
import com.artfess.yhxt.contract.manager.ContractItemManager;
import com.artfess.yhxt.contract.manager.ContractPaymentManager;
import com.artfess.yhxt.contract.model.*;
import com.artfess.yhxt.contract.dao.ContractDao;
import com.artfess.yhxt.contract.manager.ContractManager;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.yhxt.contract.vo.ContractVo;
import com.artfess.yhxt.contract.vo.WorkOrderParamVo;
import com.artfess.yhxt.statistics.vo.Org4ContractVO;
import com.artfess.yhxt.statistics.vo.Org4bridgeInfoVO;
import com.artfess.yhxt.statistics.vo.Org4roadSideVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.jsonwebtoken.lang.Assert;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 合同表 服务实现类
 *
 * @author 超级管理员
 * @company 阿特菲斯信息技术有限公司
 * @since 2021-08-06
 */
@Service
public class ContractManagerImpl extends BaseManagerImpl<ContractDao, Contract> implements ContractManager {
/*    @Value(value = "${minio.minio_url}")
    private String minioUrl;*/

    @Resource
    private ContractItemManager itemManager;
    @Resource
    private ContractPaymentManager paymentManager;

    @Resource
    private AccessoryManager accessoryManager;
    @Resource
    private ContractPaymentDao contractPaymentDao;
    @Resource
    private ContractItemDao contractItemDao;
    @Resource
    private SysIdentityManager sysIdentityManager;


    @Autowired
    private YearBudgetManager yearBudgetManager;

    @Autowired
    private YearBudgetDetailedManager yearBudgetDetailedManager;

    @Resource
    private BillOfQuantitiesManager billOfQuantitiesManager;

    @Resource
    private OrgDao orgDao;

    @Resource
    private RoadManager roadManager;

    @Resource
    BaseContext baseContext;

    @Override
    public List<Org4ContractVO> getContractCount(String year) {
        String orgId ;
        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId())&&!"0".equals(baseContext.getCurrentOrgId())){
            orgId = baseContext.getCurrentOrgId();
        }else {
            orgId = "1419863231459102720";
        }
        List<Org4ContractVO> lists = new ArrayList<>();

        List<Org> rtnList = new ArrayList<Org>();

        QueryWrapper<Org> rgQueryWrapper = new QueryWrapper<>();
        rgQueryWrapper.eq("is_dele_","0");
        List<Org> allList = orgDao.selectList(rgQueryWrapper);

        List<Org> list = getOrgChild(allList, orgId, rtnList);
        for (Org org: list){
            Org4ContractVO fvo = new Org4ContractVO();
            BeanUtils.copyProperties(org,fvo);
            lists.add(fvo);
        }
        lists = getChild(lists,orgId);


        return this.setCount(lists,year);
    }

    public List<Org4ContractVO> setCount(List<Org4ContractVO> list,String year){
        // 获取迭代器
        Iterator<Org4ContractVO> it = list.iterator();

        while(it.hasNext()){
            Org4ContractVO orgVO = it.next();
            Integer grade = Integer.valueOf(orgVO.getGrade());
            List<String> roadList = new ArrayList<>();
            if (grade<4){
                QueryWrapper<Road> roadQueryWrapper = new QueryWrapper<>();
                roadQueryWrapper.like( "COMPANY_IDS_", orgVO.getId());
                roadList = roadManager.list(roadQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }else if (grade==4){
                QueryWrapper<Road> roadByNameQueryWrapper = new QueryWrapper<>();
                roadByNameQueryWrapper.eq("NAME_",orgVO.getName());
                roadList =
                        roadManager.list(roadByNameQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }
            if (roadList.size()>0){
                orgVO = this.newCount(roadList,orgVO,year);
            }else {
                it.remove();
            }
            if (orgVO.getChirldren().size()>0&&Integer.valueOf(orgVO.getGrade())<4){
                this.setCount(orgVO.getChirldren(),year);
            }
        }
        return list;
    }

    public Org4ContractVO newCount(List<String> ids, Org4ContractVO orgVO,String year) {
        BigDecimal allMoney = new BigDecimal(0);
        BigDecimal contractMoney = new BigDecimal(0);
        BigDecimal payMoney = new BigDecimal(0);
        BigDecimal finishRate = new BigDecimal(0);
        for (String roadId : ids){
            //获取金额
            QueryWrapper<YearBudget> queryWrapperYearBudget = new QueryWrapper<>();
            queryWrapperYearBudget.eq("IS_DELE_", "0");
            queryWrapperYearBudget.eq("ROAD_SEGMENT_ID_", roadId);
            queryWrapperYearBudget.eq("ASCRIPTION_YEAR_", String.valueOf(year));
            YearBudget yearBudget = yearBudgetManager.getOne(queryWrapperYearBudget);
            if (yearBudget!=null){
                allMoney = allMoney.add(yearBudget.getBudgetSum());
            }

            QueryWrapper<YearBudgetDetailed> detailedQueryWrapper = new QueryWrapper<>();
            detailedQueryWrapper.eq("YEAR_BUDGET_ID_",yearBudget.getId());
            detailedQueryWrapper.eq("IS_DELE_","0");
            detailedQueryWrapper.eq("EXPENDITURE_TYPE_","FXCBXZC");
            detailedQueryWrapper.eq("BUDGET_TYPE_","RCJF");
            detailedQueryWrapper.eq("BUDGET_ITEM_","RCYH");
            detailedQueryWrapper.eq("BUDGET_CONTENT","日常养护");
            YearBudgetDetailed detaileds = yearBudgetDetailedManager.getOne(detailedQueryWrapper);
            payMoney = payMoney.add(detaileds.getImageProgress().multiply(new BigDecimal(10000)));

            QueryWrapper<Contract> contractWrapper = new QueryWrapper<>();
            contractWrapper.eq("ROAD_SEGMENT_ID_",roadId);
            contractWrapper.eq("IS_DELE_","0");
            contractWrapper.orderByDesc("CREATE_TIME_");
            contractWrapper.last("limit 1");
            Contract contract = this.getOne(contractWrapper);
            if (contract!=null){
                contractMoney = contractMoney.add(new BigDecimal(String.valueOf(contract.getContractAmount())));

            }
        }

        orgVO.setAllMoney(allMoney);
        orgVO.setContractMoney(contractMoney);
        orgVO.setPayMoney(payMoney);
        if (!payMoney.equals(BigDecimal.ZERO)&&!contractMoney.equals(BigDecimal.ZERO)){
            finishRate = finishRate.add(payMoney.divide(contractMoney,2,BigDecimal.ROUND_UP));
        }
        if ("4".equals(orgVO.getGrade())){
            orgVO.setRoadSegmentId(ids.get(0));
        }
        orgVO.setFinishRate(finishRate);
        return orgVO;
    }

    public static List<Org> getOrgChild(List<Org> orgList, String parentId, List<Org> rtnList) {
        for (Org org : orgList) {
            // 遍历出父id等于参数的id，add进子节点集合
            if (parentId.equals(org.getParentId())) {
                // 递归遍历下一级
                getOrgChild(orgList, org.getId(), rtnList);
                rtnList.add(org);
            }
        }
        return rtnList;
    }

    public static List<Org4ContractVO> getChild(List<Org4ContractVO> allList, String pCode) {
        List<Org4ContractVO> returnList = new ArrayList<>();
        for (Org4ContractVO entity : allList){
            if (pCode.equals(entity.getParentId())) {
                entity.setChirldren(getChild(allList, entity.getId()));
                returnList.add(entity);
            }
        }
        return returnList;
    }

    @Override
    public PageList<Contract> queryContract(QueryFilter<Contract> queryFilter) {
        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Contract> result = baseMapper.queryContract(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        //List<Contract> records = result.getRecords();
        return new PageList<>(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveContractVo(ContractVo vo) {
        Contract contract = vo.getContract();
        contract.setIsDele("0");
        //合同唯一编号
        String rcyhht = sysIdentityManager.nextId("rcyhht");
        contract.setUniqueNumber(rcyhht);
        //保存合同表
        this.save(contract);
        //保存合同明细
        String id = contract.getId();
        if (vo.getItemList().size() > 0) {
            vo.getItemList().forEach(s -> {
                s.setContractId(id);
                this.itemManager.save(s);
            });
        }

        //保存合同支付
        vo.getPaymentList().forEach(s -> {
            s.setContractId(id);
            paymentManager.save(s);
        });
        //保存附件信息

        List<Accessory> accessories = vo.getAccessories();
        if (accessories.size()>0){
            accessories.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveBatch(accessories);
        }
        return id;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateContractVo(ContractVo vo) {
        Contract contract = vo.getContract();

        //保存合同表
        this.update(contract);
        //保存合同明细
        String id = contract.getId();
        if (vo.getItemList().size() > 0) {
            QueryWrapper<ContractItem> wrapper = new QueryWrapper<>();
            wrapper.eq("CONTRACT_ID_",id);
            this.itemManager.getBaseMapper().delete(wrapper);
            vo.getItemList().forEach(s -> {
                s.setContractId(id);
                this.itemManager.saveOrUpdate(s);
            });
        }

        //保存合同支付
        QueryWrapper<ContractPayment> wrapper = new QueryWrapper<>();
        wrapper.eq("CONTRACT_ID_",id);
        this.paymentManager.getBaseMapper().delete(wrapper);
        if (vo.getPaymentList().size()>0) {
            vo.getPaymentList().forEach(s -> {
                s.setContractId(id);
                paymentManager.saveOrUpdate(s);
            });
        }

        //修改附件信息
        List<Accessory> accessories = vo.getAccessories();
        //删除原来的附件信息
        this.accessoryManager.delAccessoryBySourceId(id);
        if (accessories.size()>0) {
            //获取附件信息
            accessories.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveOrUpdateBatch(accessories);
        }
        return id;
    }

    @Override
    public void checkUniqueNumber(Contract contract) {
        QueryWrapper<Contract> queryWrapper = new QueryWrapper<>();
        if (contract.getId() != null) {
            queryWrapper.notIn("ID_", contract.getId());
        }
        if (StringUtils.isNotBlank(contract.getUniqueNumber())) {
            queryWrapper.eq("UNIQUE_NUMBER_", contract.getUniqueNumber());
        }
        queryWrapper.eq("is_dele_", 0);
        List<Contract> list = this.baseMapper.selectList(queryWrapper);
        if (list.size() > 0) {
            throw new RuntimeException("唯一编码已存在");
        }
    }

    @Override
    public String minioContractUpload(MultipartFile file, String sourceId) {
        Accessory accessory = new Accessory();
        accessory.setSourceId(sourceId);
        if (file.isEmpty() || file.getSize() == 0) {
            throw new RuntimeException("文件为空");
        }

        try {

            String fileName = file.getOriginalFilename();
            System.out.println(fileName);
            accessory.setName(fileName);
            assert fileName != null;
            String name =  DigestUtils.md5Hex(UUID.randomUUID().toString()) + fileName.substring(fileName.lastIndexOf("."));

            String url = MinioUtil.uploadRelative(file, "/contract", name, "yhxt");
            //验证图片类型
            //String ext = CheckFileFormatUtil.getFileType((FileInputStream) file.getInputStream());
            String ext = fileName.substring(fileName.lastIndexOf(".")+1);
            System.out.println(ext);
            accessory.setType(ext);
            accessory.setSuffix(ext);
            accessory.setUrl(url);
            accessory.setIsDele("0");
            this.accessoryManager.create(accessory);
            return url;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void downloadContractUpload(String ids, HttpServletResponse response) throws IOException {
        if (StringUtils.isNotBlank(ids)){
            String s1 = ResourceUtils.getURL("classpath:").getPath();
            System.out.println(s1);
            String file = "download/contract";
            File path = new File(file);
            if (!path.exists()) {
                path.mkdirs();
            }
            List<String> idList = Arrays.asList(ids.split(","));
            List<Accessory> accessories = this.accessoryManager.listByIds(idList);
            accessories.forEach(s->{
                String url = s.getUrl();
                String substring = url.substring(url.lastIndexOf("/"));
                FileOutputStream out = null;
                try {
                    out = new FileOutputStream(path+"/"+s.getName());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                System.out.println("contract"+substring);
                MinioUtil.downFile("yhxt", "contract"+substring, out, false);

            });
            ZipUtil.zip(file,true);
            String zipPath=file+".zip";
            HttpUtil.downLoadFile(response, zipPath, "contract.zip");
            // 删除导出的文件
            FileUtil.deleteFile(zipPath);
        }

    }

    @Override
    public ContractVo getContractById(String id) {
        ContractVo contractVo = new ContractVo();
        Contract contract = this.getById(id);
        contractVo.setContract(contract);
        QueryWrapper<ContractPayment> queryWrapper = new QueryWrapper<ContractPayment>();
        queryWrapper.eq("CONTRACT_ID_",id);
        List<ContractPayment> contractPayments = this.contractPaymentDao.selectList(queryWrapper);
        if (contractPayments.size()>0){
            contractVo.setPaymentList(contractPayments);
        }

        QueryWrapper<ContractItem> wrapper = new QueryWrapper<>();
        wrapper.eq("CONTRACT_ID_",id);
        List<ContractItem> contractItems = this.contractItemDao.selectList(wrapper);
        if (contractItems.size()>0){
            contractVo.setItemList(contractItems);
        }
    //查询附件信息
        List<Accessory> accessoryList = this.accessoryManager.getAccessoryBySourceId(id);
        contractVo.setAccessories(accessoryList);
        return contractVo;
    }

    @Override
    public void minioContractDel(List<String> asList) {
        asList.forEach(s -> {
            this.accessoryManager.minIoRemoveFile(s, "contract", "yhxt");
        });
    }


}
