package com.yeejoin.amos.boot.module.tzs.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.QRCodeUtil;
import com.yeejoin.amos.boot.module.common.api.dto.AttachmentDto;
import com.yeejoin.amos.boot.module.common.biz.service.impl.SourceFileServiceImpl;
import com.yeejoin.amos.boot.module.tzs.api.dto.AlertCalledDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorWlInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.Elevator;
import com.yeejoin.amos.boot.module.tzs.api.entity.EquipmentCategory;
import com.yeejoin.amos.boot.module.tzs.api.mapper.ElevatorMapper;
import com.yeejoin.amos.boot.module.tzs.api.service.IElevatorService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*  服务实现类
*
* @author tb
* @date 2021-06-01
*/
@Service
public class ElevatorServiceImpl extends BaseService<ElevatorDto, Elevator, ElevatorMapper> implements IElevatorService {


    private final Logger logger = LogManager.getLogger(ElevatorServiceImpl.class);

    @Autowired
    SourceFileServiceImpl sourceFileService;

    @Autowired
    AlertCalledServiceImpl alertCalledServiceImpl;

    @Autowired
    ElevatorMapper elevatorMapper;

    @Autowired
    EquipmentCategoryServiceImpl equipmentCategoryServiceImpl;

    @Autowired
    DataDictionaryServiceImpl iDataDictionaryService;


    /**
     * 保存电梯信息
     *
     * @param elevatorDto
     * @return
     */
    public ElevatorDto saveElevator(ElevatorDto elevatorDto) {
        elevatorDto = createWithModel(elevatorDto);

        // 保存附件
        sourceFileService.saveAttachments(elevatorDto.getSequenceNbr(), elevatorDto.getAttachments());
        return elevatorDto;
    }

    /**
     * 批量删除电梯信息
     *
     * @param seqStr 电梯主键（逗号分割）
     * @return
     */
    public boolean deleteBatchBySeq(String seqStr) {
        if (!ValidationUtil.isEmpty(seqStr)) {
            List<String> seqList = Lists.newArrayList(seqStr.split(","));
            LambdaUpdateWrapper<Elevator> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.in(Elevator::getSequenceNbr, seqList).set(Elevator::getIsDelete, true);
            this.update(lambdaUpdateWrapper);
            return true;
        }
        return false;
    }

    /**
     * 更新电梯信息
     *
     * @param elevatorDto
     * @return
     */
    public ElevatorDto updateElevator(ElevatorDto elevatorDto) {
        elevatorDto = updateWithModel(elevatorDto);

        // 保存附件
        sourceFileService.saveAttachments(elevatorDto.getSequenceNbr(), elevatorDto.getAttachments());
        return elevatorDto;
    }

    /**
     * 根据id查询电梯信息
     *
     * @param sequenceNbr
     * @return
     */
    public ElevatorDto selectBySeq(Long sequenceNbr) {
        ElevatorDto elevatorDto = this.queryBySeq(sequenceNbr);
        Map<String, List<AttachmentDto>> attachment = sourceFileService.getAttachments(sequenceNbr);
        // 获取附件
        elevatorDto.setAttachments(attachment);
        // 判断是否存在qrcode 如果不存在则生成qrcode
        if(attachment.get("qrCode") == null) {
            this.saveElevatorQrCode(sequenceNbr);
            attachment = sourceFileService.getAttachments(sequenceNbr);
            // 获取附件
            elevatorDto.setAttachments(attachment);
        }
        // 封装设备类别 使用场所 和 使用状态
        EquipmentCategory equipmentCategory = equipmentCategoryServiceImpl.getOne(new LambdaQueryWrapper<EquipmentCategory>().eq(EquipmentCategory::getCode,elevatorDto.getCategory()));
        elevatorDto.setCategoryName(equipmentCategory.getName());

        QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", "USE_SITE_CATEGORY").eq("code", elevatorDto.getUseSiteCategory());
        DataDictionary useSiteCategory = iDataDictionaryService.getOne(queryWrapper);
        elevatorDto.setUseSiteCategoryName(useSiteCategory.getName());

        if(elevatorDto.getUseStatus() == 1) {
            elevatorDto.setUseStatusStr("在用");
        } else {
            elevatorDto.setUseStatusStr("停用");
        }
        return elevatorDto;
    }

    @Override
    public Elevator selectByAlertId(Long alertId) {
        AlertCalledDto alertCalledDto = alertCalledServiceImpl.queryBySeq(alertId);
        if (ValidationUtil.isEmpty(alertCalledDto)
                || ValidationUtil.isEmpty(alertCalledDto.getDeviceId()))
            throw new BadRequest("警情不存在或者设备编码不存在");
        // 设备类型 和 编码 确定设备的使用单位或者维保单位
        String equipmentClassificationCode = alertCalledDto.getEquipmentClassificationCode();
        Long deviceId = alertCalledDto.getEquipmentId();
        // 目前只有电梯类型
        LambdaQueryWrapper<Elevator> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Elevator::getSequenceNbr, deviceId);
        Elevator elevator = this.getOne(queryWrapper);
        if (ValidationUtil.isEmpty(elevator))
            throw new BadRequest("设备未找到");
        return elevator;
    }

    @Override
    public String saveElevatorQrCode(Long elevatorId) {
        // 二维码生成规则
        JSONObject qrString = new JSONObject();
        Elevator elevator = this.getById(elevatorId);
        if(elevator == null) {
            throw new BadRequest("未找到电梯数据");
        }
        qrString.put("elevatorId",elevator.getSequenceNbr());
        qrString.put("rescueCode",elevator.getRescueCode());
        byte[] bytes = QRCodeUtil.generateQRCodeImageByteData(qrString.toJSONString(), 480);
        MultipartFile file = new MockMultipartFile("elevator_" + elevator.getSequenceNbr() + ".png","elevator_" + elevator.getSequenceNbr() + ".png","application/octet-stream" ,bytes);
        FeignClientResult<Map<String, String>> result =  Systemctl.fileStorageClient.updateCommonFile(file);
        Map<String, String> map = result.getResult();
        if(map.isEmpty()) {
            logger.error("未生成二维码文件");
            throw new BadRequest("未生成二维码文件");
        }
        String filePath = "";
        for(Map.Entry<String,String> fileResult : map.entrySet()) {
            filePath = fileResult.getKey();
        }
        // 保存qrCode
        List<AttachmentDto> qrCode = new ArrayList<>();
        AttachmentDto temp = new AttachmentDto();
        temp.setName("elevator_" + elevator.getSequenceNbr() + ".png");
        temp.setType("image");
        temp.setUrl(filePath);
        qrCode.add(temp);
        Map<String, List<AttachmentDto>> attachmentMap = new HashMap<>();
        attachmentMap.put("qrCode",qrCode);
        sourceFileService.saveAttachments(elevatorId,attachmentMap);
        return filePath;
    }


    public List<ElevatorWlInfoDto> queryElevatorList(ElevatorWlInfoDto esElevatorDto) {
       return elevatorMapper.queryElevatorList(esElevatorDto.getAddress(),
                esElevatorDto.getRegisterCode(),esElevatorDto.getRescueCode(),
                esElevatorDto.getType(), !ValidationUtil.isEmpty(esElevatorDto.getDealStatus()) ? Integer.parseInt(esElevatorDto.getDealStatus()) :null
                , esElevatorDto.getSequenceNbr(),(esElevatorDto.getPage()-1)*esElevatorDto.getSize(), esElevatorDto.getSize());
    }

    public List<ElevatorWlInfoDto> queryElevatorListDetails(ElevatorWlInfoDto esElevatorDto) {
        return elevatorMapper.queryElevatorListDetails(
                esElevatorDto.getSequenceNbr());
    }

    public int queryElevatorListCount() {
        return elevatorMapper.queryElevatorListCount();
    }
}
