package com.hdkj.lt.si.service.estimation.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hdkj.lt.base.exception.ExceptionCast;
import com.hdkj.lt.core.bizms.modle.dto.StateEstimation;
import com.hdkj.lt.core.bizms.modle.po.FhzgFeederAutoSwitchMapping;
import com.hdkj.lt.core.bizms.modle.request.StateEstimationEquipRequest;
import com.hdkj.lt.core.bizms.modle.request.StateEstimationRequest;
import com.hdkj.lt.core.rest.service.IRemoteCallService;
import com.hdkj.lt.si.dao.FhzgFeederAutoSwitchMappingMapper;
import com.hdkj.lt.si.service.estimation.StateEstimationService;
import com.hdkj.lt.si.service.remote.impl.SateEstimationRemoteCallServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StateEstimationServiceImpl implements StateEstimationService {

    @Resource(type = SateEstimationRemoteCallServiceImpl.class)
    private IRemoteCallService remoteCallService;

    @Value("${remote.stateEstimation.queryPeriodByFeeder-uri}")
    private String periodByFeederUri;

    @Value("${remote.stateEstimation.queryPeriodByEquip-uri}")
    private String periodByEquipUri;

    @Autowired
    private FhzgFeederAutoSwitchMappingMapper fhzgFeederAutoSwitchMappingMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public StateEstimation queryByFeeder(StateEstimationRequest request) {
        try {
            Object data = remoteCallService.call(periodByFeederUri, HttpMethod.POST, request, Object.class);
            return JSON.parseObject(JSON.toJSONString(data), StateEstimation.class);
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionCast.cast("调用状估接口失败");
        }
        return new StateEstimation();
    }

    @Override
    public StateEstimation queryPeriodByEquip(StateEstimationEquipRequest request) {
        request.setEndTime(convertTimeFormat(request.getEndTime()));
        request.setStartTime(convertTimeFormat(request.getStartTime()));
        try {
            Object data = remoteCallService.call(periodByEquipUri, HttpMethod.POST, request, Object.class);
            return JSON.parseObject(JSON.toJSONString(data), StateEstimation.class);
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionCast.cast("调用状估接口失败");
        }
        return new StateEstimation();
    }

    /**
     * 获取存储状估数据到redis
     *
     * @param request
     * @return
     */
    @Override
    public StateEstimation queryByFeederSave(StateEstimationRequest request) {
        StateEstimation stateEstimation = queryByFeeder(request);
        //log.info(stateEstimation.toString());
        log.info("调用状估接口并存储");
//        redisTemplate.opsForValue()
//                .set(request.getPsrIds().get(0) + request.getStartTime() + "zg", stateEstimation, 30, TimeUnit.MINUTES);
        //失效时间暂时移除
        redisTemplate.opsForValue()
                .set(request.getPsrIds().get(0) + request.getStartTime() + "zg", stateEstimation);
        return stateEstimation;

    }

    /**
     * 获取存储状估数据到redis
     *
     * @param request
     * @return
     */
    @Override
    public StateEstimation querySave(StateEstimationRequest request, StateEstimation stateEstimation) {
        log.info(stateEstimation.toString());
        redisTemplate.opsForValue()
                .set(request.getPsrIds().get(0) + request.getStartTime() + "zg", stateEstimation, 180, TimeUnit.MINUTES);
        return stateEstimation;

    }

    /**
     * 获取所有入参线路自动化开关信息
     * （入参需要线路和时间信息，时间取某一时刻即可）
     *
     * @param request
     */
    public List<FhzgFeederAutoSwitchMapping> saveAutoSwitch(StateEstimationRequest request) {
        Snowflake snowflake = IdUtil.getSnowflake(1,1);
        request.setIsAuto(true);
        request.setContainerCode(Collections.singletonList("switch"));
        StateEstimation stateEstimation = queryByFeeder(request);
        List<FhzgFeederAutoSwitchMapping> list = new ArrayList<>();
        if (stateEstimation != null) {
            list = new ArrayList<>(stateEstimation.getPeriodSwitchSeResult().stream().filter(a ->
                    a.getIsAuto().equals("true")
            ).map(a -> {
                FhzgFeederAutoSwitchMapping autoSwitchMapping = new FhzgFeederAutoSwitchMapping();
                autoSwitchMapping.setSwitchId(a.getPsrId()).setFeederId(a.getFeederId()).setId(snowflake.nextId())
                        .setCreator("auto").setIsAuto(1);
                return autoSwitchMapping;
            }).collect(Collectors.toMap(
                    b -> Arrays.asList(b.getFeederId(), b.getSwitchId()), Function.identity(),
                    (existing, replacement) -> existing
            )).values());
        }
        request.getPsrIds().forEach(i -> fhzgFeederAutoSwitchMappingMapper.delete(new LambdaUpdateWrapper<FhzgFeederAutoSwitchMapping>().eq(FhzgFeederAutoSwitchMapping::getFeederId, i)));
        list.forEach(i -> fhzgFeederAutoSwitchMappingMapper.insert(i));
        return list;
    }

    private String convertTimeFormat(String original) {
        DateTimeFormatter dateTimeFormat = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(original, dateTimeFormat);
        return dateTime.format(dateTimeFormatter);
    }
}
