//단말기 연동여부 (단말기 연결 안하고 테스트할 시 false 단말기 연동 시 true로 변경.)
var terminalLinkage = false;
let completeFlag = false;
/*
!!!! 요청데이터 !!!!!
    S01 전문 구분코드     (필수값) 2자리
    S02 WCC                     1자리
    S03 카드번호                40자리
    S04 할부/현금 영수증용도       2자리
    S05 승인일시                 6자리
    S06 승인번호                12자리
    S07 금액                    8자리
    S08 봉사료                  8자리
    S09 부가세                  8자리




!!!! 응답데이터 !!!!!
    R01 전문구분코드            2자리
    R02 응답코드               4자리
    R03 단말기번호(TID)         8자리
    R04 WCC                   1자리
    R05 카드번호              40자리
    R06 할부/영수증용도         2자리
    R07 금액                  8자리
    R08 봉사료			     8자리
    R09 VAT		             8자리
    R10 승인번호		        12자리
    R11 승인일시      	    12자리
    R12 발급사코드             3자리
    R13 카드사명              20자리
    R14 가맹점코드            12자리
    R15 매입사코드             3자리
    R16 매입사명              20자리
    R17 POS거래번호           20자리
    R18 DSC구분               1자리
    R19 전자서명
*/

/****************************************************************************
 * 지정된 길이로 문자열을 맞추고 왼쪽에 공백을 추가
 ****************************************************************************/
function padString(str, length) {
      return (str ? str : '').padStart(length, ' ');
}

/****************************************************************************
 * 결제 데이터 문자열을 생성
 ****************************************************************************/
function createDataString(params) {
    const fixedValue = "CM^FD^00^00^"; //고정값

    // 각 파라미터의 길이 지정
    const paramStr = [
        padString(params.S01, 2),   // 전문 구분코드 2자리
        padString(params.S02, 1),   // WCC 1자리
        padString(params.S03, 40),  // 카드번호 40자리
        padString(params.S04, 2),   // 할부/현금 영수증용도 2자리
        padString(params.S05, 6),   // 승인일시 6자리
        padString(params.S06, 12),  // 승인번호 12자리
        padString(params.S07, 8),   // 금액 8자리
        padString(params.S08, 8),   // 봉사료 8자리
        padString(params.S09, 8),    // 부가세 8자리
        // padString(params.S10,params.S10.length)    // POS거래번호 8자리
    ].join('');  // 파라미터 사이에 공백 없이 연결
    //결제 요청시간 60초로 고정.
    //더 길게해도 단말기 최대 요청 시간이 60초인것으로 보임.
     return `${fixedValue}${paramStr}^60000^Y^^`;
}

/****************************************************************************
 * 단말기 응답 데이터 파싱
 ****************************************************************************/
function parseResponseString(responseString) {
    return {
        transactionType: sliceByBytes(responseString, 0, 2),          // 전문구분코드 2바이트
        responseCode: sliceByBytes(responseString, 2, 4),             // 응답코드 4바이트
        terminalId: sliceByBytes(responseString, 6, 8),               // 단말기번호(TID) 8바이트
        WCC: sliceByBytes(responseString, 14, 1),                     // WCC 1바이트
        cardNumber: sliceByBytes(responseString, 15, 40).replace(/[\x00-\x1F\x7F]/g, ''), // 카드번호 40바이트
        paymentOptionCode: sliceByBytes(responseString, 55, 2),       // 할부/영수증용도 2바이트 installmentMonths or cashReceiptPurpose or earnPoint
        totalAmount: sliceByBytes(responseString, 57, 8),             // 금액 8바이트
        serviceFee: sliceByBytes(responseString, 65, 8),              // 봉사료 8바이트
        vatAmount: sliceByBytes(responseString, 73, 8),               // VAT 8바이트
        approvalNo: sliceByBytes(responseString, 81, 12),             // 승인번호 12바이트
        approvalDate: sliceByBytes(responseString, 93, 12),           // 승인일시 12바이트
        issuerCode: sliceByBytes(responseString, 105, 3),             // 발급사코드 3바이트
        issuerName: sliceByBytes(responseString, 108, 20),            // 카드사명 20바이트
        merchantCode: sliceByBytes(responseString, 128, 12),          // 가맹점코드 12바이트
        acquirerCode: sliceByBytes(responseString, 140, 3),           // 매입사코드 3바이트
        acquirerName: sliceByBytes(responseString, 143, 20),          // 매입사명 20바이트
        posTransactionNumber: sliceByBytes(responseString, 163, 20),  // POS거래번호 20바이트
        dscType: sliceByBytes(responseString, 183, 1)                 // DSC구분 1바이트
    };
}

/****************************************************************************
 * 응답 문자열에서 해당 항목 데이터 구분해서 리턴.
 ****************************************************************************/
function sliceByBytes(str, start, length) {
    let byteLength = 0;
    let result = '';

    for (let char of str) {
        let charLength = char.charCodeAt(0) > 0xFF ? 2 : 1;  // UTF-16에서 한글은 2바이트, 영문자나 숫자는 1바이트
        if (byteLength + charLength > start + length) break;
        if (byteLength >= start) result += char;
        byteLength += charLength;
    }

    return result.trim();
}

/****************************************************************************
 * 단말기에 결제 데이터 전송
 ****************************************************************************/
function sendData(dataString) {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: encodeURI('http://127.0.0.1:90'),
            dataType: 'jsonp',
            jsonp: 'callback',
            data: {"REQ": dataString},
            cache: true,
            type: 'GET',
            async: false,
            success: function (data) {
                console.log('Success:', data.MSG);
                let parsedData = {};
                //요청 성공 시
                if(data.SUC==='00'){
                    let parsingData = parseData(JSON.stringify(data)).RDATA;
                    parsedData = parseResponseString(parsingData);
                    if('0000' !== parsedData.responseCode) {
                        parsedData.msg = parsingData.split('=')[parsingData.length - 1].trim();
                    }
                }else{
                    parsedData.responseCode = data.SUC;
                    if (data.MSG === "User Cancel") {
                        parsedData.msg= "결제가 고객에 의해 취소되었습니다.";
                    } else if (data.MSG === "Time Over") {
                        parsedData.msg= "결제 요청이 시간 초과되었습니다.";
                    } else if (data.MSG === "9996") {
                        parsedData.msg= "LAN 통신 에러가 발생했습니다.";
                    } else if (data.MSG === "FAIL") {
                        parsedData.msg= "결제 처리 중 오류가 발생했습니다.";
                    } else {
                        parsedData.msg= "알 수 없는 오류가 발생했습니다."; // 예상치 못한 메시지에 대한 기본 처리
                    }
                    $(".loading-image-layer").hide();
                }
                resolve(parsedData);
            },
            error: function (xhr, status, error) {
                console.error('Error:', error);
                reject(error);
            },
            beforeSend: function () {
                console.log('Sending data...');
            },
            complete: function () {
                console.log('Request complete');
            }
        });
    });
}

function decodeEucKr(base64String) {
    const buffer = Uint8Array.from(atob(base64String), c => c.charCodeAt(0));
    const decoder = new TextDecoder('euc-kr');
    return decoder.decode(buffer);
}

function parseData(response) {
    // 응답을 JSON 형식으로 파싱
    let parsedResponse;
    try {
        parsedResponse = JSON.parse(response);
    } catch (e) {
        console.error('Parsing error:', e);
        return null;
    }

    if (!parsedResponse.SUC || parsedResponse.SUC !== '00' || !parsedResponse.MSG) {
        console.error('Invalid response format:', parsedResponse);
        return parsedResponse.msg;
    }

    // MSG 데이터 파싱
    const msg = parsedResponse.MSG;
    const parts = msg.split('^');

    if (parts.length < 6) {
        console.error('Invalid MSG format:', msg);
        return null;
    }

    const [CMD, GCD, JCD, RCD, base64RDATA, hexRHexData] = parts;

    // Base64 디코딩
    const decodedRDATA = decodeEucKr(base64RDATA);
    const RHexData = hexToStringUTF8(hexRHexData.replace("$", ""));
    console.log(RHexData);
    return {
        CMD,
        GCD,
        JCD,
        RCD,
        RDATA: decodedRDATA,
        RHexData
    };
}

function hexToStringUTF8(hexRHexData) {
    return utf8_hex_string_to_string(hexRHexData);
}

function utf8_hex_string_to_string(hex_str1) {
    // UTF-8에서 EUC-KR로 변환
    const utf8Bytes = new Uint8Array(hex_str1.match(/[\da-f]{2}/gi).map(function (h) {
        return parseInt(h, 16);
    }));
    return new TextDecoder('euc-kr').decode(utf8Bytes);
}

/****************************************************************************
 * 단말기 결제요청 데이터 저장
 ****************************************************************************/
function fn_saveRequestParam(param,userData){
    let muPaymentRequestHistoryId='';

    let muUserId = userData.muUserId;
    let userName = userData.userName;
    let cashReceiptPurpose = param.S03?param.S03.length>10?'00':'01':''
    let formData = new FormData();
    formData.append('menuClass',menuClass);
    formData.append('muUserId',muUserId);
    formData.append('userName',userName);
    formData.append('transactionType',param.S01);
    formData.append('cashReceiptInfo',param.S03);
    formData.append('cashReceiptPurpose',cashReceiptPurpose);
    formData.append('totalAmount',param.S07);
    formData.append('vatAmount',param.S09);

    $.ajax({
        url: encodeURI('/webpayment/insertPaymentRequestHistory.do'),
        data: formData,
        dataType: "json",
        processData: false,
        contentType: false,
        type: 'POST',
        async: false,
        success: function(data){
            if('0'==data.msgCode){
                muPaymentRequestHistoryId = data.muPaymentRequestHistoryId;
            }
            else if(data.msgCode=='-1'){
                modalEvent.warning("조회 오류", data.msgDesc);
            }
            else{
                modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
            }
        },
        error : function(xhr, status, error) {
            modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
        },
        beforeSend:function(){
            $(".loading-image-layer").show();
        },
        complete:function(){

        }
    });
    return muPaymentRequestHistoryId;
}

/****************************************************************************
 * 단말기 결제응답 데이터 저장
 ****************************************************************************/
function fn_saveResponseData(id,param){
    let formData = new FormData();

    let muPaymentResponseHistoryId = '';

    let muUserId = reservePaymentInsertModal.reqParam.muUserId;
    let userName = $('#reservePaymentInsertModal .modalUserName').text();

    if('I1'===param.transactionType){
        formData.append('installmentMonths',param.paymentOptionCode);
        formData.append('cardNumber',param.cardNumber);
    }else if('B1'===param.transactionType){
        formData.append('cashReceiptPurpose',param.paymentOptionCode);
        formData.append('cashReceiptInfo',param.cardNumber);
    }
    formData.append('menuClass',menuClass);
    formData.append('muPaymentRequestHistoryId',id);
    formData.append('muUserId',muUserId);
    formData.append('userName',userName);
    formData.append('transactionType',param.transactionType);
    formData.append('responseCode',param.responseCode);
    formData.append('terminalId',param.terminalId);
    formData.append('WCC',param.WCC);
    formData.append('totalAmount',param.totalAmount);
    formData.append('serviceFee',param.serviceFee);
    formData.append('vatAmount',param.vatAmount);
    formData.append('approvalNo',param.approvalNo);
    formData.append('approvalDate',param.approvalDate);
    formData.append('issuerCode',param.issuerCode);
    formData.append('issuerName',param.issuerName);
    formData.append('merchantCode',param.merchantCode);
    formData.append('acquirerCode',param.acquirerCode);
    formData.append('acquirerName',param.acquirerName);
    formData.append('posTransactionNumber',param.posTransactionNumber);
    formData.append('dscType',param.dscType);

    $.ajax({
        url: encodeURI('/webpayment/insertPaymentResponseHistory.do'),
        data: formData,
        dataType: "json",
        processData: false,
        contentType: false,
        type: 'POST',
        async: false,
        success: function(data){
            if('0'==data.msgCode){
                muPaymentResponseHistoryId = data.muPaymentResponseHistoryId;
            }
            else if(data.msgCode=='-1'){
                modalEvent.warning("조회 오류", data.msgDesc);
            }
            else{
                modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
            }
        },
        error : function(xhr, status, error) {
            modalEvent.danger("조회 오류", "조회 중 오류가 발생하였습니다. 잠시후 다시시도하십시오.");
        },
        beforeSend:function(){

        },
        complete:function(){
            if(completeFlag){
                $(".loading-image-layer").hide();
            }else{
                // modalEvent.success("", "다음 결제 건을 처리해주세요.");
                $(".loading-image-layer").hide();
            }
        }
    });
    return muPaymentResponseHistoryId;
}