const pagePerRow = 23;
/**
 * Api 호출
 * @param url api url
 * @param method GET, POST, UPDATE...
 * @param data Parameter
 * @param successCallBack CallBack Function
 * @param failCallBack Failed CallBack Function
 * @param table loading table
 */
function callApi(url, method, data, successCallBack, failCallBack, table) {
    const param = method === 'GET' ? data : JSON.stringify(data);
    const loading = $('.' + table + ' .loading');
    if (loading.length) loading.css('display', 'flex');
    $.ajax({
        url,
        method,
        data: param,
        contentType: 'application/json',
        dataType: 'json',
        success : (res)=>{
            if (successCallBack) {
                successCallBack(res);
            }
        },
        error : ({responseJSON})=>{
            if (failCallBack) {
                failCallBack(responseJSON);
            }
            else {
                const {error, message, status, timestamp} = responseJSON;
                let time = timestamp.replace('T', ' ');

                alert(`timestamp : ${time.substr(0,19)}\nstatus : ${status}\nerror : ${error}\nmessage : ${message}`);
            }
        },
        complete : () =>{
            if (loading.length) loading.hide();
        }
    });
}


function padStr(str, number) {
    return str.toString().padStart(number, "0");
}

/**
 * Table Row checkbox change event
 * @param check this
 * @param el table
 */
function checkEvent(check, el) {
    $('.' + el + ' tr.on').removeClass('on');
    $(check).parent().parent().addClass('on');
}


/**
 * 오름 차순, 내림차순 설정
 * @param el
 * @param table
 * @returns {{asc: number, desc: number}}
 */
function getSortType(el, table) {
    if (!$(el).attr('class')) {
        $('.' + table + ' .asc').removeClass('asc');
        $('.' + table + ' .desc').removeClass('desc');
    }
    let addClass = 'asc';
    let removeClass = 'desc';
    if ($(el).hasClass('asc')) {
        addClass = 'desc';
        removeClass = 'asc';
    }
    $(el).removeClass(removeClass);
    $(el).addClass(addClass);
    $('.' + table).addClass('sorting');
    let asc = 1;
    let desc = -1;

    if (addClass === 'asc') {
        asc = -1;
        desc = 1;
    }
    return { asc, desc };
}

/**
 * sort event
 * @param data origin data
 * @param drawCallback draw Table
 * @param el this
 * @param table table
 */
function sortingData(data, drawCallback, el, table) {
    const { asc, desc } = getSortType(el, table);
    if (data && data.length) {
        const column = $(el).attr('id');
        const sortData = [...data];
        sortData.sort(function(a, b) {
            const aIsNumber = typeof a[column] === 'number' || !isNaN(Number(a[column]));
            const bIsNumber = typeof b[column] === 'number' || !isNaN(Number(b[column]));
            if (aIsNumber && !bIsNumber) return asc;          // 숫자 < 문자열
            if (!aIsNumber && bIsNumber) return desc;           // 문자열 > 숫자
            return a[column] > b[column] ? desc : a[column] === b[column] ? 0 : asc;
        });

        drawCallback(sortData);
    }
}

/**
 * 외부연계 sort event
 * @param data origin data
 * @param drawCallback draw Table
 * @param el this
 * @param table table
 */
function processSortingData(data, drawCallback, el, table) {
    const { asc, desc } = getSortType(el, table);
    if (data && data.length) {
        const column = $(el).attr('id');
        const sortData = [...data];
        sortData.sort(function(a, b) {
            let aVal = a[column];
            let bVal = b[column];
            if (column === 'regDate' || column ===  'cnt') {
                aVal = !a.linkHistory ? 0 : a.linkHistory[0][column];
                bVal = !b.linkHistory ? 0 :b.linkHistory[0][column];
            }
            const aIsNumber = typeof aVal === 'number' || !isNaN(Number(aVal));
            const bIsNumber = typeof bVal === 'number' || !isNaN(Number(bVal));
            if (aIsNumber && !bIsNumber) return asc;          // 숫자 < 문자열
            if (!aIsNumber && bIsNumber) return desc;           // 문자열 > 숫자
            return aVal > bVal ? desc : aVal === bVal ? 0 : asc;
        });

        drawCallback(sortData);
    }
}

/**
 * 위아래 드래그 높이 조절
 * @param bar Drag Bar
 * @param container Drag Section
 * @param topHeight Top Position Box Original Height
 * @param bottomHeight Bottom Position Original Box Height
 * @param top Top Box
 * @param bottom Bottom Box
 */
function resizeHeight(bar, container, topHeight, bottomHeight, top, bottom) {
    let isDragging = false;
    bar.addEventListener('dblclick', function() {
        top.style.height = topHeight;
        bottom.style.height = bottomHeight;
    })
    bar.addEventListener('mousedown', function (e) {
        e.preventDefault();
        isDragging = true;
    });

    document.addEventListener('mousemove', function (e) {
        if (!isDragging) return;

        const topTitle = $("." + top.className + " .title");
        const botTitle = $("." + bottom.className + " .title");
        const bottomTab = $("." + bottom.className + " .tab");
        const conEl = $('.' + container);
        let conTop = conEl.offset().top;
        // let conBot = conEl.outerHeight() + conTop - botTitle.outerHeight() - bar.offsetHeight;
        // if (bottomTab.length) conBot -= bottomTab.outerHeight();
        // if (e.clientY > conBot) return;
        const offsetY = e.clientY - conTop;
        const bottomY = offsetY + bar.offsetHeight;
        const wH = window.innerHeight;

        if (offsetY < 30) return;
        if (wH - e.clientY <= 78) return;

        top.style.height = offsetY + 'px';
        bottom.style.height = `calc(100% - ${bottomY}px)`;
    });

    document.addEventListener('mouseup', function () {
        isDragging = false;
    });
}

/**
 * 좌우 드래그 가로 조절
 * @param bar Drag Bar
 * @param container Drag Section
 * @param leftWidth Left Position Box Original Width
 * @param rightWidth Right Position Original Box Width
 * @param left Left Box
 * @param right Right Box
 */
function resizeWidth(bar, container, leftWidth, rightWidth, left, right) {
    let isDragging = false;

    bar.addEventListener('dblclick', function () {
        left.style.width = leftWidth;
        right.style.width = rightWidth;
    });

    bar.addEventListener('mousedown', function (e) {
        e.preventDefault();
        isDragging = true;
    });

    document.addEventListener('mousemove', function (e) {
        if (!isDragging) return;

        const containerElem = document.querySelector('.' + container);
        const containerLeft = containerElem.getBoundingClientRect().left;
        const containerRight = containerElem.getBoundingClientRect().right;

        const offsetX = e.clientX - containerLeft;
        if (offsetX < 0) return;
        if (offsetX > containerRight - 8) return;
        left.style.width = offsetX + 'px';
        right.style.width = `calc(100% - ${offsetX + bar.offsetWidth}px)`;
    });

    document.addEventListener('mouseup', function () {
        isDragging = false;
    });
}

/**
 * make pagination number
 * @param isBefore 첫 페이지가 1보다 큰지
 * @param isNext 전체 페이지가 마지막 페이지보다 큰지
 * @param start 현재 페이지의 start
 * @param end 현재 페이지의 end
 * @param active 클릭 페이지
 * @param callBack CallBack Function
 */
function makePageStr(isBefore, isNext, start, end, active, callBack) {
    let str = `<div class="prev ${isBefore ? '' : 'unactive'}" data-role="prev">«</div>`;

    for (let ii = start; ii <= end; ii++) {
        str += `<div class="page ${active === ii ? 'active' : ''}" data-page="${ii}">${ii}</div>`;
    }
    str += `<div class="next ${isNext ? '' : 'unactive'}" data-role="next">»</div>`;

    const $pagination = $('.pagination');
    $pagination.html(str);

    $pagination.off('click').on('click', 'div', function() {
        const $el = $(this);

        if ($el.hasClass('unactive')) return; // 비활성 클릭 무시

        if ($el.data('role') === 'prev') {
            beforePage(this, callBack);
        }
        else if ($el.data('role') === 'next') {
            nextPage(this, callBack);
        }
        else if ($el.hasClass('page')) {
            showPage(this, callBack);
        }
    });

    $pagination.find('.active').each(function() {
        showPage(this, callBack);
    });
}

/**
 * 현재 페이지
 * @param el
 * @param callBack
 */
function showPage(el, callBack) {
    // 1. active 클래스 처리
    $('.active').removeClass('active');
    $(el).addClass('active');

    // 2. 페이지 번호와 범위 계산
    const page = Number($(el).text());
    const start = (page - 1) * pagePerRow;
    const end = Math.min(start + pagePerRow, _searchedData.length);

    // 3. 해당 페이지 데이터 추출
    const pageData = _searchedData.slice(start, end);

    // 4. 콜백 호출
    callBack(pageData);

}

/**
 * 앞으로 이동
 * @param el this
 * @param callBack CallBack Function
 */
function beforePage(el, callBack) {
    const $prev = $(el);

    // // 버튼 비활성화면 종료
    // if ($prev.hasClass('unactive')) return;

    const firstPage = Number($prev.next().text());
    const start = firstPage - 10;
    const end = firstPage - 1;
    const hasPrevGroup = firstPage !== 11;

    makePageStr(hasPrevGroup, true, start, end, end, callBack);
}

/**
 * 다음으로 이동
 * @param el this
 * @param callBack CallBack Function
 */
function nextPage(el, callBack) {
    const $next = $(el);

    // 버튼 비활성화면 종료
    // if ($next.hasClass('unactive')) return;

    // 이전 페이지 번호 가져오기
    const prevPageNum = Number($next.prev().text());

    // 다음 그룹 시작/끝 페이지 계산
    const lastPage = getLastPage();
    const startPage = prevPageNum + 1;
    let endPage = prevPageNum + 10;
    endPage = Math.min(endPage, lastPage);

    const hasNextGroup = lastPage > endPage;

    makePageStr(true, hasNextGroup, startPage, endPage, startPage, callBack);
}

/**
 * 마지막 페이지 값
 * @returns {number|number}
 */
function getLastPage() {
    return Math.ceil(_searchedData.length / pagePerRow) || 1;
}
