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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.jcs.api.dto.FusionDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.VoiceRecordFileDto;
import com.yeejoin.amos.boot.module.jcs.api.entity.VoiceRecordFile;
import com.yeejoin.amos.boot.module.jcs.api.entity.VoiceRecordLog;
import com.yeejoin.amos.boot.module.jcs.api.enums.EmployeeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.PropertyEnum;
import com.yeejoin.amos.boot.module.jcs.api.mapper.VoiceRecordFileMapper;
import com.yeejoin.amos.boot.module.jcs.api.service.IVoiceRecordFileService;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.DataNotFound;

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

/**
 * 通话记录附件服务实现类
 *
 * @author system_generator
 * @date 2021-08-03
 */
@Service
public class VoiceRecordFileServiceImpl extends BaseService<VoiceRecordFileDto, VoiceRecordFile, VoiceRecordFileMapper> implements IVoiceRecordFileService {

    private final String SINGLE_PAWN = "FUSION_TERMINAL_SINGLE_PAWN";

    @Autowired
    private VoiceRecordFileServiceImpl voiceRecordFileServiceImpl;

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

    @Autowired
    AlertCalledServiceImpl iAlertCalledService;

    @Autowired
    FusionServiceImpl fusionService;

    private volatile JSONArray ctiInfos;

    @Autowired
    EmqKeeper emqKeeper;

    @Autowired
    VoiceRecordLogServiceImpl iVoiceRecordLogServiceImpl;

    @Autowired
    EquipFeignClient equipFeignClient;

    /**
     * 分页查询
     */
    public Page<VoiceRecordFileDto> queryForVoiceRecordFilePage(Page<VoiceRecordFileDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<VoiceRecordFileDto> queryForVoiceRecordFileList() {
        return this.queryForList("", false);
    }

    public VoiceRecordFileDto saveRecord(final VoiceRecordFileDto model) {
        Map<String, String> dMap = fusionService.getCallRecordByNumber(model.getCaller(), model.getCalled());
        // 保存到日志表中
        VoiceRecordLog log = new VoiceRecordLog();
        log.setAlertId(model.getAlertId());
        String cid = dMap.get("cid");
        Assert.notNull(cid, "CID不能为空");
        Map<String, String> callRecord = fusionService.getCallRecordByCID(cid);
        model.setConnectId(cid);
        log.setConnectId(cid);
        log.setIsDeal(false);
        log.setDealTimes(0);
        if (!ValidationUtil.isEmpty(callRecord)) {
            model.setFilePath(String.format("/%s/%s", callRecord.get("subPath"), callRecord.get("recordName").replace("wav", "mp3")));
            logger.info(String.format("音频地址：【%s】", String.format("/%s/%s", callRecord.get("subPath"), callRecord.get("recordName"))));
        } else { // 无录音地址记录日志
            iVoiceRecordLogServiceImpl.save(log);
        }
        return this.createWithModel(model);
    }

    @Override
    public Page<VoiceRecordFileDto> queryRecordListByQueryDto(Page<VoiceRecordFileDto> page, String telStartTimeStr, String telEndTimeStr, String fileType, String caller, String called, String sortParam, String sortRule) {
        Page<List<VoiceRecordFileDto>> list = baseMapper.queryRecordListByQueryDto(page,
                telStartTimeStr, telEndTimeStr, fileType, caller,
                called, sortParam, sortRule);
        Page<VoiceRecordFileDto> page1 = new Page<>();
        List<VoiceRecordFileDto> resultDtoList = JSONArray.parseArray(JSONArray.toJSONString(list.getRecords()), VoiceRecordFileDto.class);
        page1.setCurrent(page.getCurrent());
        page1.setSize(page.getSize());
        page1.setTotal(list.getTotal());
        page1.setRecords(resultDtoList);
        return page1;
    }

    @Override
    public VoiceRecordFileDto getRecordById(Long sequenceNbr) {
        VoiceRecordFileDto record = baseMapper.getRecordById(sequenceNbr);
        return buildFilePath(record);
    }

    @Override
    public List<VoiceRecordFileDto> selectExportData(String exportId) {
        List<String> ids = null;
        if (StringUtils.isNotEmpty(exportId)) {
            String[] idStr = exportId.split(",");
            ids = Arrays.asList(idStr);
        }
        return baseMapper.selectExportData(ids);
    }

    @Override
    public List<FusionDto> getCarList(Boolean hasFusion) {
        List<FusionDto> fusionDtos = new ArrayList<>();
        List carList = equipFeignClient.getCarFusionList().getResult();
        List<String> employeeIDs = getAllOnlineUser(hasFusion);
        if (!ValidationUtil.isEmpty(carList)) {
            carList.forEach(x -> {
                FusionDto fusionDto = new FusionDto();
                Map map = (Map) x;
                fusionDto.setName(String.valueOf(map.get("name")));
                fusionDto.setCarNum(String.valueOf(map.get("carNum")));
                buildFusionDtoAndId(fusionDto, employeeIDs, hasFusion, map);
                fusionDtos.add(fusionDto);
            });
        }

        return fusionDtos;
    }

    @Override
    public List<FusionDto> getSinglePawnList(Boolean hasFusion) {
        List<DictionarieValueModel> result = Systemctl.dictionarieClient.dictValues(SINGLE_PAWN).getResult();
        List<FusionDto> fusionDtos = new ArrayList<>();
        List<String> employeeIDs = getAllOnlineUser(hasFusion);

        result.forEach(model -> {
            FusionDto fusionDto = new FusionDto();
            String employeeID = model.getDictDataKey();
            fusionDto.setId(employeeID);
            fusionDto.setName(model.getDictDataValue());
            fusionDtos.add(buildFusionDto(fusionDto, employeeIDs, hasFusion));
        });

        return fusionDtos;
    }

    @Override
    public List<VoiceRecordFileDto> listByAlertId(Long alertId) {
        LambdaQueryWrapper<VoiceRecordFile> queryWrapper = new LambdaQueryWrapper<VoiceRecordFile>();
        queryWrapper.eq(VoiceRecordFile::getAlertId, alertId).orderByDesc(VoiceRecordFile::getRecDate);
        List<VoiceRecordFile> list = voiceRecordFileServiceImpl.list(queryWrapper);
        List<VoiceRecordFileDto> dtoList = new ArrayList<>();
        list.stream().forEach(voiceRecord -> {
            // 创建新的对象实例
            VoiceRecordFileDto target = new VoiceRecordFileDto();
            // 把原对象数据拷贝到新对象
            BeanUtils.copyProperties(voiceRecord, target);
            buildFilePath(target);
            dtoList.add(target);
        });
        return dtoList;
    }

    public VoiceRecordFileDto updateRecord(VoiceRecordFileDto model) {
        VoiceRecordFileDto oldModel = this.queryBySeq(model.getSequenceNbr());
        if (ValidationUtil.isEmpty(oldModel))
            throw new DataNotFound("找不到指定的数据.");
        oldModel.setAlertId(model.getAlertId());
        return this.updateWithModel(oldModel);
    }

    /**
     * 获取在线用户的employeeID集合
     *
     * @return
     */
    private List<String> getAllOnlineUser(Boolean hasFusion) {
        List<String> employeeIDs = new ArrayList<>();
        if (hasFusion) {
            JSONObject jsonObject = fusionService.getAllOnlineUser();
            if (!ValidationUtil.isEmpty(jsonObject)) {
                JSONArray onlines = jsonObject.getJSONArray("Onlines");
                onlines.forEach(x -> {
                    Map<String, String> obj = (Map) x;
                    employeeIDs.add(obj.get("employeeID"));
                });
            }
        }
        return employeeIDs;
    }

    private FusionDto buildFusionDtoAndId(FusionDto fusionDto, List<String> employeeIDs, Boolean hasFusion, Map map) {
        List carPropertyList = (List) map.get("carPropertyList");
        carPropertyList.forEach(carProperty -> {
            Map carPropertyMap = (Map) carProperty;
            Object nameKey = carPropertyMap.get("nameKey");
            if (hasFusion && PropertyEnum.GIS.getValue().equals(nameKey)) {
                fusionDto.setId(String.valueOf(carPropertyMap.get("value")));
            } else if (!hasFusion && PropertyEnum.VIDEO.getValue().equals(nameKey)) {
                fusionDto.setId(String.valueOf(carPropertyMap.get("value")));
            }
        });
        buildFusionDto(fusionDto, employeeIDs, hasFusion);
        return fusionDto;
    }

    private FusionDto buildFusionDto(FusionDto fusionDto, List<String> employeeIDs, Boolean hasFusion) {
        if (hasFusion) {
            Map<String, String> dMap = fusionService.getGISByEmployeeID(fusionDto.getId());
            fusionDto.setLatitude(dMap.get("latitude"));
            fusionDto.setLongitude(dMap.get("longitude"));
            fusionDto.setState(employeeIDs.contains(fusionDto.getId()) ? EmployeeEnum.在线.getValue() : EmployeeEnum.离线.getValue());
        }
        return fusionDto;
    }

    private VoiceRecordFileDto buildFilePath(VoiceRecordFileDto record) {
        Map<String, String> callRecord = fusionService.getCallRecordByCID(record.getConnectId());
        if (!ValidationUtil.isEmpty(callRecord)){
            record.setFilePath(String.format("/%s/%s", callRecord.get("subPath"), callRecord.get("recordName")));
        }
        return record;
    }
}