package cokr.xit.ens.modules.common.ctgy.nicedici.presentation;

import cokr.xit.ens.core.aop.EnsResponseVO;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import cokr.xit.ens.modules.common.ctgy.nicedici.code.LinkType;
import cokr.xit.ens.modules.common.ctgy.nicedici.service.NiceDiCiService;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.NiceCiApiExecutor;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.model.NiceCiRespDTO;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.model.NiceCiRespVO;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.model.conf.DataBodyCiResp;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.model.conf.DataBodySymkeyResp;
import cokr.xit.ens.modules.common.ctgy.nicedici.support.rest.utils.SymmetricKey;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

@Tag(name = "NiceDiCiController")
@RestController
@RequiredArgsConstructor
public class NiceDiCiController {

    private final NiceDiCiService niceDiCiService;


    @Value("${contract.nice.dici.rest.host}")
    private String HOST;
    @Value("${contract.nice.dici.rest.client-id}")
    private String CLIENT_ID;
    @Value("${contract.nice.dici.rest.client-secret}")
    private String CLIENT_SECRET;
    @Value("${contract.nice.dici.rest.api.generate-token}")
    private String API_GENERATE_TOKEN;
    @Value("${contract.nice.dici.rest.api.revoke-token}")
    private String API_REVOKE_TOKEN;
    @Value("${contract.nice.dici.rest.api.publickey}")
    private String API_PUBLICKEY;
    @Value("${contract.nice.dici.rest.api.symmetrickey}")
    private String API_SYMMETRICKEY;
    @Value("${contract.nice.dici.rest.api.ci}")
    private String API_CI;


    @Parameters({
            @Parameter(in = ParameterIn.PATH, name = "siteCode"),
            @Parameter(in = ParameterIn.PATH, name = "sitePw"),
            @Parameter(in = ParameterIn.QUERY, name = "jid"),
    })
    @Operation(summary = "ci 변환")
    @GetMapping("/cmft/nice/ci/{siteCode}/{sitePw}")
    public ResponseEntity<EnsResponseVO> ci(@PathVariable String siteCode, @PathVariable String sitePw, @RequestParam String jid) {
        EnsResponseVO responseVO = null;

        EnsResponseVO resp = niceDiCiService.ci(LinkType.socket, siteCode, sitePw, Arrays.asList(jid));

        if (EnsErrCd.OK.equals(resp.getErrCode())) {   
            responseVO = EnsResponseVO.okBuilder()
                    .resultInfo(resp.getResultInfo())
                    .build();

        } else {   
            responseVO = resp;
        }


        return new ResponseEntity<EnsResponseVO>(responseVO, HttpStatus.OK);
    }


//    @Operation(summary = "1.토큰발급")
//    @GetMapping("/cmft/nice/ci/rest/step1")
//    public ResponseEntity<EnsResponseVO<DataBodyGenerateTokenResp>> step1() {
//        EnsResponseVO<DataBodyGenerateTokenResp> restResponseVO = niceCiApi.generateToken(SITE_CODE, SITE_PW);
//
//        return new ResponseEntity<EnsResponseVO<DataBodyGenerateTokenResp>>(restResponseVO, HttpStatus.OK);
//    }
//
//    @Operation(summary = "1-2.토큰폐기")
//    @GetMapping("/cmft/nice/ci/rest/step1-2")
//    public ResponseEntity<EnsResponseVO<DataBodyRevokeTokenResp>> step1_2(@RequestBody Map<String, String> mParam) {
//        String accessToken = mParam.get("accessToken");
//        EnsResponseVO<DataBodyRevokeTokenResp> restResponseVO = niceCiApi.revokeToken(accessToken, SITE_CODE);
//
//        return new ResponseEntity<EnsResponseVO<DataBodyRevokeTokenResp>>(restResponseVO, HttpStatus.OK);
//    }
//
//    @Operation(summary = "2.공개키 요청")
//    @GetMapping("/cmft/nice/ci/rest/step2")
//    public ResponseEntity<EnsResponseVO<DataBodyPubkeyResp>> step2(@RequestBody Map<String, String> mParam) {
//        String accessToken = mParam.get("accessToken");
//        String clientId = mParam.get("clientId");
//        String pubkeyVersion = mParam.get("pubkeyVersion");
//        String symkeyRegInfo = mParam.get("symkeyRegInfo");
//        EnsResponseVO<DataBodyPubkeyResp> restResponseVO = niceCiApi.generatePublickey(accessToken, clientId, pubkeyVersion, symkeyRegInfo);
//
//        return new ResponseEntity<EnsResponseVO<DataBodyPubkeyResp>>(restResponseVO, HttpStatus.OK);
//    }
//
//    @Operation(summary = "3.대칭키 요청")
//    @GetMapping("/cmft/nice/ci/rest/step3")
//    public ResponseEntity<EnsResponseVO<DataBodySymkeyResp>> step3(@RequestBody Map<String, String> mParam) {
//        String accessToken = mParam.get("accessToken");
//        String clientId = mParam.get("clientId");
//        String pubkeyVersion = mParam.get("pubkeyVersion");
//        String symkeyRegInfo = mParam.get("symkeyRegInfo");
//        EnsResponseVO<DataBodySymkeyResp> restResponseVO = niceCiApi.generateSymmetrickey(accessToken, clientId, pubkeyVersion, symkeyRegInfo);
//
//        return new ResponseEntity<EnsResponseVO<DataBodySymkeyResp>>(restResponseVO, HttpStatus.OK);
//    }
//
//    @Operation(summary = "4.CI 변환")
//    @GetMapping("/cmft/nice/ci/rest/step4")
//    public ResponseEntity<EnsResponseVO<DataBodyCiResp>> step4(@RequestBody Map<String, String> mParam) {
//        String clientId = mParam.get("clientId");
//        String clientSecret = mParam.get("clientSecret");
//        String symkeyVersion = mParam.get("symkeyVersion");
//        String encData = mParam.get("encData");
//        String integrityValue = mParam.get("integrityValue");
//        EnsResponseVO<DataBodyCiResp> restResponseVO = niceCiApi.getCi(clientId, clientSecret, symkeyVersion, encData, integrityValue);
//
//        return new ResponseEntity<EnsResponseVO<DataBodyCiResp>>(restResponseVO, HttpStatus.OK);
//    }

    @Parameters({
            @Parameter(in = ParameterIn.PATH, name = "clientId"),
            @Parameter(in = ParameterIn.PATH, name = "clientSecret"),
            @Parameter(in = ParameterIn.QUERY, name = "jid"),
    })
    @Operation(summary = "CI 변환(rest API)")
    @GetMapping(value = "/cmft/nice/ci/rest/{clientId}/{clientSecret}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EnsResponseVO> getCi(@PathVariable String clientId, @PathVariable String clientSecret, @RequestParam String jid) {
        EnsResponseVO responseVO = null;

        EnsResponseVO resp = niceDiCiService.ci(LinkType.rest, clientId, clientSecret, Arrays.asList(jid));

        if (EnsErrCd.OK.equals(resp.getErrCode())) {   
            responseVO = EnsResponseVO.okBuilder()
                    .resultInfo(resp.getResultInfo())
                    .build();

        } else {   
            responseVO = resp;
        }

        return new ResponseEntity<EnsResponseVO>(responseVO, HttpStatus.OK);
    }


    @Parameters({
            @Parameter(in = ParameterIn.PATH, name = "jid"),
    })
    @Operation(summary = "CI 변환(rest API) 테스트")
    @GetMapping(value = "/cmft/nice/ci/rest/{jid}/test", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<EnsResponseVO> getCiTest(@PathVariable String jid) throws Exception {

        final ObjectMapper mapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        final String respBody = "{  \"dataHeader\": {    \"CNTY_CD\": \"ko\",    \"GW_RSLT_CD\": \"1200\",    \"GW_RSLT_MSG\": \"오류 없음\"  },  \"dataBody\": {    \"rsp_cd\": \"P000\",    \"result_cd\": \"0000\",    \"symkey_stat_info\": \"{\\\"cur_symkey_version\\\":\\\"2022050990141666-D28C-IP9E-A61E-8C54984218ED\\\",\\\"cur_valid_dtim\\\":\\\"20221109142207\\\",\\\"bef_symkey_version\\\":\\\"20220506A6834B1B-1288-IPCD-965C-8C9B30558CCF\\\",\\\"bef_valid_dtim\\\":\\\"20221106180509\\\"}\"  }}";

        String strRespBody = respBody.replace("\"\"", "null");
        strRespBody = strRespBody.replace("\\", "").replace("\"{", "{").replace("}\"", "}"); 
        NiceCiRespDTO<DataBodySymkeyResp> respDTO = mapper.readValue(strRespBody, new TypeReference<NiceCiRespDTO<DataBodySymkeyResp>>() {
        });
        if (!(respDTO.getDataBody() == null || "".equals(respDTO.getDataBody()))) {
            respDTO.getDataBody().setSiteCode("R0k3Nw==");
            respDTO.getDataBody().setRequestNo("tpvqiofuregohiogpcsuxtdejqkfwj");
            respDTO.getDataBody().setKey("quwvgxnyqalbguobfbtmfrlhroprqdwi");
            respDTO.getDataBody().setIv("ealxvqbxgrmcvrgs");
            respDTO.getDataBody().setHmacKey("oldiptsfqlrrqkkvbpihjtjyqgdajxym");
        }
        NiceCiApiExecutor executor = NiceCiApiExecutor.builder()
                .HOST(this.HOST)
                .CLIENT_ID(this.CLIENT_ID)
                .CLIENT_SECRET(this.CLIENT_SECRET)
                .API_GENERATE_TOKEN(this.API_GENERATE_TOKEN)
                .API_REVOKE_TOKEN(this.API_REVOKE_TOKEN)
                .API_PUBLICKEY(this.API_PUBLICKEY)
                .API_SYMMETRICKEY(this.API_SYMMETRICKEY)
                .API_CI(this.API_CI)
                .build();
        SymmetricKey.getInstance(this.CLIENT_ID, respDTO.getDataBody());
        NiceCiRespVO<DataBodyCiResp> ciResponseVO = executor.ci(jid, "127.0.0.1");


        EnsResponseVO responseVO = EnsResponseVO.okBuilder().resultInfo(ciResponseVO).build();
        return new ResponseEntity<EnsResponseVO>(responseVO, HttpStatus.OK);
    }
}
