package com.crm.manager.service.impl;

import com.crm.manager.dao.mapper.SysAreaMapper;
import com.crm.manager.service.SysAreaService;
import com.crm.manager.service.UserInfoService;
import com.crm.manager.service.ib.SysPointFeignService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.base.BaseDropDownDto;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.BaseResultWithPagerDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.ib.point.SysPointDto;
import com.crm.rely.backend.core.dto.system.area.SysAreaDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.system.area.SysAreaAddEntity;
import com.crm.rely.backend.core.entity.system.area.SysAreaSearchEntity;
import com.crm.rely.backend.core.entity.system.area.SysAreaUpdateEntity;
import com.crm.rely.backend.core.pojo.table.SysAreaTable;
import com.crm.rely.backend.core.pojo.view.SysAreaView;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.util.FormatPage;
import org.apache.commons.compress.utils.Lists;
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.List;

@Service
public class  SysAreaServiceImpl implements SysAreaService {

    @Autowired
    private SysAreaMapper sysAreaMapper;

    @Autowired
    private SysPointFeignService sysPointFeignService;

    @Autowired
    private UserInfoService userInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysAreaAddEntity entity) throws Exception {
        if (!checkAreaNameUnique(entity.getAreaName())) {
            throw new ServiceException("Duplicate area name");
        }
        rebateTemplateExists(entity.getPointId());

        SysAreaTable table = new SysAreaTable();
        BeanUtils.copyProperties(entity, table);
        sysAreaMapper.save(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(SysAreaUpdateEntity entity) throws Exception {
        SysAreaTable table = findInfoById(entity.getId());
        if (!table.getAreaName().equals(entity.getAreaName()) && !checkAreaNameUnique(entity.getAreaName())) {
            throw new ServiceException("Duplicate area name");
        }
        rebateTemplateExists(entity.getPointId());
        BeanUtils.copyProperties(entity, table);
        sysAreaMapper.update(table);
    }

    @Override
    public BaseResultWithPagerDto<List<SysAreaDto>> getList(SysAreaSearchEntity entity) throws Exception {

        Integer count = sysAreaMapper.countList(entity);
        PageDto pageDto = FormatPage.format(entity.getPage(), count);
        if (count == null || count == 0) {
            return new BaseResultWithPagerDto(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto);
        }

        List<SysAreaDto> dtos = Lists.newArrayList();
        List<SysAreaView> views = sysAreaMapper.pageList(entity);
        for (SysAreaView view : views) {
            dtos.add(convertViewToDto(view));
        }

        return new BaseResultWithPagerDto(Constants.SUCCESS_CODE, Constants.SEARCH_SUCCESS, pageDto, dtos);
    }

    @Override
    public SysAreaDto getById(Long id) throws Exception {
        SysAreaView view = findViewById(id);
        return convertViewToDto(view);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) throws Exception {
        if (infoInUse(id)) {
            throw new ServiceException("Area info in use");
        }
        sysAreaMapper.removeById(id);
    }

    @Override
    public List<BaseDropDownDto> getDd() throws Exception {
        List<SysAreaTable> tables = sysAreaMapper.findAll();
        List<BaseDropDownDto> dtos = Lists.newArrayList();
        for (SysAreaTable table : tables) {
            BaseDropDownDto dto = new BaseDropDownDto();
            dto.setId(table.getId());
            dto.setName(table.getAreaName());
            dtos.add(dto);

        }
        return dtos;
    }


    boolean checkAreaNameUnique(String areaName) throws Exception {
        Integer count = sysAreaMapper.countByAreaName(areaName);
        if (count == null || count <= 0) {
            return true;
        } else {
            return false;
        }
    }

    SysAreaTable findInfoById(Long id) throws Exception {
        SysAreaTable table = sysAreaMapper.findInfoById(id);
        if (table == null) {
            throw new ServiceException("Info not found");
        }
        return table;
    }

    SysAreaView findViewById(Long id) throws Exception {
        SysAreaView view = sysAreaMapper.findViewById(id);
        if (view == null) {
            throw new ServiceException("Info not found");
        }
        return view;
    }

    private SysAreaDto convertViewToDto(SysAreaView view) throws Exception {
        SysAreaDto dto = new SysAreaDto();
        BeanUtils.copyProperties(view, dto);
        return dto;
    }

    private void rebateTemplateExists(Long pointId) throws Exception {
        SingleLongEntity entity = new SingleLongEntity();
        entity.setId(pointId);
        BaseResultDto<SysPointDto> resultDto = sysPointFeignService.getOne(entity);
        if (resultDto.getCode() != Constants.SUCCESS_CODE) {
            throw new ServiceException("Rebate template not found");
        }
    }

    private boolean infoInUse(Long areaId) throws Exception {
        return userInfoService.existsByAreaId(areaId);
    }

}
