package cn.skcks.docking.gb28181.wvp.service.record;

import cn.skcks.docking.gb28181.common.json.JsonException;
import cn.skcks.docking.gb28181.common.json.JsonResponse;
import cn.skcks.docking.gb28181.common.xml.XmlUtils;
import cn.skcks.docking.gb28181.core.sip.gb28181.constant.CmdType;
import cn.skcks.docking.gb28181.core.sip.message.subscribe.GenericSubscribe;
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
import cn.skcks.docking.gb28181.service.record.vo.RecordInfoItemVO;
import cn.skcks.docking.gb28181.sip.manscdp.recordinfo.request.RecordInfoRequestDTO;
import cn.skcks.docking.gb28181.wvp.orm.mybatis.dynamic.model.WvpProxyDevice;
import cn.skcks.docking.gb28181.wvp.orm.mybatis.dynamic.model.WvpProxyDocking;
import cn.skcks.docking.gb28181.wvp.service.device.DeviceService;
import cn.skcks.docking.gb28181.wvp.service.docking.DockingService;
import cn.skcks.docking.gb28181.wvp.service.record.dto.RecordInfoDTO;
import cn.skcks.docking.gb28181.wvp.sip.request.SipRequestBuilder;
import cn.skcks.docking.gb28181.wvp.sip.sender.SipSender;
import cn.skcks.docking.gb28181.wvp.sip.subscribe.RecordSubscribe;
import cn.skcks.docking.gb28181.wvp.sip.subscribe.SipSubscribe;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;

import java.text.MessageFormat;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class RecordInfoService {
    private final SipSender sipSender;
    private final SipSubscribe sipSubscribe;
    private final DockingService dockingService;
    private final DeviceService deviceService;

    @SneakyThrows
    public DeferredResult<JsonResponse<List<RecordInfoItemVO>>> requestRecordInfo(RecordInfoDTO dto){
        String deviceCode = dto.getDeviceCode();
        Optional<WvpProxyDevice> deviceByDeviceCode = deviceService.getDeviceByDeviceCode(deviceCode);
        if (deviceByDeviceCode.isEmpty()) {
            String reason = MessageFormat.format("未能找到 设备编码 为 {0} 的设备", deviceCode);
            log.error("{}",reason);
            throw new JsonException(reason);
        } else {
            WvpProxyDevice device = deviceByDeviceCode.get();
            return requestRecordInfo(device.getGbDeviceId(), device.getGbDeviceChannelId(), dto);
        }
    }

    public DeferredResult<JsonResponse<List<RecordInfoItemVO>>> requestRecordInfo(String gbDeviceId, String channel, RecordInfoDTO dto){
        DeferredResult<JsonResponse<List<RecordInfoItemVO>>> result = new DeferredResult<>();
        Optional<WvpProxyDocking> deviceByGbDeviceId = dockingService.getDeviceByGbDeviceId(gbDeviceId);
        if(deviceByGbDeviceId.isEmpty()){
            log.info("未能找到 国标编码 {} 的注册信息", gbDeviceId);
            result.setResult(JsonResponse.error(MessageFormat.format("未能找到 设备编码 为 {0} 的设备", gbDeviceId)));
            return result;
        }
        Optional<WvpProxyDevice> deviceByGbDeviceIdAndChannel = deviceService.getDeviceByGbDeviceIdAndChannel(gbDeviceId, channel);
        if (deviceByGbDeviceIdAndChannel.isEmpty()) {
            log.info("未能找到 编码 {}, 通道 {} 的设备", gbDeviceId, channel);
            result.setResult(JsonResponse.error(MessageFormat.format("未能找到 编码 {0}, 通道 {1} 的设备", gbDeviceId, channel)));
            return result;
        }
        WvpProxyDocking device = deviceByGbDeviceId.get();
        String sn = String.valueOf((int) (Math.random() * 9 + 1) * 100000);
        RecordInfoRequestDTO recordInfoRequestDTO = RecordInfoRequestDTO.builder()
                .deviceId(channel)
                .sn(sn)
                .startTime(dto.getStartTime())
                .endTime(dto.getEndTime())
                .type(dto.getType())
                .secrecy(dto.getSecrecy())
                .filePath(dto.getFilePath())
                .indistinctQuery(0)
                .build();

        String key = GenericSubscribe.Helper.getKey(CmdType.RECORD_INFO, channel, sn);
        sipSubscribe.getMessageSubscribe().addPublisher(key);
        sipSubscribe.getMessageSubscribe().addSubscribe(key, new RecordSubscribe(sipSubscribe, key, result, gbDeviceId));
        sipSender.sendRequest((provider, ip, port)-> SipRequestBuilder.createMessageRequest(device,ip,port,SipRequestBuilder.getCSeq(), XmlUtils.toXml(recordInfoRequestDTO), SipUtil.generateViaTag(),
                SipUtil.generateFromTag(), provider.getNewCallId()));
        return result;
    }
}
