/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.xrtymis.custom.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.api.CodeClient;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.pojo.Syschildcode;
import com.tofly.xrtymis.config.FilePathBean;
import com.tofly.xrtymis.custom.commons.CommonConstants;
import com.tofly.xrtymis.custom.commons.Constate;
import com.tofly.xrtymis.custom.dto.TfYwpnWaterRepDTO;
import com.tofly.xrtymis.custom.service.QfkhjbxxService;
import com.tofly.xrtymis.custom.service.TfYwpnGatherrecordService;
import com.tofly.xrtymis.custom.service.TfYwpnWaterRepService;
import com.tofly.xrtymis.custom.service.TfYwpnWatermeterService;
import com.tofly.xrtymis.custom.utils.SaveFile;
import com.tofly.xrtymis.custom.vo.TfYwpnWaterRepVO;
import com.tofly.xrtymis.custom.vo.TfYwpnWatermeterVO;
import com.tofly.xrtymis.entity.Qfkhjbxx;
import com.tofly.xrtymis.entity.TfYwpnGatherrecord;
import com.tofly.xrtymis.entity.TfYwpnWaterRep;
import com.tofly.xrtymis.entity.TfYwpnWatermeter;
import com.tofly.xrtymis.mapper.TfYwpnWatermeterMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 水表信息采集数据表：TF_YWPN_WATERMETER_W
 *
 * @author fcl
 * @date Fri Apr 16 00:00:00 CST 2021
 */
@Service("tfYwpnatermeterService")
@Slf4j
public class TfYwpnWatermeterServiceImpl extends ServiceImpl<TfYwpnWatermeterMapper, TfYwpnWatermeter> implements TfYwpnWatermeterService {

    @Autowired
    SaveFile saveFile;
    @Autowired
    private FilePathBean filePathBean;
    @Autowired
    private TfYwpnGatherrecordService gatherrecordService;
    @Autowired
    private CodeClient codeClient;
    @Autowired
    private TfYwpnWaterRepService repService;
    @Autowired
    private QfkhjbxxService qfkhjbxxService;

    @Override
    public ResultRespone saveInformation(TfYwpnWaterRep rep) {
        if (repService.save(rep)) {
            String sid = gatherrecordService.getGlobalSid("610", rep.getId());
            rep.setSid(sid);
            repService.update(Wrappers.<TfYwpnWaterRep>lambdaUpdate().eq(TfYwpnWaterRep::getId,rep.getId())
                    .set(TfYwpnWaterRep::getSid,sid));

            Integer count = gatherrecordService.getBaseMapper().selectCount(Wrappers.<TfYwpnGatherrecord>lambdaQuery()
                    .eq(TfYwpnGatherrecord::getTableName, CommonConstants.WATERREP_RECORD_TABLE_NAME)
                    .eq(TfYwpnGatherrecord::getGatherId, rep.getId()));
            if (count<=0) {
                TfYwpnGatherrecord gatherrecord = new TfYwpnGatherrecord();
                gatherrecord.setGatherType("610");
                gatherrecord.setTableName(CommonConstants.WATERREP_RECORD_TABLE_NAME);
                gatherrecord.setGatherId(rep.getId());
                gatherrecord.setGatherTime(rep.getCreateTime());
                gatherrecord.setAuditUser(rep.getCreateUser());
                gatherrecord.setState(Constate.NO);
                gatherrecord.setIsread(Constate.NO);
                gatherrecord.setIspublish(Constate.YES);
                gatherrecordService.save(gatherrecord);
            }
            return ResultRespone.success(rep);
        }
        return ResultRespone.failed();
    }

    @Override
    public String getRFID(String sid, String sbcjName,String yhbh) {
        StringBuilder builder = new StringBuilder("C");
        if (StringUtils.isBlank(sid) || StringUtils.isBlank(sbcjName)) {
            return builder.toString();
        }

        Syschildcode syschildcode = new Syschildcode();
        syschildcode.setCname(sbcjName);
        Object result = codeClient.getChild(syschildcode).getResult();
        if (ObjectUtils.isEmpty(result)) {
            return builder.append("水表厂商获取失败，请联系管理员").toString();
        }

        String str = JSON.toJSONString(result);
        String json = str.substring(1, str.length() - 1);
        Syschildcode code = JSON.parseObject(json, Syschildcode.class);
//        if (StringUtils.isBlank(yhbh)) {
//            return builder.append(code.getCcontert()).append("O").append(sid).toString();
//        } else {
//        return builder.append(code.getCcontert()).append("O").append(sid).append(yhbh).toString();
//        }
        return builder.append(code.getCcontert()).append(sid).toString();
    }

    @Override
    public ResultRespone calibration(TfYwpnWatermeter tfYwpnWatermeter) {
        log.info("水表标注请求参数{}",JSON.toJSONString(tfYwpnWatermeter));
        if (tfYwpnWatermeter != null && tfYwpnWatermeter.getSid() != null){
            // 通过水表编号sid查询是否存在正在使用的水表
            List<TfYwpnWatermeter> tfYwpnWatermeters = this.getBaseMapper().selectList(Wrappers.<TfYwpnWatermeter>lambdaQuery()
                    .eq(TfYwpnWatermeter::getSid, tfYwpnWatermeter.getSid())
                    .eq(TfYwpnWatermeter::getStatus,Constate.YES));

            if (tfYwpnWatermeters != null && tfYwpnWatermeters.size() == 1) {
                log.info("水表标注更新数据{}",JSON.toJSONString(tfYwpnWatermeters));
                for (TfYwpnWatermeter meter : tfYwpnWatermeters) {
                    if (StringUtils.isBlank(meter.getRfid()) || meter.getRfid().equals(tfYwpnWatermeter.getRfid())) {
                        tfYwpnWatermeter.setId(meter.getId());
                        return ResultRespone.success(this.updateById(tfYwpnWatermeter));
                    } else {
                        throw new ToflyDeniedException("水表编号与RFID标定错误");
                    }
                }
            } else if (ObjectUtils.isEmpty(tfYwpnWatermeters)) {
                log.info("水表标注新增数据{}",JSON.toJSONString(tfYwpnWatermeters));
                Integer count = this.getBaseMapper().selectCount(Wrappers.<TfYwpnWatermeter>lambdaQuery()
                        .eq(TfYwpnWatermeter::getRfid, tfYwpnWatermeter.getRfid())
                        .eq(TfYwpnWatermeter::getStatus,Constate.YES));
                if (count <= 0) {
                    tfYwpnWatermeter.setStatus(Constate.YES);
                    return ResultRespone.success(this.save(tfYwpnWatermeter));
                } else {
                    throw new ToflyDeniedException("RFID已标定水表，请重试");
                }
            }
        }
        return ResultRespone.failed("水表编号异常，请联系管理员! 有多只水表编号相同。");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultRespone updateWaterMater(List<MultipartFile> fileList, TfYwpnWaterRepDTO repDTO) {
        boolean ispublished = gatherrecordService.ispublished(CommonConstants.WATERREP_RECORD_TABLE_NAME, repDTO.getId());
        TfYwpnWaterRep waterRep = null;
        if (!ispublished) {
            // 完善水表代表点未关联水表校验
            List<TfYwpnWatermeter> meterList = repDTO.getWaterMeterList();
            if (meterList != null && meterList.size() > 0) {
                update(Wrappers.<TfYwpnWatermeter>lambdaUpdate().eq(TfYwpnWatermeter::getRepId, repDTO.getId())
                        .eq(TfYwpnWatermeter::getStatus, Constate.YES).set(TfYwpnWatermeter::getRepId, 0));

                for (TfYwpnWatermeter ywpnatermeter : meterList) {
                    Integer count =ywpnatermeter.getSid() != null ? this.getBaseMapper().selectCount(Wrappers.<TfYwpnWatermeter>lambdaQuery()
                            .eq(TfYwpnWatermeter::getSid, ywpnatermeter.getSid())) : 0;
                    ywpnatermeter = RepDTO2WaterMeter(ywpnatermeter, repDTO);
                    if (count >= 1) {
                        this.update(ywpnatermeter, Wrappers.<TfYwpnWatermeter>lambdaUpdate()
                                .eq(TfYwpnWatermeter::getSid, ywpnatermeter.getSid()));
                    } else {
                        this.save(ywpnatermeter);
                    }
//                    ywpnatermeter.setRepId(waterRep.getId());
//                    ywpnatermeter.setStatus("1");
//                    this.saveOrUpdate(ywpnatermeter);
                }
            } else {
                return ResultRespone.failed("请至少添加一个水表信息再保存水表采集代表点修改。");
            }

            waterRep = new TfYwpnWaterRep();
            BeanUtils.copyProperties(repDTO,waterRep);

            StringBuilder filesb = saveFiles(fileList,repService.getById(repDTO.getId()).getFileIds(),waterRep.getFileIds());
            if(StringUtils.isEmpty(filesb)){
                repService.update(new UpdateWrapper<TfYwpnWaterRep>().lambda().set(TfYwpnWaterRep::getFileIds,"").eq(TfYwpnWaterRep::getId,repDTO.getId()));
            }
            waterRep.setFileIds(filesb.toString());
            return ResultRespone.success(repService.updateById(waterRep));
        } else {
            return ResultRespone.failed("已提交的水表采集代表点不允许修改");
        }
    }

    /**
     * 存储文件
     * @param fileList
     * @param fileIdsdb
     * @param fileIds
     * @return
     */
    private StringBuilder saveFiles(List<MultipartFile> fileList, String fileIdsdb, String fileIds) {
        StringBuilder fileIdList = null;
        if (CollectionUtils.isNotEmpty(fileList)) {
            fileIdList = saveFile.saveFileList(fileList, filePathBean.getSbxxcj(), CommonConstants.WATERREP_RECORD_TABLE_NAME);
        }

        if (StringUtils.isNotEmpty(fileIdsdb) && !fileIdsdb.equals(fileIds)) {
            List<Long> removeFileId = new ArrayList<>();
            if (StringUtils.isEmpty(fileIds)) {
                removeFileId = Arrays.stream(fileIdsdb.split(Constate.CSV)).map(s -> Long.parseLong(s.trim()))
                        .collect(Collectors.toList());
            } else {
                removeFileId = Arrays.stream(fileIdsdb.split(Constate.CSV)).filter(st -> !fileIds.contains(st)).map(st -> Long.parseLong(st.trim())).collect(Collectors.toList());
            }
            // 删除对应文件数据
            if (!removeFileId.isEmpty()) {
                // 删除远程文件
                saveFile.removeFileById(org.apache.commons.lang.StringUtils.join(removeFileId,","));
            }
        }
        StringBuilder files = new StringBuilder();
        if (StringUtils.isEmpty(fileIds) || StringUtils.isEmpty(fileIdList)) {
            if(StringUtils.isNotEmpty(fileIds)){
                files.append(fileIds);
            }else if(StringUtils.isNotEmpty(fileIdList)){
                files.append(fileIdList);
            }
        } else {
            files.append(fileIds).append(Constate.CSV).append(fileIdList);
        }
        return files;
    }


    private TfYwpnWatermeter RepDTO2WaterMeter(TfYwpnWatermeter ywpnatermeter, TfYwpnWaterRepDTO repDTO) {
        ywpnatermeter.setId(null);
        ywpnatermeter.setStatus(Constate.YES);
        ywpnatermeter.setRepId(repDTO.getId());
        if (ywpnatermeter.getX() == null) {
            ywpnatermeter.setX(repDTO.getX());
        }
        if (ywpnatermeter.getY() == null) {
            ywpnatermeter.setY(repDTO.getY());
        }
        if (ywpnatermeter.getAddress() == null ) {
            ywpnatermeter.setAddress(repDTO.getAddress());
        }
        if (ywpnatermeter.getGroundz() == null) {
            ywpnatermeter.setGroundz(repDTO.getGroundz());
        }
        if (ywpnatermeter.getOwnerunit() == null) {
            ywpnatermeter.setOwnerunit(repDTO.getOwnerunit());
        }
        if (ywpnatermeter.getSurveyunit() == null) {
        ywpnatermeter.setSurveyunit(repDTO.getSurveyunit());
        }
        if (ywpnatermeter.getSurveydate() == null) {
        ywpnatermeter.setSurveydate(repDTO.getSurveydate());
        }
        if (ywpnatermeter.getMaintainedunit() == null) {
        ywpnatermeter.setMaintainedunit(repDTO.getMaintainedunit());
        }
        return ywpnatermeter;
    }

    @Override
    public ResultRespone removeRepById(Long id) {
        boolean ispublished = gatherrecordService.deleteByTableNameAndGatherId(CommonConstants.WATERREP_RECORD_TABLE_NAME,id);
        if (ispublished) {
            update(Wrappers.<TfYwpnWatermeter>lambdaUpdate().eq(TfYwpnWatermeter::getRepId,id)
                    .eq(TfYwpnWatermeter::getStatus,Constate.YES).set(TfYwpnWatermeter::getRepId,0));
            return ResultRespone.success(repService.removeById(id));
        }
        return ResultRespone.failed("已提交数据不允许删除");
    }

    @Override
    public ResultRespone getWaterRepById(Long id) {
        TfYwpnWaterRepVO repVO = null;
        List<TfYwpnWatermeterVO> meterVO = null;
        TfYwpnWaterRep rep = repService.getById(id);
        if (rep != null ) {
            repVO = new TfYwpnWaterRepVO();
            BeanUtils.copyProperties(rep,repVO);

            List<TfYwpnWatermeter> list = this.getBaseMapper().selectList(Wrappers.<TfYwpnWatermeter>lambdaQuery()
                    .eq(TfYwpnWatermeter::getRepId, rep.getId()));
            if (list != null && list.size() > 0 ) {
                meterVO = new ArrayList<>();
                for (TfYwpnWatermeter tfYwpnWatermeter : list) {
                    meterVO.add(watermMter2VO(tfYwpnWatermeter));
                }
                repVO.setWaterMeterList(meterVO);
            }
            return ResultRespone.success(repVO);
        }
        return ResultRespone.failed();
    }

    @Override
    public TfYwpnWatermeterVO watermMter2VO(TfYwpnWatermeter watermeter) {
        TfYwpnWatermeterVO vo = new TfYwpnWatermeterVO();
        BeanUtils.copyProperties(watermeter,vo);
        String yhbh = watermeter.getYhbh();
        if(yhbh != null && yhbh.length() > 0 ){
            Qfkhjbxx qfkhjbxx = qfkhjbxxService.getById(yhbh);
            if (qfkhjbxx != null ) {
                vo.setYhbhName(qfkhjbxx.getYhxm());
                vo.setLxdh(qfkhjbxx.getLxdh());
                if(vo.getInstalldate()==null){
                    vo.setInstalldate(qfkhjbxx.getZhHbrq());
                }
            }
        }

        if(watermeter.getMetertype()!=null) {
            String typeName = getMeterTypeName(watermeter.getMetertype());
            if (StringUtils.isNotBlank(typeName)) {
                vo.setMetertypeName(typeName);
            }
        }

        if(StringUtils.isNotEmpty(watermeter.getAreano())) {
            String areaName = getAreaNameByAreano(watermeter.getAreano());
            if (StringUtils.isNotBlank(areaName)) {
                vo.setAreaName(areaName);
            }
        }

        if(StringUtils.isNotEmpty(watermeter.getManufacturer())) {
            String manufacturerName = getmanufacturerNameByManufacturerCode(watermeter.getManufacturer());
            if (StringUtils.isNotBlank(manufacturerName)) {
                vo.setManufacturerName(manufacturerName);
            }
        }

        vo.setDiameterName("DN" + watermeter.getDiameter());
        return vo;
    }

    private String getmanufacturerNameByManufacturerCode(String manufacturer) {
        Syschildcode syschildcode = new Syschildcode();
        syschildcode.setPcid(2L);
        syschildcode.setCcode(manufacturer);
        Object result = codeClient.getChild(syschildcode).getResult();
        if (ObjectUtils.isNotEmpty(result)) {
            String str = JSON.toJSONString(result);
            String json = str.substring(1, str.length() - 1);
            return JSON.parseObject(json, Syschildcode.class).getCname();
        } else {
            return manufacturer;
        }
    }

    private String getAreaNameByAreano(String areano) {
        return this.getBaseMapper().getAreaNameByAreano(areano);
    }

    @Override
    public ResultRespone getWaterMeterInfoByRFID(String rfid) {
        if (rfid != null && rfid.length() > 0 ) {
            List<TfYwpnWatermeter> selectList = this.getBaseMapper().selectList(Wrappers.<TfYwpnWatermeter>lambdaQuery()
                    .eq(TfYwpnWatermeter::getRfid, rfid)
                    .eq(TfYwpnWatermeter::getStatus, Constate.YES));
            if (selectList != null && selectList.size() > 0) {
                if (selectList.size() == 1) {
                    for (TfYwpnWatermeter ywpnatermeter : selectList) {
                        return ResultRespone.success(watermMter2VO(ywpnatermeter));
                    }
                } else {
                    throw new ToflyDeniedException("水表RFID标定重复，请联系管理员。");
                }
            } else {
                ResultRespone.failed("未能查询到相关水表信息");
            }
        }
        return ResultRespone.failed("请传入正确RFID");
    }

    private String getMeterTypeName(Long metertype) {
        Syschildcode syschildcode = new Syschildcode();
        syschildcode.setPcid(3L);
        syschildcode.setCcode(String.valueOf(metertype));
        Object result = codeClient.getChild(syschildcode).getResult();
        if (ObjectUtils.isNotEmpty(result)) {
            String str = JSON.toJSONString(result);
            String json = str.substring(1, str.length() - 1);
            return JSON.parseObject(json, Syschildcode.class).getCname();
        }
        return "";
    }

}
