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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.casic.missiles.core.application.context.AbstractPermissionContext;
import com.casic.missiles.core.application.service.AbstractDictService;
import com.casic.missiles.core.datascope.DataScope;
import com.casic.missiles.core.util.SpringContextHolder;
import com.casic.missiles.modular.config.SluicewellProperties;
import com.casic.missiles.modular.system.constant.BusWellConst;
import com.casic.missiles.modular.system.dao.BusWellInfoMapper;
import com.casic.missiles.modular.system.dto.BatchExportDataDto;
import com.casic.missiles.modular.system.dto.BusWellInfoDto;
import com.casic.missiles.modular.system.model.BusWellInfo;
import com.casic.missiles.modular.system.model.Dict;
import com.casic.missiles.modular.system.service.IBusWellInfoService;
import com.casic.missiles.modular.system.service.IBusWellInfoSupportService;
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 javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

    @Resource
    private AbstractPermissionContext service;
    @Resource
    private AbstractDictService dictService;
    @Autowired
    private Validator validator;

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

    @Override
    @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(dictService.getDictNameByCode(BusWellConst.SLUICEWELL_TYPE, well.getWellType()));
            well.setDeptName(service.getDeptService().getDeptName(well.getDeptid()));
            well.setBfztName(dictService.getDictNameByCode(BusWellConst.BFZT_TEMP, well.getBfzt()));
//            well.setDeviceCount(this.getDeviceCountData(well.getId()));

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






    @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);
    }

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

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

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


    @Override
    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<String> gpsCoordinates = new ArrayList<>();

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

            final Integer[] index = {0};
            for (BusWellInfo well : results) {
                index[0]++;
                validator.validate(well, beanPropertyBindingResult);
                if (beanPropertyBindingResult.hasErrors()) {
                    List<FieldError> errors = beanPropertyBindingResult.getFieldErrors();

                    //导入表格总共有10个字段，如果同一行有多于10个错误，则表示此行为空
                    if (errors.size() >= 10) {
                        break;
                    }

                    errors.forEach(error -> {
                                list.add("第" + index[0] + "行，".concat(error.getDefaultMessage()));
                            }
                    );
                    break;
                }

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

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

                String coordinateX = well.getCoordinateX().length() > 10 ? well.getCoordinateX().substring(0, 10) : well.getCoordinateX();
                String coordinateY = well.getCoordinateY().length() > 9 ? well.getCoordinateY().substring(0, 9) : well.getCoordinateY();
                well.setCoordinateX(coordinateX);
                well.setCoordinateY(coordinateY);

                gpsCoordinates.add(coordinateX + "," + coordinateY);

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

            if (CollectionUtil.isNotEmpty(list)) {
                return list;
            }

            SluicewellProperties sluicewellProperties = SpringContextHolder.getBean(SluicewellProperties.class);
            String coordinate = sluicewellProperties.getCoordinate().toLowerCase();
            List<String> convertCoordinates = null;

            if ("baidu".equals(coordinate)) {
                convertCoordinates = Utility.convertBaiduAPI(gpsCoordinates);
            } else if ("gaode".equals(coordinate)) {
                convertCoordinates = Utility.convertGaodeAPI(gpsCoordinates);
            }

            if (CollectionUtil.isNotEmpty(convertCoordinates) &&
                    results.size() == convertCoordinates.size()) {

                if ("baidu".equals(coordinate)) {
                    for (int i = 0; i < convertCoordinates.size(); i++) {
                        String[] xy = convertCoordinates.get(i).split(",");
                        results.get(i).setLngBaidu(xy[0]);
                        results.get(i).setLatBaidu(xy[1]);
                    }
                } else if ("gaode".equals(coordinate)) {
                    for (int i = 0; i < convertCoordinates.size(); i++) {
                        String[] xy = convertCoordinates.get(i).split(",");
                        results.get(i).setLngGaode(xy[0]);
                        results.get(i).setLatGaode(xy[1]);
                    }
                }
            }

            this.saveBatch(results);

        } else {
            list.add("导入数据不能为空");
        }
        return list;
    }

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

    @Override
    public BusWellInfo getById(Long id) {
        return this.baseMapper.selectById(id);
    }


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

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

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


    @Override
    public Boolean isExistWellCode(String wellCode) {
        return this.baseMapper.isExistWellCode(wellCode);
    }

    @Override
    public Boolean changeCoordinates(int startNumber) {
        //
        List<BusWellInfo> wellList = this.baseMapper.getWellListAll();
        try {
            for (int i = 0; i < wellList.size(); i++) {
                if (i < startNumber) {
                    continue;
                }
                BusWellInfo wellInfo = wellList.get(i);
                // 获取84坐标
                String coordinateX = wellInfo.getCoordinateX();
                String coordinateY = wellInfo.getCoordinateY();
                // 转换高德百度坐标
                Map<String, Object> baiduCoordinate = Utility.convertBaiduAPI(coordinateX, coordinateY);
                Map<String, Object> gaodeCoordinate = Utility.convertGaodeAPI(coordinateX, coordinateY);
                // 设置百度坐标
                wellInfo.setLngBaidu(baiduCoordinate.get("x").toString());
                wellInfo.setLatBaidu(baiduCoordinate.get("y").toString());
                // 设置高德坐标
                wellInfo.setLngGaode(gaodeCoordinate.get("x").toString());
                wellInfo.setLatGaode(gaodeCoordinate.get("y").toString());
                this.baseMapper.updateById(wellInfo);
                System.out.println(i + " : " + wellInfo.getWellCode() + "|" + wellInfo.getCoordinateX() + "," + wellInfo.getCoordinateY() + "|" + wellInfo.getLngBaidu() + "," + wellInfo.getLatBaidu() + "|" + wellInfo.getLngGaode() + "," + wellInfo.getLatGaode());
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
