package com.jeeplus.test.cw.workClientInfo.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.projectRecords.domain.CwProjectClientInfo;
import com.jeeplus.test.cw.projectRecords.mapper.CwProjectClientInfoMapper;
import com.jeeplus.test.cw.workClientInfo.domain.CwWorkClientBase;
import com.jeeplus.test.cw.workClientInfo.domain.CwWorkClientBilling;
import com.jeeplus.test.cw.workClientInfo.domain.CwWorkClientContact;
import com.jeeplus.test.cw.workClientInfo.domain.CwWorkClientType;
import com.jeeplus.test.cw.workClientInfo.mapper.*;
import com.jeeplus.test.cw.workClientInfo.service.dto.CwWorkClientBaseDTO;
import com.jeeplus.test.cw.workClientInfo.service.dto.CwWorkClientBillingDTO;
import com.jeeplus.test.cw.workClientInfo.service.dto.CwWorkClientContactDTO;
import com.jeeplus.test.cw.workClientInfo.service.mapstruct.CwWorkClientBaseWrapper;
import com.jeeplus.test.cw.workClientInfo.service.mapstruct.CwWorkClientBillingWrapper;
import com.jeeplus.test.cw.workClientInfo.service.mapstruct.CwWorkClientContactWrapper;
import com.jeeplus.test.cw.workClientInfo.service.mapstruct.CwWorkClientTypeWrapper;
import com.jeeplus.test.mould.service.SerialnumTplService;
import com.jeeplus.test.oss.service.OssService;
import com.jeeplus.test.program.configuration.projectList.service.dto.ProjectListDto;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class CwWorkClientService extends ServiceImpl<CwWorkClientBaseMapper, CwWorkClientBase> {

    @Resource
    private CwWorkClientBaseMapper cwWorkClientBaseMapper;
    @Resource
    private CwWorkClientBillingService cwWorkClientBillingService;
    @Resource
    private CwWorkClientContactService cwWorkClientContactService;
    @Resource
    private CwWorkClientTypeService cwWorkClientTypeService;
    @Resource
    private CwManageLevelTypeService cwManageLevelTypeService;
    @Resource
    private CwOrganizationTypeService cwOrganizationTypeService;
    @Resource
    private SerialnumTplService serialnumTplService;
    @Resource
    private OssService ossService;
    @Resource
    private CwProjectClientInfoMapper cwProjectClientInfoMapper;


    public IPage<CwWorkClientBaseDTO> findList(Page<CwWorkClientBaseDTO> page, CwWorkClientBaseDTO cwWorkClientBaseDTO) throws Exception{
        QueryWrapper<CwWorkClientBase> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwWorkClientBaseWrapper.INSTANCE.toEntity(cwWorkClientBaseDTO), CwWorkClientBase.class );
        queryWrapper.eq("cw_wcb.del_flag","0");
        queryWrapper.orderByDesc("cw_wcb.create_date");
        if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO)) {
            if (ArrayUtil.isNotEmpty(cwWorkClientBaseDTO.getCreateDates())) {
                queryWrapper.between("cw_wcb.create_date", cwWorkClientBaseDTO.getCreateDates()[0], cwWorkClientBaseDTO.getCreateDates()[1]);
            }
            if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO.getCwWorkClientTypeDTO())){
                if (StringUtils.isNotBlank(cwWorkClientBaseDTO.getCwWorkClientTypeDTO().getOwnershipType())) {
                    queryWrapper.eq("cw_wct.ownership_type",cwWorkClientBaseDTO.getCwWorkClientTypeDTO().getOwnershipType());
                }
            }
            if (StringUtils.isNotBlank(cwWorkClientBaseDTO.getProjectId())){
                List<CwProjectClientInfo> cwProjectClientInfos = cwProjectClientInfoMapper.selectList(new QueryWrapper<CwProjectClientInfo>().lambda().eq(CwProjectClientInfo::getProjectId, cwWorkClientBaseDTO.getProjectId()));
                List<String> ids = cwProjectClientInfos.stream().distinct().map(CwProjectClientInfo::getClientId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(ids)) {
                    queryWrapper.in("cw_wcb.id",ids);
                } else {
                    return new Page<>();
                }
            }
        }
        return cwWorkClientBaseMapper.findList(page, queryWrapper);
    }

    public IPage<CwWorkClientBaseDTO> findListTree(Page<CwWorkClientBaseDTO> page, CwWorkClientBaseDTO cwWorkClientBaseDTO) throws Exception{
        QueryWrapper<CwWorkClientBase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cw_wcb.del_flag","0");
        queryWrapper.orderByDesc("cw_wcb.create_date");
        if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO)) {
            if (StringUtils.isNotBlank(cwWorkClientBaseDTO.getName()) ||
                    StringUtils.isNotBlank(cwWorkClientBaseDTO.getNo()) ||
                    StringUtils.isNotBlank(cwWorkClientBaseDTO.getType()) ||
                    StringUtils.isNotBlank(cwWorkClientBaseDTO.getIndustry())) {
                List<String> ids = new ArrayList<>();
                List<CwWorkClientBase> list = this.list(new QueryWrapper<CwWorkClientBase>().lambda()
                        .like(StringUtils.isNotBlank(cwWorkClientBaseDTO.getName()),CwWorkClientBase::getName, cwWorkClientBaseDTO.getName())
                        .like(StringUtils.isNotBlank(cwWorkClientBaseDTO.getNo()),CwWorkClientBase::getNo, cwWorkClientBaseDTO.getNo())
                        .eq(StringUtils.isNotBlank(cwWorkClientBaseDTO.getType()),CwWorkClientBase::getType, cwWorkClientBaseDTO.getType())
                        .eq(StringUtils.isNotBlank(cwWorkClientBaseDTO.getIndustry()),CwWorkClientBase::getIndustry, cwWorkClientBaseDTO.getIndustry())
                );
                list.stream().forEach(item->{
                    ids.add(item.getId());
                    if (StringUtils.isNotBlank(item.getOneUpCompany())) {
                        String parentId = item.getOneUpCompany();
                        while (true) {
                            CwWorkClientBase byId = this.getOne(new QueryWrapper<CwWorkClientBase>().lambda().eq(CwWorkClientBase::getId, parentId));
                            if (ObjectUtil.isNotEmpty(byId)) {
                                ids.add(byId.getId());
                                if (StringUtils.isBlank(byId.getOneUpCompany())) {
                                    break;
                                } else {
                                    parentId = byId.getOneUpCompany();
                                }
                            }
                        }
                    }
                    List<String> childIdList = this.list(new QueryWrapper<CwWorkClientBase>().lambda().eq(CwWorkClientBase::getOneUpCompany, item.getId())).stream().map(CwWorkClientBase::getId).collect(Collectors.toList());
                    while (true) {
                        if (CollectionUtil.isNotEmpty(childIdList)) {
                            childIdList.stream().forEach(childId->{
                                ids.add(childId);
                            });
                            List<String> childIdS = this.list(new QueryWrapper<CwWorkClientBase>().lambda().in(CwWorkClientBase::getOneUpCompany, childIdList)).stream().map(CwWorkClientBase::getId).collect(Collectors.toList());
                            if (CollectionUtil.isNotEmpty(childIdS)) {
                                childIdList = childIdS;
                            } else {
                                break;
                            }
                        } else {
                            break;
                        }
                    }
                });
                List<String> lastIdList = ids.stream().distinct().collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(lastIdList)){
                    queryWrapper.in("cw_wcb.id",lastIdList);
                } else {
                    return new Page<>();
                }
            }
            if (StringUtils.isNotBlank(cwWorkClientBaseDTO.getStatus())) {
                queryWrapper.eq("cw_wcb.status",cwWorkClientBaseDTO.getStatus());
            }
        }
        return cwWorkClientBaseMapper.findList(page, queryWrapper);
    }

    public CwWorkClientBaseDTO queryById(String id) {

        CwWorkClientBaseDTO cwWorkClientBaseDTO = cwWorkClientBaseMapper.queryById(id);

        return cwWorkClientBaseDTO;
    }

    public String saveForm(CwWorkClientBaseDTO cwWorkClientBaseDTO) throws Exception{
        if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO)) {
            if (StringUtils.isEmpty(cwWorkClientBaseDTO.getId())) {
                cwWorkClientBaseDTO.setCreateBy(new UserDTO());
            }
        }
        CwWorkClientBase cwWorkClientBase = CwWorkClientBaseWrapper.INSTANCE.toEntity(cwWorkClientBaseDTO);
        if(ObjectUtil.isNotEmpty(cwWorkClientBase)){
            if(StringUtils.isBlank(cwWorkClientBase.getId())){
                UserDTO userDTO = UserUtils.getCurrentUserDTO();
                String no = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), CwWorkClientBaseDTO.BIZ_CODE);
                cwWorkClientBase.setNo(no);
            }
        }
        this.saveOrUpdate(cwWorkClientBase);
        if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO)) {
            // 附件
            ossService.saveOrUpdateFileList(cwWorkClientBaseDTO.getWorkAttachmentDtoList(),cwWorkClientBase.getId(),"cw_work_client");
            // 客户类型
            if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO.getCwWorkClientTypeDTO())){
                CwWorkClientType cwWorkClientType = CwWorkClientTypeWrapper.INSTANCE.toEntity(cwWorkClientBaseDTO.getCwWorkClientTypeDTO());
                cwWorkClientType.setClientId(cwWorkClientBase.getId());
                cwWorkClientTypeService.saveOrUpdate(cwWorkClientType);
            }
            // 开票信息
            if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO.getCwWorkClientBillingDTOList())){
                List<String> ids = cwWorkClientBaseDTO.getCwWorkClientBillingDTOList().stream().filter(item -> {
                    if (StringUtils.isNotBlank(item.getId())) {
                        return true;
                    }
                    return false;
                }).distinct().map(CwWorkClientBillingDTO::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(ids)){
                    cwWorkClientBillingService.remove(new QueryWrapper<CwWorkClientBilling>().lambda()
                            .eq(CwWorkClientBilling::getClientId,cwWorkClientBase.getId()).notIn(CwWorkClientBilling::getId,ids));
                } else {
                    cwWorkClientBillingService.remove(new QueryWrapper<CwWorkClientBilling>().lambda().eq(CwWorkClientBilling::getClientId,cwWorkClientBase.getId()));
                }
                cwWorkClientBaseDTO.getCwWorkClientBillingDTOList().stream().forEach(item->{
                    CwWorkClientBilling cwWorkClientBilling = CwWorkClientBillingWrapper.INSTANCE.toEntity(item);
                    if (StringUtils.isEmpty(item.getId())) {
                        cwWorkClientBilling.setClientId(cwWorkClientBase.getId());
                    }
                    cwWorkClientBillingService.saveOrUpdate(cwWorkClientBilling);
                });
            } else {
                cwWorkClientBillingService.remove(new QueryWrapper<CwWorkClientBilling>().lambda().eq(CwWorkClientBilling::getClientId,cwWorkClientBase.getId()));
            }
            // 联系人信息
            if (ObjectUtil.isNotEmpty(cwWorkClientBaseDTO.getCwWorkClientContactDTOList())){
                List<String> ids = cwWorkClientBaseDTO.getCwWorkClientContactDTOList().stream().filter(item -> {
                    if (StringUtils.isNotBlank(item.getId())) {
                        return true;
                    }
                    return false;
                }).distinct().map(CwWorkClientContactDTO::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(ids)){
                    cwWorkClientContactService.remove(new QueryWrapper<CwWorkClientContact>().lambda()
                            .eq(CwWorkClientContact::getClientId,cwWorkClientBase.getId()).notIn(CwWorkClientContact::getId,ids));
                } else {
                    cwWorkClientContactService.remove(new QueryWrapper<CwWorkClientContact>().lambda().eq(CwWorkClientContact::getClientId,cwWorkClientBase.getId()));
                }
                cwWorkClientBaseDTO.getCwWorkClientContactDTOList().stream().forEach(item->{
                    CwWorkClientContact cwWorkClientContact = CwWorkClientContactWrapper.INSTANCE.toEntity(item);
                    if (StringUtils.isEmpty(item.getId())) {
                        cwWorkClientContact.setClientId(cwWorkClientBase.getId());
                    }
                    cwWorkClientContactService.saveOrUpdate(cwWorkClientContact);
                });
            } else {
                cwWorkClientContactService.remove(new QueryWrapper<CwWorkClientContact>().lambda().eq(CwWorkClientContact::getClientId,cwWorkClientBase.getId()));
            }
        }
        return cwWorkClientBase.getId();
    }

    public ResponseEntity saveClient(CwWorkClientBaseDTO cwWorkClientBaseDTO) throws Exception{
        this.saveForm(cwWorkClientBaseDTO);
        return ResponseEntity.ok("保存成功");
    }

    public ResponseEntity deleteByIds(String ids) {
        String idArray[] =ids.split(",");
        this.removeByIds (Lists.newArrayList (idArray));
        return ResponseEntity.ok ("删除成功");
    }

    public String updateStatusById(CwWorkClientBaseDTO cwWorkClientBaseDTO) {
        CwWorkClientBase cwWorkClientBase = CwWorkClientBaseWrapper.INSTANCE.toEntity(cwWorkClientBaseDTO);
        cwWorkClientBaseMapper.update(cwWorkClientBase, new QueryWrapper<CwWorkClientBase>().lambda().eq(CwWorkClientBase::getId, cwWorkClientBase.getId()));
        return "操作成功";
    }

}
