package com.tofly.feesapi.cbgl.service.impl;

import com.tofly.feesapi.bjgl.entity.dto.YhCbkxxSync;
import com.tofly.feesapi.bjgl.service.YhCbkxxService;
import com.tofly.feesapi.cbgl.entity.ZnbCbLog;
import com.tofly.feesapi.cbgl.entity.dto.ReadResult;
import com.tofly.feesapi.cbgl.service.CjService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 声立德克
 */
@Slf4j
@Service
public class SldkCjServiceImpl implements CjService {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private SldkProperties sldkProperties;

    private final Timer timer = new Timer("Token-remove-timer", true);
    private static String CACHE_TOKEN;

    @Override
    public List<ReadResult> read(List<String> sbbhs) {
        String token = getToken();
        return sbbhs.stream()
                .map(sbbh -> getReadResult(token, sbbh))
                .collect(Collectors.toList());
    }

    private ReadResult getReadResult(String token, String sn) {
        if (Thread.interrupted()) return null;
        String baseUrl = sldkProperties.getBaseUrl();
        String readUrl = sldkProperties.getReadUrl();
        String url = String.format("%s%s?token=%s&sn=%s", baseUrl, readUrl, token, sn);
        log.info("url:{}", url);
        ResponseEntity<SldkReadResult> response = restTemplate
                .getForEntity(url, SldkReadResult.class);
        SldkReadResult body = response.getBody();
        List<SldkReadData> data = body.getData();
        BigDecimal bcds = data != null && !data.isEmpty() ? new BigDecimal(data.get(0).accFlow) : null;
        return new ReadResult(sn, bcds);
    }

    private String getToken() {
        if (CACHE_TOKEN != null) return CACHE_TOKEN;
        synchronized (this) {
            String baseUrl = sldkProperties.getBaseUrl();
            String tokenUrl = sldkProperties.getTokenUrl();
            String appid = sldkProperties.getAppid();
            String secret = sldkProperties.getSecret();
            String url = String.format("%s%s?appid=%s&secret=%s", baseUrl, tokenUrl, appid, secret);

            Map<String, String> params = new LinkedHashMap<>();
//            params.put("appid", appid);
//            params.put("secret", secret);
            HttpEntity<Map> request = new HttpEntity<>(params);
            ResponseEntity<Token> response = restTemplate
                    .postForEntity(url, request, Token.class);
            Token body = response.getBody();
            long expires = body.getExpires();
            CACHE_TOKEN = body.getToken();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    CACHE_TOKEN = null;
                }
            }, expires > 5000 ? expires - 5000 : expires);
            return CACHE_TOKEN;
        }
    }

    @Override
    public void close(List<ZnbCbLog> qfList) {
        String sbbhs = qfList.stream().map(e -> e.getBjbh()).collect(Collectors.joining());
        log.info("关阀:{}", sbbhs);
    }

    @Override
    public void syncSyje(List<ZnbCbLog> znbCbLogs) {
        String sbbhs = znbCbLogs.stream().map(e -> e.getBjbh()).collect(Collectors.joining());
        log.info("同步智能表余额:{}", sbbhs);
    }

    @Override
    public void syncMeters(List<YhCbkxxSync> cbkxxList) {
        String token = getToken();
        List<Map<String, String>> params = cbkxxList.stream().map(e -> {
            Map<String, String> map = new HashMap<>();
            map.put("ownerGuid", e.getYhbh());
            map.put("sn", e.getSbbh());
            map.put("ownerName", e.getYhxm());
            map.put("address", e.getYhdz());
            map.put("phone", e.getLxdh());
            return map;
        }).collect(Collectors.toList());
        String baseUrl = sldkProperties.getBaseUrl();
        String postMetersUrl = sldkProperties.getPostMetersUrl();
        String url = String.format("%s%s", baseUrl, postMetersUrl);
        HttpHeaders headers = new HttpHeaders();
        headers.set("token", token);
        log.info("url:{}", url);
        HttpEntity<List<Map<String, String>>> request = new HttpEntity<>(params, headers);
        ResponseEntity<String> response = restTemplate
                .postForEntity(url, request, String.class);
        log.info("同步表档案结果:{}", response.getBody());
    }

    @Data
    private static class Token {
        private String token;
        private long expires;
    }

    @Data
    @ToString
    private static class SldkReadResult {

        private List<SldkReadData> data;
        private String iTotalRecords;
        private String iTotalDisplayRecords;
        private String httpCode;
        private String msg;
        private String timestamp;
    }

    @Data
    @ToString
    private static class SldkReadData {
        private String accFlow;
        private String flow;
        private String inTemp;
        private String meterStatus;
        private Date readTime;
        private String sn;
        private String temp;
    }
}
