package com.nokia.domainb.service;

import cn.chinaunicom.open.nlgxptconnection.COMPConnectionContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.nokia.common.http.R;
import com.nokia.domainb.capability.*;
import com.nokia.domainb.dto.*;
import com.nokia.domainb.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Service
public class DomainService {
    @Autowired
    private ThreadPoolExecutor qryowefeeExecutor;

    public R route(RouteDTO dto) {
        QryRouteAll qryRouteAll = new QryRouteAll();
        String result = qryRouteAll.query(dto.getPhoneNumber());
        JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
        JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                .getAsJsonObject("QRYROUTEALL_RSP")
                .getAsJsonObject("RSP");
        String rspCode = rsp.get("RSP_CODE").getAsString();
        if (!"0000".equals(rspCode)) {
            String rspDesc = rsp.get("RSP_DESC").getAsString();
            log.warn("route: {} -> {}", dto.getPhoneNumber(), rspDesc);
            return R.error().message(rspDesc);
        }

        RouteVO vo = new RouteVO();
        vo.setPhoneNumber(dto.getPhoneNumber());
        JsonObject data = rsp.getAsJsonArray("DATA").get(0).getAsJsonObject();
        JsonElement routeTypeElement = data.get("ROUTE_TYPE");
        if (routeTypeElement != null) {
            vo.setRouteType(routeTypeElement.getAsString());
        }

        JsonElement userStatusElement = data.get("USER_STATUS");
        if (userStatusElement != null) {
            vo.setUserStatus(userStatusElement.getAsString());
        }

        JsonElement provinceCodeElement = data.get("PROVINCE_CODE");
        if (provinceCodeElement != null) {
            vo.setProvinceCode(data.get("PROVINCE_CODE").getAsString());
        }

        JsonElement eparchyCodeElement = data.get("EPARCHY_CODE");
        if (eparchyCodeElement != null) {
            vo.setEparchyCode(eparchyCodeElement.getAsString());
        }

        if ("3".equals(vo.getUserStatus())) {
            return R.error().message("非CB 号码在cBss系统没有路由记录");
        }

        vo.setIsUnicomNumber(true);
        return R.ok().data(vo);
    }

    public R sa(SaDTO dto) {
        R r = route(new RouteDTO(dto.getFromSystem(), dto.getPhoneNumber()));
        if (Boolean.FALSE.equals(r.getSuccess())) {
            return r;
        }

        RouteVO routeVO = (RouteVO) r.getData();
        SaVO vo = new SaVO();
        vo.setIsUnicomNumber(true);
        QryUserIsUdm qryUserIsUdm = new QryUserIsUdm();
        COMPConnectionContext result = qryUserIsUdm.query(dto.getPhoneNumber(), routeVO.getProvinceCode(), false);
        JsonObject jsonObject = JsonParser.parseString(result.getResponseContext()).getAsJsonObject();
        JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                .getAsJsonObject("QRY_USER_IS_UDM_RSP")
                .getAsJsonObject("RSP");
        String rspCode = rsp.get("RSP_CODE").getAsString();
        if (!"0000".equals(rspCode)) {
            String rspDesc = rsp.get("RSP_DESC").getAsString();
            log.warn("sa: {} -> {}", dto.getPhoneNumber(), rspDesc);
            return R.error().message(rspDesc);
        }

        JsonObject data = rsp.getAsJsonArray("DATA").get(0).getAsJsonObject();
        JsonElement isHaveSaElement = data.get("IS_HAVE_SA");
        if (isHaveSaElement != null) {
            vo.setIsHaveSa("Y".equals(isHaveSaElement.getAsString()));
        }

        JsonElement isUdmUserElement = data.get("IS_UDM_USER");
        if (isUdmUserElement != null) {
            vo.setIsUdmUser("Y".equals(isUdmUserElement.getAsString()));
        }

        return R.ok().data(vo);
    }

    public R saAndVolte(SaAndVolteDTO dto) {
        Foreignproduct foreignproduct = new Foreignproduct();
        COMPConnectionContext result = foreignproduct.query(dto.getPhoneNumber(), "18", false);
        JsonObject jsonObject = JsonParser.parseString(result.getResponseContext()).getAsJsonObject();
        JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                .getAsJsonObject("FOREIGN_PRODUCT_RSP")
                .getAsJsonObject("RSP");
        String rspCode = rsp.get("RSP_CODE").getAsString();
        if (!"0000".equals(rspCode)) {
            String rspDesc = rsp.get("RSP_DESC").getAsString();
            log.warn("saAndVolte: {} -> {}", dto.getPhoneNumber(), rspDesc);
            return R.error().message(rspDesc);
        }

        SaAndVolteVO vo = new SaAndVolteVO();
        vo.setIsHaveSa(false);
        vo.setIsHaveVolte(false);
        vo.setIsHebeiUnicomNumber(true);
        String res = result.getResponseContext();
        if (res.contains("VoLTE")) {
            vo.setIsHaveVolte(true);
        }

        if (res.contains("SA")) {
            vo.setIsHaveSa(true);
        }

        return R.ok().data(vo);
    }

    public R userState(UserStateDTO dto) {
        SpThreePartCheck spThreePartCheck = new SpThreePartCheck();
        COMPConnectionContext result = spThreePartCheck.query(dto.getPhoneNumber(), "18", false);
        JsonObject jsonObject = JsonParser.parseString(result.getResponseContext()).getAsJsonObject();
        JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                .getAsJsonObject("SP_THREEPART_CHECK_RSP")
                .getAsJsonObject("RSP");
        String rspCode = rsp.get("RSP_CODE").getAsString();
        if (!"0000".equals(rspCode)) {
            String rspDesc = rsp.get("RSP_DESC").getAsString();
            log.warn("userState: {} -> {}", dto.getPhoneNumber(), rspDesc);
            return R.error().message(rspDesc);
        }

        JsonObject data = rsp.getAsJsonArray("DATA").get(0).getAsJsonObject();
        JsonElement userStateElement = data.getAsJsonObject("userInfo").get("userState");
        if (userStateElement == null) {
            String detail = data.get("detail").getAsString();
            return R.error().message(detail);
        }

        String userState = userStateElement.getAsString();
        return R.ok().data(new UserStateVO(userState));
    }

    public R qryowefee(QryowefeeDTO dto) {
        // 用户信用度查询
        CompletableFuture<R> t1 = CompletableFuture.supplyAsync(() -> {
            GetEcredit getEcredit = new GetEcredit();
            String result = getEcredit.query(dto.getPhoneNumber());
            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
            JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                    .getAsJsonObject("GET_ECREDIT_RSP")
                    .getAsJsonObject("RSP");
            String rspCode = rsp.get("RSP_CODE").getAsString();
            if (!"0000".equals(rspCode)) {
                String rspDesc = rsp.get("RSP_DESC").getAsString();
                log.warn("getEcredit: {} -> {}", dto.getPhoneNumber(), rspDesc);
                return R.error().message(rspDesc);
            }

            JsonObject data = rsp.getAsJsonArray("DATA").get(0).getAsJsonObject();
            JsonObject creditInfo = data.getAsJsonObject("CREDIT_INFO");
            if (creditInfo == null) {
                String detail = data.get("detail").getAsString();
                return R.error().message(detail);
            }

            QryowefeeVO vo = new QryowefeeVO();
            JsonElement creditClassElement = creditInfo.get("CREDIT_CLASS");
            if (creditClassElement != null) {
                vo.setCreditClass(creditClassElement.getAsString());
            }

            JsonElement totalCreditValueElement = creditInfo.get("TOTAL_CREDIT_VALUE");
            if (totalCreditValueElement != null) {
                vo.setTotalCreditValue(totalCreditValueElement.getAsString());
            }

            JsonElement availableCreditValueElement = creditInfo.get("AVAILABLE_CREDIT_VALUE");
            if (availableCreditValueElement != null) {
                vo.setAvailableCreditValue(availableCreditValueElement.getAsString());
            }

            return R.ok().data(vo);
        }, qryowefeeExecutor);
        // 欠费查询
        CompletableFuture<R> t2 = CompletableFuture.supplyAsync(() -> {
            // 路由查询
            R route = route(new RouteDTO(dto.getFromSystem(), dto.getPhoneNumber()));
            if (route.getSuccess().equals(false)) {
                return route;
            }

            QryowefeeVO vo = new QryowefeeVO();
            RouteVO routeVO = (RouteVO) route.getData();
            String province = routeVO.getProvinceCode();
            if (!StringUtils.hasText(province)) {
                return R.ok().data(vo);
            }

            // 欠费查询
            QryOweFee qryOweFee = new QryOweFee();
            String result = qryOweFee.query(dto.getPhoneNumber(), province);
            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
            JsonObject rsp = jsonObject.getAsJsonObject("UNI_BSS_BODY")
                    .getAsJsonObject("QRY_OWE_FEE_RSP")
                    .getAsJsonObject("RSP");
            String rspCode = rsp.get("RSP_CODE").getAsString();
            if (!"0000".equals(rspCode)) {
                String rspDesc = rsp.get("RSP_DESC").getAsString();
                log.warn("qryOweFee: {} -> {}", dto.getPhoneNumber(), rspDesc);
                return R.error().message(rspDesc);
            }

            JsonObject data = rsp.getAsJsonArray("DATA").get(0).getAsJsonObject();
            JsonObject oweFeeInfo = data.getAsJsonObject("OWE_FEE_INFO");
            if (oweFeeInfo == null) {
                String detail = data.get("detail").getAsString();
                return R.error().message(detail);
            }
            JsonElement payFeeElement = oweFeeInfo.get("PAY_FEE");
            if (payFeeElement != null) {
                vo.setPayFee(payFeeElement.getAsString());
            }

            JsonElement balanceFeeElement = oweFeeInfo.get("BALANCE_FEE");
            if (balanceFeeElement != null) {
                vo.setBalanceFee(balanceFeeElement.getAsString());
            }

            JsonElement realFeeElement = oweFeeInfo.get("REAL_FEE");
            if (realFeeElement != null) {
                vo.setRealFee(realFeeElement.getAsString());
            }

            return R.ok().data(vo);
        }, qryowefeeExecutor);
        // 整合结果
        return CompletableFuture.allOf(t1, t2).thenApply(r -> {
            R r1 = t1.join();
            if (r1.getSuccess().equals(false)) {
                return r1;
            }

            R r2 = t2.join();
            if (r2.getSuccess().equals(false)) {
                return r2;
            }

            QryowefeeVO v1 = (QryowefeeVO) r1.getData();
            QryowefeeVO v2 = (QryowefeeVO) r2.getData();
            v1.setPayFee(v2.getPayFee());
            v1.setBalanceFee(v2.getBalanceFee());
            v1.setRealFee(v2.getRealFee());
            return R.ok().data(v1);
        }).exceptionally(e -> {
            log.error("欠费接口整合异常: {}", e.getMessage(), e);
            return R.error().message(e.getMessage());
        }).join();
    }
}
