package com.jeeplus.pubmodules.purchase.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.pubmodules.oss.domain.WorkAttachment;
//import com.jeeplus.pubmodules.oss.mapper.OssServiceMapper;
//import com.jeeplus.pubmodules.oss.service.OssService;
import com.jeeplus.pubmodules.oss.service.dto.WorkAttachmentDto;
import com.jeeplus.pubmodules.purchase.domain.MaterialBasic;
import com.jeeplus.pubmodules.purchase.domain.MaterialDetailed;
import com.jeeplus.pubmodules.purchase.mapper.MaterialBasicMapper;
import com.jeeplus.pubmodules.purchase.mapper.MaterialDetailedMapper;
import com.jeeplus.pubmodules.purchase.service.dto.MaterialInfoDto;
import com.jeeplus.pubmodules.serialNumTpl.service.SerialnumTplService;
import com.jeeplus.pubmodules.supplier.domain.MaterialSupplier;
import com.jeeplus.pubmodules.supplier.mapper.MaterialSupplierMapper;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.jeeplus.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 王强
 * @create: 2022-12-02 16:26
 **/
@Service
public class MaterialService {

    @Resource
    private MaterialBasicMapper basicMapper;

    @Resource
    private SerialnumTplService serialnumTplService;

    @Resource
    private MaterialDetailedMapper detailedMapper;

//    @Resource
//    private OssServiceMapper ossServiceMapper;

    @Resource
    private IFlowableApi flowTaskService;

    @Resource
    private MaterialSupplierMapper materialSupplierMapper;

    /**
     * 列表查询
     */
    public IPage<MaterialInfoDto> list(Page<MaterialInfoDto> page , MaterialInfoDto dto) throws Exception{
        QueryWrapper<MaterialInfoDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, MaterialInfoDto.class);

        queryWrapper.eq("a.del_flag", "0");
        if (StringUtils.isNotEmpty(dto.getPurchaseSketch())) {
            queryWrapper.like("a.purchase_sketch", dto.getPurchaseSketch());
        }
        if (StringUtils.isNotEmpty(dto.getHandledByOffice())) {
            //先根据id查出是否是父节点，是父节点则查出所有的子节点信息
            List<String> childIds = basicMapper.findChildIds(dto.getHandledByOffice());
            if ( null != childIds & childIds.size()>0){
                childIds.add(dto.getHandledByOffice());
                queryWrapper.in("a.handled_by_office",childIds);
            }else {
                queryWrapper.eq("a.handled_by_office", dto.getHandledByOffice());
            }
        }
        if (StringUtils.isNotEmpty(dto.getStatus())) {
            queryWrapper.like("a.status", dto.getStatus());
        }
        //采购类别
        if (StringUtils.isNotEmpty(dto.getProcurementType())) {
            queryWrapper.like("b.procurement_type", dto.getProcurementType());
        }
        //经办人
        if (StringUtils.isNotEmpty(dto.getHandledBy())) {
            //根据经办人id查出经办人名称
//            String name = basicMapper.getHandledName(dto.getHandledBy());
//            dto.setHandledBy(name);
            queryWrapper.eq("su.id", dto.getHandledBy());
        }
        //合同金额
        //3、合同金额（区间）
        String[] contractAmounts = dto.getContractAmounts();
        if (contractAmounts != null) {
            if (StringUtils.isNotEmpty(contractAmounts[0])) {
                queryWrapper.ge("b.trade_total_price",contractAmounts[0]);
            }
            if (contractAmounts.length>1 && StringUtils.isNotEmpty(contractAmounts[1])) {
                queryWrapper.le("b.trade_total_price", contractAmounts[1]);
            }
        }
        String[] contractDates = dto.getContractDates();
        if (contractDates != null) {

            queryWrapper.between("a.create_time", contractDates[0], contractDates[1]);
        }
        if (ObjectUtil.isNotEmpty(dto)) {
            if (StringUtils.isNotBlank(dto.getSupplierId())) {
                List<MaterialDetailed> materialDetailedList = detailedMapper.selectList(new LambdaQueryWrapper<MaterialDetailed>().eq(MaterialDetailed::getSupplierId, dto.getSupplierId()));
                if (CollectionUtil.isNotEmpty(materialDetailedList)) {
                    List<String> containsIds = materialDetailedList.stream().map(MaterialDetailed::getBasicId).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(containsIds)) {
                        queryWrapper.in("a.id", containsIds);
                    } else {
                        return new Page<>();
                    }
                } else {
                    return new Page<>();
                }
            }
        }
        IPage<MaterialInfoDto> list = basicMapper.findList(page, queryWrapper);
        list.getRecords().stream().forEach(item -> {
            // 采购申请
            if (StringUtils.isNotBlank(item.getTaskId()) && StringUtils.isNotBlank(item.getStatus())) {
                if ("2".equals(item.getStatus())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIds(flowTaskService.getTaskAuditUsers(item.getTaskId()));  // 获取数据审核人
                }
            }
        });
        return list;
    }

    /**
     * 列表查询(报销使用)
     */
    public IPage<MaterialInfoDto> reimbursementList(Page<MaterialInfoDto> page , MaterialInfoDto dto) throws Exception{
        QueryWrapper<MaterialInfoDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, MaterialInfoDto.class);

        queryWrapper.eq("a.del_flag", "0");
        queryWrapper.eq("a.create_by_id", SpringUtil.getBean ( IUserApi.class ).getByToken (TokenProvider.getCurrentToken ( )).getId());
        if (StringUtils.isNotEmpty(dto.getPurchaseSketch())) {
            queryWrapper.like("a.purchase_sketch", dto.getPurchaseSketch());
        }
        if (StringUtils.isNotEmpty(dto.getHandledByOffice())) {
            //先根据id查出是否是父节点，是父节点则查出所有的子节点信息
            List<String> childIds = basicMapper.findChildIds(dto.getHandledByOffice());
            if ( null != childIds & childIds.size()>0){
                childIds.add(dto.getHandledByOffice());
                queryWrapper.in("a.handled_by_office",childIds);
            }else {
                queryWrapper.eq("a.handled_by_office", dto.getHandledByOffice());
            }
        }
        if (StringUtils.isNotEmpty(dto.getStatus())) {
            queryWrapper.like("a.status", dto.getStatus());
        }
        //采购类别
        if (StringUtils.isNotEmpty(dto.getProcurementType())) {
            queryWrapper.like("b.procurement_type", dto.getProcurementType());
        }
        //经办人
        if (StringUtils.isNotEmpty(dto.getHandledBy())) {
            //根据经办人id查出经办人名称
//            String name = basicMapper.getHandledName(dto.getHandledBy());
//            dto.setHandledBy(name);
            queryWrapper.eq("su.name", dto.getHandledBy());
        }
        //合同金额
        //3、合同金额（区间）
        String[] contractAmounts = dto.getContractAmounts();
        if (contractAmounts != null) {
            if (StringUtils.isNotEmpty(contractAmounts[0])) {
                queryWrapper.ge("b.trade_total_price",contractAmounts[0]);
            }
            if (StringUtils.isNotEmpty(contractAmounts[1])) {
                queryWrapper.le("b.trade_total_price", contractAmounts[1]);
            }
        }
        String[] contractDates = dto.getContractDates();
        if (contractDates != null) {

            queryWrapper.between("a.create_time", contractDates[0], contractDates[1]);
        }
        IPage<MaterialInfoDto> list = basicMapper.findList(page, queryWrapper);
        list.getRecords().stream().forEach(item -> {
            // 采购申请
            if (StringUtils.isNotBlank(item.getTaskId()) && StringUtils.isNotBlank(item.getStatus())) {
                if ("2".equals(item.getStatus())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIds(flowTaskService.getTaskAuditUsers(item.getTaskId()));  // 获取数据审核人
                }
            }
        });
        return list;
    }

    public String save(MaterialInfoDto dto) throws Exception{
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String bearerToken = authentication.getCredentials().toString();
        // 获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken (TokenProvider.getCurrentToken ( ));
        if (StringUtils.isNotEmpty(dto.getId()) && !dto.getId().equals("false")) {
            return update(dto, userDTO);
        } else {
            return add(dto, userDTO);
        }
    }

    public String add(MaterialInfoDto dto, UserDTO userDTO) throws Exception{
        // 生成id
        String id = UUID.randomUUID().toString().replace("-", "");
        // 生成编号
        String no = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), dto.BIZ_CODE,TokenProvider.getCurrentToken());
        // 保存基础信息表信息
        MaterialBasic info = new MaterialBasic();
        BeanUtils.copyProperties(dto, info);
        info.setId(id);
//        info.setNo(no);
        info.setPurchaseNo(no);
        info.setHandledBy(dto.getHandledById());
        info.setCreateById(userDTO.getId());
        info.setCreateTime(new Date());
        info.setUpdateById(userDTO.getId());
        info.setUpdateTime(new Date());
        info.setDelFlag(0);
        basicMapper.insert(info);
        // 保存详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
            for (MaterialDetailed detailed : dto.getDetailInfos()) {
                // 生成id
                String detailId = UUID.randomUUID().toString().replace("-", "");
                detailed.setId(detailId);
                detailed.setPurchaserAgent(detailed.getPurchaserAgentId());
                detailed.setProcurementType(detailed.getProcurementTypeId());
                detailed.setCreateById(userDTO.getId());
                detailed.setCreateTime(new Date());
                detailed.setUpdateById(userDTO.getId());
                detailed.setUpdateTime(new Date());
                detailed.setDelFlag(0);
                // 保存基础表信息主键值
                detailed.setBasicId(id);
                detailed.setTradeTotalPrice(dto.getTradeTotalPrice());
                detailedMapper.insert(detailed);
                //保存详情列表附件信息
                if (CollectionUtils.isNotEmpty(detailed.getFileInfoLost())){
                    saveFiles(detailed.getFileInfoLost(), userDTO, detailId);
                }

            }
        }
        // 保存附件列表信息
        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
            saveFiles(dto.getFiles(), userDTO, id);
        }
        return id;
    }

    public String update(MaterialInfoDto dto, UserDTO userDTO) {
        // 修改基础信息
        MaterialBasic info = new MaterialBasic();
        BeanUtils.copyProperties(dto, info);
        info.setUpdateById(userDTO.getId());
        info.setHandledBy(dto.getHandledById());
        info.setUpdateTime(new Date());
        basicMapper.updateById(info);
        // 修改报销详情列表信息
        // 删除原有数据
//        LambdaQueryWrapper<MaterialDetailed> detailWrapper = new LambdaQueryWrapper<>();
//        detailWrapper.eq(MaterialDetailed::getBasicId, dto.getId());
//        detailedMapper.delete(detailWrapper);
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {

            List<String> idList = detailedMapper.getIdByBasicId(info.getId());
            for (MaterialDetailed detailInfo : dto.getDetailInfos()) {
                //删除多余的领用详情
                //根据基础表id获取所有的详情表id
                if (null != idList) {
                    if (idList.contains(detailInfo.getId())){
                        idList.remove(detailInfo.getId());
                    }
                }
            }
            if (null != idList & idList.size()>0) {
                idList.forEach(id->{
                    detailedMapper.deleteById(id);
                });
            }

            for (MaterialDetailed detailInfo : dto.getDetailInfos()) {
                MaterialDetailed materialDetailed = detailedMapper.selectById(detailInfo.getId());
                if ( null == materialDetailed) {
                    // 生成id
                    String detailId = UUID.randomUUID().toString().replace("-", "");
                    detailInfo.setId(detailId);
                    detailInfo.setPurchaserAgent(detailInfo.getPurchaserAgentId());
                    detailInfo.setProcurementType(detailInfo.getProcurementTypeId());
                    detailInfo.setCreateById(userDTO.getId());
                    detailInfo.setCreateTime(new Date());
                    detailInfo.setUpdateById(userDTO.getId());
                    detailInfo.setUpdateTime(new Date());
                    detailInfo.setDelFlag(0);
                    // 保存基础表信息主键值
                    detailInfo.setBasicId(dto.getId());
                    detailInfo.setTradeTotalPrice(dto.getTradeTotalPrice());
                    detailedMapper.insert(detailInfo);
                    // 修改附件信息列表
                    if (CollectionUtils.isNotEmpty(detailInfo.getFileInfoLost())) {
                        saveFiles(detailInfo.getFileInfoLost(), userDTO, detailInfo.getId());
                    }
                } else {
                    detailInfo.setPurchaserAgent(detailInfo.getPurchaserAgentId());
                    detailInfo.setProcurementType(detailInfo.getProcurementTypeId());
                    detailInfo.setUpdateById(userDTO.getId());
                    detailInfo.setUpdateTime(new Date());
                    detailInfo.setBasicId(dto.getId());
                    detailInfo.setTradeTotalPrice(dto.getTradeTotalPrice());
                    detailedMapper.updateById(detailInfo);
                    if (CollectionUtils.isNotEmpty(detailInfo.getFileInfoLost())) {
                        updateFiles(detailInfo.getFileInfoLost(), userDTO, detailInfo.getId());
                    }
                }

            }
        }
        // 修改附件信息列表
        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
            updateFiles(dto.getFiles(), userDTO, dto.getId());
        }
        return dto.getId();
    }

    public MaterialInfoDto findById(String id) {
        MaterialInfoDto dto = new MaterialInfoDto();
        // 查询基础信息表
        MaterialBasic info = basicMapper.selectById(id);
        if (ObjectUtils.isNotEmpty(info)) {
            BeanUtils.copyProperties(info, dto);
            //将采购详情数据查出
            List<MaterialDetailed> detailedList = detailedMapper.getByBasicId(id);
            if (CollectionUtils.isNotEmpty(detailedList)){
                detailedList.forEach(detailed->{
                    // 供应商查询
                    if (StringUtils.isNotBlank(detailed.getIsSupplier()) && "2".equals(detailed.getIsSupplier()) &&
                            StringUtils.isNotBlank(detailed.getSupplierId())) {
                        MaterialSupplier materialSupplier = materialSupplierMapper.selectById(detailed.getSupplierId()); // 供应商信息
                        if (ObjectUtil.isNotEmpty(materialSupplier)) {
                            detailed.setSupplierName(materialSupplier.getName());
                        }
                    }
                    //附件信息
                    List<WorkAttachmentDto> acList = detailedMapper.getByAttachmentId(detailed.getId());
                    if (CollectionUtils.isNotEmpty(acList)) {
                        for (WorkAttachmentDto i : acList) {
                            i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                        }
                    }
                    detailed.setFileInfoLost(acList);
                });
            }
            dto.setDetailInfos(detailedList);
            //附件信息
            List<WorkAttachmentDto> files = detailedMapper.getByAttachmentId(info.getId());
            if (CollectionUtils.isNotEmpty(files)) {
                for (WorkAttachmentDto i : files) {
                    i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                }
            }
            //根据经办人id查出经办人的名称
            String name = basicMapper.getUserNameByUserId(info.getHandledBy());
            dto.setHandledBy(name);
            dto.setHandledById(info.getHandledBy());
            dto.setFiles(files);
        }
        return dto;
    }

    public String remove(String id) {
        // 删除基础信息表
        basicMapper.deleteById(id);
        // 删除详情列表 及对应附件信息
        List<MaterialDetailed> detailedList = detailedMapper.getByBasicId(id);
        if (null != detailedList){
            detailedList.forEach(de->{
                //附件
                List<WorkAttachmentDto> fileList = detailedMapper.getByAttachmentId(de.getId());
                if ( null != fileList ){
                    fileList.forEach(f->{
//                        ossServiceMapper.deleteById(f.getId());
                        SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteById(f.getId());
                    });
                }
                detailedMapper.deleteById(de.getId());
            });
        }
        // 删除附件信息
        SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteByAttachmentId(id);
//        LambdaQueryWrapper<WorkAttachment> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(WorkAttachment::getAttachmentId, id);
//        ossServiceMapper.delete(wrapper);
        return "操作成功";
    }

    public void updateStatusById(MaterialInfoDto dto) {
        basicMapper.updateStatusById(dto.getId(), dto.getStatus());
    }

    public List<MaterialDetailed> findTradeByTypeId (String typeId) {
        if (StringUtils.isNotBlank(typeId)) {
            List<MaterialDetailed> materialDetailedList = detailedMapper.getByTypeId(typeId);
            return materialDetailedList;
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 保存附件信息
     * @param list 待保存的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveFiles(List<WorkAttachmentDto> list, UserDTO userDTO, String id) {
        int j = 1;
        for (WorkAttachmentDto dto : list) {
            WorkAttachment i = new WorkAttachment();
            //包含了url、size、name
            i.setId(UUID.randomUUID().toString().replace("-", ""));
//            i.getCreateBy().setId(userDTO.getId());
            i.setCreateTime(new Date());
//            i.getUpdateBy().setId(userDTO.getId());
            i.setUpdateTime(new Date());
            i.setDelFlag(0);
            i.setUrl(dto.getUrl());
            //文件类型处理
            List<String> strings = Arrays.asList(dto.getName().split("\\."));
            if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(strings)) {
                i.setType(strings.get(1));
            }
            i.setAttachmentId(id);
            i.setAttachmentName(dto.getName());
            i.setAttachmentFlag("cwWorkContract");
            i.setFileSize(dto.getSize());
            i.setSort(j);
            Map<String,String> map = new HashMap<>();
            String workAttachment = JSON.toJSONString((i));
            String userDTOInfo = JSON.toJSONString((userDTO));
            map.put("workAttachment",workAttachment);
            map.put("userDTO",userDTOInfo);
            SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
//            ossServiceMapper.insertWorkAttachment(i, userDTO);
            j++;
        }
    }

    /**
     * 修改附件信息
     * @param list 待修改的附件列表
     * @param userDTO 当前登录用户
     * @param id 关联id
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateFiles(List<WorkAttachmentDto> list, UserDTO userDTO, String id) {
        int j = 1;
        String names = new String();
        //表中存在，但是传过来不存在，说明已删除，表中数据也要删除
        for (WorkAttachmentDto dto : list) {
            names = names + "," +dto.getUrl();
        }
        //查询保存的附件信息
        List<WorkAttachment> infoList = basicMapper.findFileList(id);
        if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(infoList)) {
            for (WorkAttachment i : infoList) {
                if (!names.contains(i.getUrl())) {
//                    ossServiceMapper.deleteById(i.getId());
                    SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteById(i.getId());
                }
            }
        }
        //保存信息
        for (WorkAttachmentDto dto : list) {
            //判断是否存在
            Integer isExit = basicMapper.findIsExit(id, dto.getName());
            if (isExit == 0) {
                WorkAttachment i = new WorkAttachment();
                //包含了url、size、name
                i.setId(UUID.randomUUID().toString().replace("-", ""));
//                i.getCreateBy().setId(userDTO.getId());
                i.setCreateTime(new Date());
//                i.getUpdateBy().setId(userDTO.getId());
                i.setUpdateTime(new Date());
                i.setDelFlag(0);
                i.setUrl(dto.getUrl());
                //文件类型处理
                List<String> strings = Arrays.asList(dto.getName().split("\\."));
                if (org.flowable.editor.language.json.converter.util.CollectionUtils.isNotEmpty(strings)) {
                    i.setType(strings.get(1));
                }
                i.setAttachmentId(id);
                i.setAttachmentName(dto.getName());
                i.setAttachmentFlag("cwWorkContract");
                i.setFileSize(dto.getSize());
                i.setSort(j);
                Map<String,String> map = new HashMap<>();
                String workAttachment = JSON.toJSONString((i));
                String userDTOInfo = JSON.toJSONString((userDTO));
                map.put("workAttachment",workAttachment);
                map.put("userDTO",userDTOInfo);
                SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
//                ossServiceMapper.insertWorkAttachment(i, userDTO);
                j++;
            }
        }
    }
}
