package com.casic.missiles.modular.system.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.casic.missiles.modular.system.constant.BusWellConst;
import com.casic.missiles.modular.system.controller.BusWellInfoController;
import com.casic.missiles.modular.system.dto.BatchExportDataDto;
import com.casic.missiles.modular.system.dto.BfztCountDataDto;
import com.casic.missiles.modular.system.dto.DeviceData;
import com.casic.missiles.modular.system.model.BusWellInfo;
import com.casic.missiles.core.common.service.ICommonPermissionService;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.core.util.ToolUtil;
import com.casic.missiles.modular.system.dto.WatchDataDto;
import com.casic.missiles.modular.system.dao.BusWellInfoMapper;
import com.casic.missiles.modular.system.model.Dict;
import com.casic.missiles.modular.system.model.User;
import com.casic.missiles.modular.system.service.IBusWellInfoService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.casic.missiles.modular.system.util.Utility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 闸井信息表 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2019-05-13
 */
@Service
public class BusWellInfoServiceImpl extends ServiceImpl<BusWellInfoMapper, BusWellInfo> implements IBusWellInfoService {
    private static final Logger logger = LoggerFactory.getLogger(BusWellInfoServiceImpl.class);


    @Autowired
    private ICommonPermissionService service;

    @Autowired
    private Validator validator;

    @Override
    public BusWellInfo selectById(Serializable id) {
        BusWellInfo wellInfo = super.selectById(id);
        if (null != wellInfo) {
            wellInfo.setDeptName(service.getDeptName(wellInfo.getDeptid()));
            wellInfo.setResponsibleDept(wellInfo.getStaff());
            wellInfo.setResponsibleDeptName(service.getDeptName(wellInfo.getStaff()));
            wellInfo.setBfztName(service.getDictNameByCode("bfZt", wellInfo.getBfzt()));
            wellInfo.setWellTypeName(service.getDictNameByCode(BusWellConst.SLUICEWELL_TYPE, wellInfo.getWellType()));
            wellInfo.setQu(this.getAreaPid(wellInfo.getArea()));
        }
        return wellInfo;
    }

    @Transactional
    public List<BusWellInfo> selectDataScopePage(DataScope dataScope, Page<BusWellInfo> page,String keywords, String wellType, String deptid, String bfzt) {
        List<BusWellInfo> list =this.baseMapper.selectDataScopePage(dataScope, page, keywords, wellType, deptid, bfzt);
        list.forEach(well -> {
            well.setWellTypeName(service.getDictNameByCode(BusWellConst.SLUICEWELL_TYPE, well.getWellType()));
            well.setDeptName(service.getDeptName(well.getDeptid()));
            well.setBfztName(service.getDictNameByCode(BusWellConst.BFZT_TEMP, well.getBfzt()));
//            well.setDeviceCount(this.getDeviceCountData(well.getId()));

            well.setQu(this.getAreaPid(well.getArea()));
            well.setResponsibleDeptName(service.getDeptName(well.getResponsibleDept()));
        });
        return list;
    }

    @Transactional
    public List<BusWellInfo> selectDataScopePageForPolice(DataScope dataScope, Page<BusWellInfo> page, String keywords, String position, String owner, String wellType, String deptid, String notes) {

        List<BusWellInfo> list =this.baseMapper.selectDataScopePageForPolice(dataScope, page, keywords, position, owner, wellType, deptid, notes);
        list.forEach(well -> {
            well.setWellTypeName(service.getDictNameByCode(BusWellConst.SLUICEWELL_TYPE, well.getWellType()));
            well.setDeptName(service.getDeptName(well.getDeptid()));
            well.setBfztName(service.getDictNameByCode(BusWellConst.BFZT_TEMP, well.getBfzt()));
//            well.setDeviceCount(this.getDeviceCountData(well.getId()));

            well.setQu(this.getAreaPid(well.getArea()));
            well.setResponsibleDeptName(service.getDeptName(well.getResponsibleDept()));
        });
        return list;
    }

    @Transactional
    public void updateBatchBfcf(String keywords, String position, String owner, String wellType, String deptid, String bfzt,List<Long> deptIds, String notes) {

        this.baseMapper.updateBatchBfcf(keywords, position, owner, wellType, deptid, bfzt, deptIds, notes);
    }

    public List<WatchDataDto> getWatchDatas(Long id){
        List<WatchDataDto> watchDataDtos =this.baseMapper.watchData(id);

        for(WatchDataDto watchDataDto : watchDataDtos){
            watchDataDto.setOnlineStateName(service.getDictNameByCode("onlineStatus",watchDataDto.getOnlineState()));

            DeviceData deviceData = null;
            if("井盖状态".equals(watchDataDto.getWatchType())){
                deviceData = this.baseMapper.wellcoverData(watchDataDto.getDevcode());
            }else if("井内水位".equals(watchDataDto.getWatchType())){
                deviceData = this.baseMapper.liquidData(watchDataDto.getDevcode());
            }else{

            }

            if(deviceData != null){
                watchDataDto.setData(deviceData.getData());

                DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                watchDataDto.setLogtime(sdf.format(deviceData.getLogtime()));
            }
        }
        return watchDataDtos;
    }

    public BfztCountDataDto getBfztCountData(DataScope dataScope, List<Long> deptIds){
        return this.baseMapper.bfztCountData(dataScope, deptIds);
    }

    @Override
    public List<BatchExportDataDto> selectDataScope(DataScope dataScope, Page<BatchExportDataDto> page, String deviceType, String deptid, String keywords) {
        return this.baseMapper.selectDataScope(dataScope, page, deviceType, deptid,keywords);
    }

    public Integer getDeviceCountData(Long id) {
        return this.baseMapper.deviceCountData(id);
    }

    public String getDeptNameData(String deptid) {
        return this.baseMapper.deptNameData(deptid);
    }


    public List<Long> deleteBatchByIds(List<Long> ids){

        List<Long> lists = new ArrayList<>();
        for(Long id : ids) {
            Integer count = this.baseMapper.deviceCountData(id);
            if(count > 0){
                //井中有有效设备，不允许删除
                lists.add(id);
            }else{
                this.baseMapper.deleteById(id);
            }
        }

        return lists;
    }

    @Transactional
    @Override
    public List<String> addWellBatch(List<BusWellInfo> results) {

        BeanPropertyBindingResult beanPropertyBindingResult = new BeanPropertyBindingResult(BusWellInfo.class,"闸井导入校验");

        List<String> list = new ArrayList<>();
        List<BusWellInfo> goodList = new ArrayList<>();
        if (ToolUtil.isNotEmpty(results)) {
            List<Dict> dicts = service.findInDictByCode(BusWellConst.SLUICEWELL_TYPE);//闸井类型
            Map<String,String> sluicewellTypeMap = new HashMap<>();
            dicts.forEach(dict->{
                sluicewellTypeMap.put(dict.getName(),dict.getCode());
            });

            final Integer[] index = {0};

            results.forEach(well -> {
                index[0]++;
                validator.validate(well, beanPropertyBindingResult);
                if (beanPropertyBindingResult.hasErrors()) {
                    List<FieldError> errors = beanPropertyBindingResult.getFieldErrors();
                    errors.forEach(error -> {
                                list.add("第" + index[0] + "行，".concat(error.getDefaultMessage()));
                                return;
                            }
                    );
                    return;
                }

                //其他相关性校验
                String areaId = this.baseMapper.getAreaId(well.getQu(),well.getArea());
                if(ToolUtil.isNotEmpty(areaId)){
                    well.setArea(areaId);
                }else {
                    list.add("第" + index[0] + "行，区与街道名不对应！");
                    return;
                }

                Utility.convertCoordinate(well);

                if(sluicewellTypeMap.containsKey(well.getWellType())){
                    well.setWellType(sluicewellTypeMap.get(well.getWellType()));
                }else{
                    list.add("第" + index[0] + "行，闸井类型不存在！");
                    return;
                }

                List<User> deptTopRoleUsers = service.getRoleUsersByTips(well.getResponsibleDept(),"leader",true);
                if(ToolUtil.isEmpty(deptTopRoleUsers)){
//                    list.add("第" + index[0] + "行，该闸井维护单位没有设置责任人！");
//                    return;
                }else {
                    well.setStaff(deptTopRoleUsers.get(0).getId().toString());
                }

                logger.info("第" + index[0] + "行校验完毕！");

                goodList.add(well);
                if(index[0] % 500 == 0){
                    this.insertBatch(goodList);
                    goodList.clear();
                }
            });
            this.insertBatch(goodList);

            if (ToolUtil.isNotEmpty(list)) {
                return list;
            }
            //保存设备信息
            //this.insertBatch(results);
        } else {
            list.add("导入数据不能为空");
        }
        return list;
    }

    @Override
    public List<BusWellInfo> getWellList(DataScope dataScope, String keywords, String wellType, String deptid) {
        return this.baseMapper.getWellList(dataScope, keywords, wellType, deptid);
    }

    @Override
    public List<BusWellInfo> getAllWellList() {
        return this.baseMapper.getAllWellList();
    }

    @Override
    public List<BusWellInfo> getAlarmWellList(DataScope dataScope, String keywords, String wellType, String deptid) {
        List<BusWellInfo> busWellInfos= this.baseMapper.getAlarmWellList(dataScope, keywords, wellType, deptid);

    return  busWellInfos;
    }

    @Override
    public List<BusWellInfo> getNotAlarmWellList(DataScope dataScope, String keywords, String wellType, String deptid) {
        return this.baseMapper.getNotAlarmWellList(dataScope, keywords, wellType, deptid);
    }

    public String getAreaPid(String id){
        return this.baseMapper.getAreaPId(id);
    }

}
