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

//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
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.datascope.DataScope;
import com.casic.missiles.model.log.LogObjectHolder;
import com.casic.missiles.model.response.ErrorResponseData;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.constant.DeviceConst;
import com.casic.missiles.modular.system.dao.BusConcentratorMapper;
import com.casic.missiles.modular.system.model.BusConcentrator;
import com.casic.missiles.modular.system.model.Device;
import com.casic.missiles.modular.system.service.IBusConcentratorService;
import com.casic.missiles.modular.system.util.Utility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
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.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 集中器信息表 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2019-06-03
 */
@Service
public class BusConcentratorServiceImpl extends ServiceImpl<BusConcentratorMapper, BusConcentrator> implements IBusConcentratorService {
    private static final Logger logger = LoggerFactory.getLogger(BusConcentratorServiceImpl.class);
    @Resource
    private Validator validator;
    @Resource
    private AbstractPermissionContext commonPermissionService;

    @Override
    public boolean updateById(BusConcentrator entity) {
        BusConcentrator old = this.getById(entity.getId());
        LogObjectHolder.me().set(old);
        if (!old.getLat().equals(entity.getLat()) || !old.getLng().equals(entity.getLng())) {
            loadPostion(entity);
        }
        return super.updateById(entity);
    }

    @Override
    public List<BusConcentrator> selectConcentratorPage(Page<BusConcentrator> page, DataScope dataScope, String keywords, String status) {
        return this.baseMapper.selectConcentratorPage(page, dataScope, keywords, status);
    }

    @Override
    public ResponseData addDeviceBatch(List<BusConcentrator> results) {
        BeanPropertyBindingResult beanPropertyBindingResult = new BeanPropertyBindingResult(Device.class, "集中器导入校验");
        List<String> list = new ArrayList<>();
        if (!CollectionUtil.isEmpty(results)) {
            final Integer[] index = {0};
            results.forEach(busConcentrator -> {
                validator.validate(busConcentrator, beanPropertyBindingResult);
                index[0]++;
                if (beanPropertyBindingResult.hasErrors()) {
                    List<FieldError> errors = beanPropertyBindingResult.getFieldErrors();
                    errors.forEach(error -> {
                                list.add(" 第" + index[0] + "行，".concat(error.getDefaultMessage()));
                                return;
                            }
                    );
                    return;
                }
                if (StrUtil.isNotEmpty(busConcentrator.getDeptName())) {
                    Long deptid = this.baseMapper.getDeptById(busConcentrator.getDeptName());
                    if (ObjectUtil.isEmpty(deptid)) {
                        list.add(" 第" + index[0] + "行，权属单位不存在");
                        return;
                    }else {
                        busConcentrator.setDeptid(deptid);
                    }
                }

                if (StrUtil.isNotEmpty(busConcentrator.getSetupdateFormat())) {
                    try {
                        busConcentrator.setSetupdate(new SimpleDateFormat("yyyy-MM-dd").parse(busConcentrator.getSetupdateFormat()));
                    } catch (Exception e) {
                        list.add(" 第" + index[0] + "行，时间格式不正确");
                        return;
                    }
                } else {
                    busConcentrator.setSetupdate(new Date());
                }

                //地图坐标转换
                loadPostion(busConcentrator);
                busConcentrator.setValid(DeviceConst.YES);
                busConcentrator.setLasttime(new Date());
                busConcentrator.setTs(new Date());
                busConcentrator.setStatus(DeviceConst.NO);
            });
            if (CollectionUtil.isNotEmpty(list)) {
                return ResponseData.error(list.get(0));
            }
            try {
//                results.stream().
                this.saveBatch(results);
            } catch (DataAccessException ex) {
                log.error("主题，集中器批量导入模板保存数据库出现异常，异常信息为{}", ex);
                list.add("保存出现异常，集中器编号重复");
                return catchMybatisPlusException(ex, "导入集中器失败");
            }
        }
        if (CollectionUtil.isNotEmpty(list)) {
            //获取第校验报错信息
            return new ErrorResponseData(list.get(0));
        }
        return ResponseData.success();
    }

    private ResponseData catchMybatisPlusException(Exception e, String errorMsg) {
        if (e instanceof DataAccessException) {
            DataAccessException mybatisPlusException = (DataAccessException) e;
            String message = mybatisPlusException.getRootCause().getMessage();
            if (message.contains("Duplicate entry '")) {
                return new ErrorResponseData("集中器编号重复:" + message.replaceAll("Duplicate entry '", "").replaceAll("' for key 'CONCENCODE'", ""));
            }
        }
        logger.error(errorMsg, e);
        return new ErrorResponseData(errorMsg);
    }

    @Transactional
    @Override
    public void deleteByIds(List<Long> ids) {
        if (CollectionUtil.isNotEmpty(ids)) {
            ids.forEach(id -> {
                this.baseMapper.deleteById(id);
            });

        }
    }

    @Override
    public boolean save(BusConcentrator entity) {
        if (StrUtil.isNotEmpty(entity.getLat()) && StrUtil.isNotEmpty(entity.getLng())) {
            loadPostion(entity);
        }

        entity.setStatus(DeviceConst.NO);
        entity.setValid(DeviceConst.YES);
        entity.setTs(new Date());
        return super.save(entity);
    }

    void loadPostion(BusConcentrator entity) {
        if (StrUtil.isNotEmpty(entity.getLat()) && StrUtil.isNotEmpty(entity.getLng())) {
            Map<String, Object> baiduCoordinate = Utility.convertBaiduAPI(entity.getLng(), entity.getLat());
            Map<String, Object> gaodeCoordinate = Utility.convertGaodeAPI(entity.getLng(), entity.getLat());
            if (ObjectUtil.isEmpty(baiduCoordinate) || ObjectUtil.isEmpty(gaodeCoordinate)) {
                logger.error("{}坐标转换失败!", entity.getConcencode());
                return;
            }
            entity.setLatBaidu(baiduCoordinate.get("x").toString());
            entity.setLngBaidu(baiduCoordinate.get("y").toString());
            entity.setLatGaode(gaodeCoordinate.get("x").toString());
            entity.setLngGaode(gaodeCoordinate.get("y").toString());
        }
    }
}
