package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.SalesLeaderMapper;
import com.crm.manager.dao.mapper.SalesPerformanceMapper;
import com.crm.manager.dao.repository.SalesLeaderExtraRepository;
import com.crm.manager.dao.repository.SalesLeaderRepository;
import com.crm.manager.dao.repository.UserInfoRepository;
import com.crm.manager.service.SalesLeaderService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.sales.SalesLeaderListDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.sales.*;
import com.crm.rely.backend.core.pojo.table.SalesLeaderExtraTable;
import com.crm.rely.backend.core.pojo.table.SalesLeaderTable;
import com.crm.rely.backend.core.pojo.table.UserInfoTable;
import com.crm.rely.backend.core.pojo.view.SalesLeaderListview;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SalesLeaderServiceImpl implements SalesLeaderService {

    @Autowired
    private SalesLeaderRepository repository;
    @Autowired
    private SalesLeaderMapper mapper;
    @Autowired
    private SalesLeaderExtraRepository salesLeaderExtraRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private SalesPerformanceMapper salesPerformanceMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SalesLeaderAddEntity entity) throws Exception {
        SalesLeaderTable leaderTable = repository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable != null) {
            throw ServiceException.exception("销售团队已设置");
        }
        UserInfoTable userTable = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        SalesLeaderTable table = new SalesLeaderTable();
        BeanUtils.copyProperties(entity, table);

        repository.save(table);

        SalesPerformanceListEntity perEntity = new SalesPerformanceListEntity();
        perEntity.setSalesNo(table.getSalesNo());
        perEntity.setEndDate(new Date());
        perEntity.setStartDate(getStartDate(userTable.getEntryDate()));
        mqSendService.send(Constants.SALES_PERFORMANCE_STATISTICS, perEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SalesLeaderDeleteEntitys entity) throws Exception {
        List<SalesLeaderTable> tables = repository.findAllByIdIn(entity.getIds());
        if (tables == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        repository.delete(tables);

        for (SalesLeaderTable table : tables) {
            UserInfoTable userTable = userInfoRepository.findFirstByIbNo(table.getSalesNo());
            if (userTable == null) {
                continue;
            }
            salesPerformanceMapper.deleteSalesPerformanceByDate(null,table.getSalesNo());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SalesLeaderUpdateEntity entity) throws Exception {
        SalesLeaderTable leaderTable = repository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable != null && leaderTable.getId() != entity.getId()) {
            throw ServiceException.exception("销售团队已设置");
        }
        UserInfoTable userTable = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        SalesLeaderTable table = repository.findFirstById(entity.getId());
        String delSalesNo = table.getSalesNo();
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        BeanUtils.copyProperties(entity, table);
        repository.save(table);

        salesPerformanceMapper.deleteSalesPerformanceByDate(null, delSalesNo);

        SalesPerformanceListEntity perEntity = new SalesPerformanceListEntity();
        perEntity.setSalesNo(table.getSalesNo());
        perEntity.setEndDate(new Date());
        perEntity.setStartDate(getStartDate(userTable.getEntryDate()));
        mqSendService.send(Constants.SALES_PERFORMANCE_STATISTICS, perEntity);
    }

    @Override
    public ResultWithPagerDto<SalesLeaderListDto> searchPageList(SalesLeaderSearchEntity entity) throws ServiceException {
        Integer count = mapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<SalesLeaderListview> views = mapper.pageList(entity);
        List<SalesLeaderListDto> dtos = new ArrayList<>(views.size());
        for (SalesLeaderListview view : views) {
            dtos.add(transformSearchListDto(view));
        }

        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    public SalesLeaderListDto searchSingle(SingleLongEntity entity) throws ServiceException {
        SalesLeaderTable table = repository.getFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        SalesLeaderListDto salesLeaderListDto = new SalesLeaderListDto();
        BeanUtils.copyProperties(table, salesLeaderListDto);

        return salesLeaderListDto;
    }

    @Override
    public List<SalesLeaderListDto> getAllList(SalesLeaderSearchEntity entity) throws ServiceException {
        entity.setPage(null);
        List<SalesLeaderListview> views = mapper.pageList(entity);
        List<SalesLeaderListDto> dtos = new ArrayList<>(views.size());
        for (SalesLeaderListview view : views) {
            dtos.add(transformSearchListDto(view));
        }
        return dtos;
    }

    @Override
    public List<SalesLeaderListDto> searchAddIbNo(SalesLeaderSearchEntity entity) throws ServiceException {
        List<SalesLeaderListDto> dtos = new ArrayList<>();
        List<SalesLeaderListview> views = mapper.searchExtraIbNo(entity.getSalesNo());

        for (SalesLeaderListview view : views) {
            dtos.add(transformSearchListDto(view));
        }

        return dtos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSalesIbNo(SalesLeaderAddEntity entity) throws Exception {
        SalesLeaderTable leaderTable = repository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        UserInfoTable userTable = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        if (entity.getAddIbNo() != null && entity.getAddIbNo().size() > 0) {
            for (String salesNo : entity.getAddIbNo()) {
                SalesLeaderExtraTable extraTable = new SalesLeaderExtraTable();
                extraTable.setLeaderSalesNo(entity.getSalesNo());
                extraTable.setSalesNo(salesNo);
                extraTable.setType(1);
                salesLeaderExtraRepository.save(extraTable);
            }
        }

        if (entity.getExcludeIbNo() != null && entity.getExcludeIbNo().size() > 0) {
            for (String salesNo : entity.getExcludeIbNo()) {
                SalesLeaderExtraTable extraTable = new SalesLeaderExtraTable();
                extraTable.setLeaderSalesNo(entity.getSalesNo());
                extraTable.setSalesNo(salesNo);
                extraTable.setType(2);
                salesLeaderExtraRepository.save(extraTable);
            }
        }

        SalesPerformanceListEntity perEntity = new SalesPerformanceListEntity();
        perEntity.setSalesNo(leaderTable.getSalesNo());
        perEntity.setEndDate(new Date());
        perEntity.setStartDate(getStartDate(userTable.getEntryDate()));
        mqSendService.send(Constants.SALES_PERFORMANCE_STATISTICS, perEntity);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSalesIbNo(SalesLeaderAddEntity entity) throws Exception {
        SalesLeaderTable leaderTable = repository.getFirstBySalesNo(entity.getSalesNo());
        if (leaderTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        List<SalesLeaderExtraTable> tables = salesLeaderExtraRepository.findAllBySalesNoIn(entity.getDelIbNo());
        if (tables == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        salesLeaderExtraRepository.delete(tables);

        UserInfoTable userTable = userInfoRepository.findFirstByIbNo(entity.getSalesNo());
        if (userTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        SalesPerformanceListEntity perEntity = new SalesPerformanceListEntity();
        perEntity.setSalesNo(leaderTable.getSalesNo());
        perEntity.setEndDate(new Date());
        perEntity.setStartDate(getStartDate(userTable.getEntryDate()));
        mqSendService.send(Constants.SALES_PERFORMANCE_STATISTICS, perEntity);
    }

    private SalesLeaderListDto transformSearchListDto(SalesLeaderListview view) {
        SalesLeaderListDto dto = new SalesLeaderListDto();
        BeanUtils.copyProperties(view, dto);
        dto.setSalesDate(DateUtil.formatDate(view.getSalesDate()));
        return dto;
    }

    public Date getStartDate(Date entryDate) throws Exception {
        if (entryDate == null) {
            return DateUtil.getMonthStart(DateUtil.addMonth(new Date(), -3));
        } else {
            return DateUtil.getMonthStart(DateUtil.addMonth(entryDate, -3));
        }
    }

}
