/**
 * 통합 진료유형 관리 (medicalCategoryList.js)
 * - medical_divi_list 테이블 기반
 * - Depth 1(진료과목 select) → Depth 2/3/4/5 (Tabulator 그리드)
 */
$(document).ready(function () {
    let globalTreeData = [];
    let nodeMap = {};
    let table2 = null;
    let table3 = null;
    let table4 = null;
    let table5 = null;
    let tableOverview = null;
    let overviewInitialized = false;

    function initGrid() {
        // 커스텀 컨텍스트 메뉴 요소 생성 및 이벤트 바인딩
        if ($('#customContextMenu').length === 0) {
            $('body').append(
                '<div id="customContextMenu" class="custom-context-menu">' +
                '  <ul>' +
                '    <li class="delete">삭제</li>' +
                '  </ul>' +
                '</div>'
            );

            // 메뉴 밖 클릭 시 커스텀 메뉴 닫기
            $(document).on('click', function (e) {
                if (!$(e.target).closest('#customContextMenu').length) {
                    $('#customContextMenu').hide();
                }
            });

            // 메뉴 [삭제] 클릭 이벤트 - 멀티셀렉트 지원
            $(document).on('click', '#customContextMenu .delete', function () {
                var menu = $('#customContextMenu');
                menu.hide();

                if (!window.currentContextRow) return;

                var contextTable = window.currentContextRow.getTable();
                var contextData = window.currentContextRow.getData();
                var selectedRows = contextTable.getSelectedRows();

                // 우클릭한 행이 선택된 행 목록에 포함되어 있는지 확인
                var isContextRowSelected = selectedRows.some(function (r) {
                    return r.getData().pid === contextData.pid;
                });

                var targetRows;
                if (isContextRowSelected && selectedRows.length > 1) {
                    // 멀티 선택 상태에서 선택된 행 중 하나를 우클릭한 경우 → 전체 선택 삭제
                    targetRows = selectedRows;
                } else {
                    // 단일 행 또는 선택되지 않은 행을 우클릭한 경우 → 해당 행만 삭제
                    targetRows = [window.currentContextRow];
                }

                var pidList = targetRows.map(function (r) { return r.getData().pid; });
                var nameList = targetRows.map(function (r) { return r.getData().divi_name; });

                var confirmMsg;
                if (pidList.length === 1) {
                    confirmMsg = "'" + nameList[0] + "' 항목을 삭제하시겠습니까?\n하위 항목이 있을 경우 삭제되지 않습니다.";
                } else {
                    confirmMsg = pidList.length + "개 항목을 삭제하시겠습니까?\n(" + nameList.join(', ') + ")\n하위 항목이 있는 경우 해당 항목은 건너뜁니다.";
                }

                if (!confirm(confirmMsg)) return;

                if (pidList.length === 1) {
                    // 단건 삭제 - 기존 API 사용
                    $.ajax({
                        url: '/settings/medicalCategory/delMedicalCategory.do',
                        type: 'POST',
                        data: { pid: pidList[0] },
                        success: function (res) {
                            alert(res.msgDesc);
                            if (res.msgCode === '0') {
                                loadData(true);
                            }
                        },
                        error: function () {
                            alert("삭제 중 오류가 발생했습니다.");
                        }
                    });
                } else {
                    // 멀티 삭제
                    $.ajax({
                        url: '/settings/medicalCategory/delMultiMedicalCategory.do',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify({ pidList: pidList }),
                        success: function (res) {
                            alert(res.msgDesc);
                            if (res.msgCode === '0') {
                                loadData(true);
                            }
                        },
                        error: function () {
                            alert("삭제 중 오류가 발생했습니다.");
                        }
                    });
                }
            });
        }

        // Tabulator rowContext 이벤트(우클릭) 공통 핸들러
        function onRowContextMenu(e, row) {
            e.preventDefault();
            var data = row.getData();
            window.currentContextRow = row; // 행 삭제를 위해 캐싱

            $('#customContextMenu')
                .data('pid', data.pid)
                .data('name', data.divi_name)
                .css({
                    top: e.pageY + 'px',
                    left: e.pageX + 'px'
                })
                .show();
        }

        let commonOpts = {
            index: "pid",
            layout: "fitColumns",
            placeholder: "상위 항목을 선택하세요.",
            selectableRows: true, // 5.x 에서 선택 기능 활성화
            selectableRowsRangeMode: "click", // 브라우저/그리드 자체 단축키 동작을 막고 순수 클릭 이벤트로 동작하게 함
            height: "100%",
            columnDefaults: {
                headerTooltip: true,
                headerHozAlign: "center"
            }
        };

        // Depth 2 Grid - 순번, 명칭, 순서, 하위
        table2 = new Tabulator("#gridDepth2", Object.assign({}, commonOpts, {
            columns: [
                { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
                { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
                { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" },
                { title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 2); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 3, d.divi_name); } }
            ],
            placeholder: "진료유형을 선택하세요."
        }));

        // Depth 3 Grid (제품) - 순번, 명칭, 거래처, 담당자(연락처), 단가, 순서, 하위
        table3 = new Tabulator("#gridDepth3", Object.assign({}, commonOpts, {
            columns: [
                { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
                { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
                { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" },
                { title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 3); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 4, d.divi_name); } }
            ],
            placeholder: "진료유형을 선택하세요."
        }));

        // Depth 4 Grid (용량/출력) - 순번, 명칭, 단가, 할인가, 순서, 하위
        table4 = new Tabulator("#gridDepth4", Object.assign({}, commonOpts, {
            columns: [
                { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
                { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
                { title: "단가", field: "kind_cost", width: 80, hozAlign: "right", formatter: costFormatter },
                { title: "할인가", field: "dc_cost", width: 80, hozAlign: "right", formatter: costFormatter },
                { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" },
                { title: "하위", width: 50, hozAlign: "center", headerSort: false, formatter: function (c) { return addDescendantFormatter(c, 4); }, cellClick: function (e, cell) { e.stopPropagation(); var d = cell.getRow().getData(); addChildCategory(d.pid, 5, d.divi_name); } }
            ],
            placeholder: "제품/시술을 선택하세요."
        }));

        // Depth 5 Grid (부위) - 순번, 명칭, 순서 (최하위, 하위 없음)
        table5 = new Tabulator("#gridDepth5", Object.assign({}, commonOpts, {
            columns: [
                { title: "순번", formatter: "rownum", width: 38, hozAlign: "center", headerSort: false, cssClass: "col-sm" },
                { title: "명칭", field: "divi_name", formatter: categoryNameFormatter, tooltip: true },
                { title: "순서", field: "divi_sort", width: 38, hozAlign: "center", cssClass: "col-sm" }
            ],
            placeholder: "용량을 선택하세요."
        }));

        // Shift+Click 범위 선택을 위한 마지막 클릭 행 추적
        var lastClickedRow = {};

        function handleRowClick(e, row, table, depth) {
            var tableId = table.element.id;

            if (e.shiftKey || e.ctrlKey || e.metaKey) {
                // [MULTI-SELECT MODE]
                // Shift+Click 또는 Ctrl+Click: 
                // Tabulator 자체 옵션(selectableRows: true)에 의해 다중 선택/토글이 자동으로 처리됩니다.
                // 여러 줄이 동시 선택되어도 하위 뎁스 표(자식 그리드)에 여러 부모의 데이터를 보여줄 구조가 아니므로,
                // 하위 표를 갱신하는 clickRow()를 호출하지 않고 여기서 함수를 완전히 종료합니다.
                lastClickedRow[tableId] = row;
                return;
            }

            // [SINGLE-SELECT / NAVIGATION MODE]
            // 일반 클릭: 해당 항목으로 "내비게이션(이동)"하려는 의도.
            // 1) 내가 클릭한 행이 이미 선택되어 있는 상태라면 Tabulator가 클릭하면서 선택을 해제(토글)해버리는 것을 방지.
            // 2) 다른 행들의 선택을 모두 해제하고, 내가 누른 행 1개만 확실히 선택되도록 강제합니다.
            table.deselectRow();
            window.setTimeout(function () {
                row.select();
            }, 0);

            // 3) 마지막 활성 행 갱신
            lastClickedRow[tableId] = row;

            // 4) 자식 항목들을 불러와 다음 뎁스의 표에 뿌려줍니다.
            clickRow(row, depth);
        }

        table2.on("rowClick", function (e, row) { handleRowClick(e, row, table2, 2); });
        table3.on("rowClick", function (e, row) { handleRowClick(e, row, table3, 3); });
        table4.on("rowClick", function (e, row) { handleRowClick(e, row, table4, 4); });
        table5.on("rowClick", function (e, row) { handleRowClick(e, row, table5, 5); });


        function onCellDblClick(e, cell) {
            if (cell.getField() === "divi_name") {
                var data = cell.getRow().getData();
                editCategory(data.pid, data.divi_dept);
            }
        }
        table2.on("cellDblClick", onCellDblClick);
        table3.on("cellDblClick", onCellDblClick);
        table4.on("cellDblClick", onCellDblClick);
        table5.on("cellDblClick", onCellDblClick);

        table2.on("rowContext", onRowContextMenu);
        table3.on("rowContext", onRowContextMenu);
        table4.on("rowContext", onRowContextMenu);
        table5.on("rowContext", onRowContextMenu);

        window.loadData();
    }

    /* ====== 포맷터 영역 ====== */

    function categoryNameFormatter(cell) {
        var data = cell.getRow().getData();
        var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;';
        var color = data.divi_color || '#333';
        if (data.list_use !== 'y') color = '#aaa';

        var html = '<span style="' + nameStyle + ' color:' + color + '">' + cell.getValue() + '</span>';

        // 면세 표시
        if (data.tax_free === 'y') {
            html += ' <span style="color:#ff0000; font-size:11px;">[면세]</span>';
        }
        return html;
    }

    function costFormatter(cell) {
        var val = cell.getValue();
        if (val && Number(val) > 0) {
            return Number(val).toLocaleString();
        }
        return '';
    }

    function ynFormatter(cell) {
        var val = cell.getValue();
        if (val === 'y') {
            return '<span style="color:#3985EA; font-weight:600;">Y</span>';
        }
        return '<span style="color:#ccc;">N</span>';
    }

    function editFormatter(cell) {
        return '<span class="grid-link-btn grid-link-edit">수정</span>';
    }

    function addDescendantFormatter(cell, depth) {
        return '<span class="grid-link-btn grid-link-add">등록</span>';
    }

    /* ====== 행 클릭 ====== */

    function clickRow(row, depth, currentState) {
        var data = row.getData();
        var children = data._children || [];


        if (depth === 2) {
            table3.setData(children).then(function () {
                if (currentState && currentState.depth3) {
                    table3.selectRow(currentState.depth3);
                    let selectedRows = table3.getSelectedRows();
                    if (selectedRows && selectedRows.length > 0) {
                        clickRow(selectedRows[0], 3, currentState);
                    }
                }
            });
            table4.setData([]);
            table5.setData([]);
            $("#btnArea3").html('<button class="put_btn" onclick="addChildCategory(\'' + data.pid + '\', \'3\', \'' + (data.divi_name || '').replace(/'/g, "\\'") + '\')"><img src="/image/web/notice_btn_icon.svg" alt="추가" style="width:12px; height:12px; margin:0; position:static !important;">추가</button>');
            $("#btnArea4").empty();
            $("#btnArea5").empty();
        } else if (depth === 3) {
            table4.setData(children).then(function () {
                if (currentState && currentState.depth4) {
                    table4.selectRow(currentState.depth4);
                    let selectedRows = table4.getSelectedRows();
                    if (selectedRows && selectedRows.length > 0) {
                        clickRow(selectedRows[0], 4, currentState);
                    }
                }
            });
            table5.setData([]);
            $("#btnArea4").html('<button class="put_btn" onclick="addChildCategory(\'' + data.pid + '\', \'4\', \'' + (data.divi_name || '').replace(/'/g, "\\'") + '\')"><img src="/image/web/notice_btn_icon.svg" alt="추가" style="width:12px; height:12px; margin:0; position:static !important;">추가</button>');
            $("#btnArea5").empty();
        } else if (depth === 4) {
            table5.setData(children).then(function () {
                if (currentState && currentState.depth5) {
                    table5.selectRow(currentState.depth5);
                }
            });
            $("#btnArea5").html('<button class="put_btn" onclick="addChildCategory(\'' + data.pid + '\', \'5\', \'' + (data.divi_name || '').replace(/'/g, "\\'") + '\')"><img src="/image/web/notice_btn_icon.svg" alt="추가" style="width:12px; height:12px; margin:0; position:static !important;">추가</button>');
        }
    }

    /* ====== 트리 구성 ====== */

    function buildNodeMap(nodes) {
        nodes.forEach(node => {
            nodeMap[node.pid] = node;

            // 편집 모드 진입 시 입력창(Input)에 기존 값이 제대로 표시되게 하기 위해
            // 공통 피쳐인 divi_name 값을 각 뎁스별 전용 열 필드에 복사해 둡니다.
            if (node.divi_dept == 2) node.divi_name2 = node.divi_name;
            else if (node.divi_dept == 3) node.divi_name3 = node.divi_name;
            else if (node.divi_dept == 4) node.divi_name4 = node.divi_name;
            else if (node.divi_dept == 5) node.divi_name5 = node.divi_name;

            if (node._children && node._children.length > 0) {
                buildNodeMap(node._children);
            } else if (node._children && node._children.length === 0) {
                delete node._children; // 하위 뎁스가 없어 최하위 node일 경우 트리 확정버튼(+/-)을 숨기기 위해 빈 배열 삭제
            }
        });
    }

    /* ====== 데이터 로드 ====== */

    window.loadData = function (preserveState) {
        let currentState = {};
        if (preserveState) {
            currentState.depth1 = $("#depth1Select").val();
            currentState.depth1Overview = $("#depth1SelectOverview").val();
            let selected2 = table2.getSelectedData()[0];
            let selected3 = table3.getSelectedData()[0];
            let selected4 = table4.getSelectedData()[0];
            let selected5 = table5.getSelectedData()[0];

            if (selected2) currentState.depth2 = selected2.pid;
            if (selected3) currentState.depth3 = selected3.pid;
            if (selected4) currentState.depth4 = selected4.pid;
            if (selected5) currentState.depth5 = selected5.pid;
        }

        $.ajax({
            url: "/settings/medicalCategory/getMedicalCategoryTreeList.do",
            type: "POST",
            data: { storePid: '1' },
            success: function (res) {
                if (res.msgCode === '0') {
                    globalTreeData = res.rows || [];
                    nodeMap = {};
                    buildNodeMap(globalTreeData);
                    renderDepth1Select(globalTreeData, currentState);
                } else {
                    alert(res.msgDesc);
                }
            },
            error: function () {
                alert("데이터 목록을 불러오는데 실패했습니다.");
            }
        });
    };

    function renderDepth1Select(nodes, currentState) {
        let filteredNodes = [];
        if (nodes && nodes.length > 0) {
            const seenNames = new Set();
            for (const node of nodes) {
                const name = node.divi_name ? node.divi_name.trim() : '';
                if (!seenNames.has(name)) {
                    seenNames.add(name);
                    filteredNodes.push(node);
                }
            }
        }

        const optionList = $("#depth1OptionList");
        const labelBtn = $("#depth1SelectBox .label");
        const hiddenInput = $("#depth1Select");
        optionList.empty();

        const optListOverview = $("#depth1OptionListOverview");
        const lblBtnOverview = $("#depth1SelectBoxOverview .label");
        const hdInputOverview = $("#depth1SelectOverview");
        optListOverview.empty();

        if (filteredNodes.length === 0) {
            labelBtn.text('항목 없음');
            hiddenInput.val('');
            lblBtnOverview.text('항목 없음');
            hdInputOverview.val('');

            table2.setData([]);
            table3.setData([]);
            table4.setData([]);
            table5.setData([]);
            $("#btnArea2").empty();
            $("#btnArea3").empty();
            $("#btnArea4").empty();
            $("#btnArea5").empty();

            if (tableOverview) tableOverview.setData([]);
            return;
        }

        filteredNodes.forEach(function (node) {
            var li = $('<li class="option_list_item"></li>');
            var label = $('<label></label>').text(node.divi_name);
            li.append(label);
            li.data('value', node.pid);
            li.on('click', function () {
                hiddenInput.val(node.pid);
                labelBtn.text(node.divi_name);
                window.onChangeDepth1();
            });
            optionList.append(li);

            var liOver = $('<li class="option_list_item"></li>');
            var labelOver = $('<label></label>').text(node.divi_name);
            liOver.append(labelOver);
            liOver.data('value', node.pid);
            liOver.on('click', function () {
                hdInputOverview.val(node.pid);
                lblBtnOverview.text(node.divi_name);
                window.onChangeDepth1Overview();
            });
            optListOverview.append(liOver);
        });

        // 선택 상태 복원
        let targetPid = filteredNodes[0].pid;
        let targetName = filteredNodes[0].divi_name;

        let targetPidOverview = filteredNodes[0].pid;
        let targetNameOverview = filteredNodes[0].divi_name;

        if (currentState && currentState.depth1) {
            let matched = filteredNodes.find(n => n.pid == currentState.depth1);
            if (matched) {
                targetPid = matched.pid;
                targetName = matched.divi_name;
            }
        }

        if (currentState && currentState.depth1Overview) {
            let matched = filteredNodes.find(n => n.pid == currentState.depth1Overview);
            if (matched) {
                targetPidOverview = matched.pid;
                targetNameOverview = matched.divi_name;
            }
        }

        hiddenInput.val(targetPid);
        labelBtn.text(targetName);
        window.onChangeDepth1(currentState);

        hdInputOverview.val(targetPidOverview);
        lblBtnOverview.text(targetNameOverview);

        if (overviewInitialized) {
            window.onChangeDepth1Overview();
        }
    }

    window.onChangeDepth1Overview = function () {
        const selectedPid = $("#depth1SelectOverview").val();
        if (!selectedPid) {
            if (tableOverview) tableOverview.setData([]);
            return;
        }

        const pid = parseInt(selectedPid);
        const node = nodeMap[pid];

        if (tableOverview && node) {
            tableOverview.setData([node]);
        } else if (tableOverview) {
            tableOverview.setData([]);
        }
    };

    window.onChangeDepth1 = function (currentState) {
        const selectedPid = $("#depth1Select").val();
        if (!selectedPid) {
            table2.setData([]);
            table3.setData([]);
            table4.setData([]);
            table5.setData([]);
            $("#btnArea2").empty();
            $("#btnArea3").empty();
            $("#btnArea4").empty();
            $("#btnArea5").empty();
            return;
        }

        const pid = parseInt(selectedPid);
        const node = nodeMap[pid];

        table3.setData([]);
        table4.setData([]);
        table5.setData([]);
        $("#btnArea3").empty();
        $("#btnArea4").empty();
        $("#btnArea5").empty();

        if (node && node._children) {
            table2.setData(node._children).then(function () {
                if (currentState && currentState.depth2) {
                    table2.selectRow(currentState.depth2);
                    let selectedRows = table2.getSelectedRows();
                    if (selectedRows && selectedRows.length > 0) {
                        clickRow(selectedRows[0], 2, currentState);
                    }
                }
            });
            $("#btnArea2").html('<button class="put_btn" style="padding:2px 8px; font-size:12px; height:26px;" onclick="addChildCategory(\'' + node.pid + '\', \'2\', \'' + (node.divi_name || '').replace(/'/g, "\\'") + '\')"><img src="/image/web/notice_btn_icon.svg" alt="추가" style="width:12px; height:12px; margin:0; position:static !important;">추가</button>');
        } else {
            table2.setData([]);
            $("#btnArea2").empty();
        }
    };

    /* ====== 팝업 관련 ====== */

    window.editDepth1 = function () {
        const pid = $("#depth1Select").val();
        if (!pid) {
            alert("수정할 진료과목을 선택하세요.");
            return;
        }
        editCategory(pid, 1);
    };

    window.editCategory = function (pid, diviDept) {
        openInfoPopup('edit', pid, diviDept);
    };

    window.addChildCategory = function (diviParent, diviDept, parentName) {
        openInfoPopup('add', '', diviDept, diviParent, (parentName || '').replace(/'/g, "\\'"));
    };

    window.delCategory = function (pid) {
        if (!confirm("해당 카테고리를 삭제하시겠습니까?\n하위 항목이 있을 경우 삭제되지 않습니다.")) return;

        $.ajax({
            url: "/settings/medicalCategory/delMedicalCategory.do",
            type: "POST",
            data: { pid: pid },
            success: function (res) {
                alert(res.msgDesc);
                if (res.msgCode === '0') {
                    loadData(true);
                }
            },
            error: function () {
                alert("삭제 통신 중 오류가 발생했습니다.");
            }
        });
    };

    function openInfoPopup(mode, pid, diviDept, diviParent, parentName) {
        pid = pid || '';
        diviDept = diviDept || '';
        diviParent = diviParent || '';
        parentName = parentName || '';

        // 뎁스별 분리된 URL 호출
        let endpoint = 'infoPopDept' + diviDept + '.do';
        if (!diviDept) {
            // 예외 적인 fallback
            endpoint = 'infoPopDept2.do';
            diviDept = 2;
        }

        const url = '/settings/medicalCategory/' + endpoint + '?mode=' + mode + '&pid=' + pid + '&diviDept=' + diviDept + '&diviParent=' + diviParent + '&parentName=' + encodeURIComponent(parentName);

        let width = 600;
        let height = 300; // Depth 2, 3, 5는 기본 300px

        if (diviDept == 4) {
            width = 780;   // 약품 관리 그리드 포함으로 넓힘
            height = 700;  // Depth 4 (용량/출력 + 약품 관리)
        }

        let left = (screen.width - width) / 2;
        let top = (screen.height - height) / 2;

        window.open(url, "MedicalCategoryInfoPopup_" + diviDept, "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes");
    }

    initGrid();

    /* ====== 전체보기 탭 ====== */

    // 탭 전환 이벤트
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var target = $(e.target).attr('href');
        if (target === '#tabOverview') {
            if (!overviewInitialized) {
                initOverviewGrid(function () {
                    window.onChangeDepth1Overview();
                });
                overviewInitialized = true;
            } else {
                window.onChangeDepth1Overview();
            }
        }
    });

    function initOverviewGrid(callback) {
        tableOverview = new Tabulator("#gridOverview", {
            editTriggerEvent: "dblclick",
            dataTree: true,
            dataTreeElementColumn: "divi_name",
            dataTreeStartExpanded: true,
            dataTreeChildIndent: 0,
            layout: "fitColumns",
            placeholder: "데이터를 불러오는 중...",
            height: "100%",
            columnDefaults: {
                headerTooltip: true,
                headerHozAlign: "center",
                tooltip: true,
                headerSort: false
            },
            columns: [
                { title: "진료과목", field: "divi_name", width: "6%", hozAlign: "left", formatter: overviewDepthFormatter(1), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 1; }, cellClick: handleTreeToggleClick },
                { title: "진료유형", field: "divi_name2", width: "16.25%", hozAlign: "left", formatter: overviewDepthFormatter(2), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 2; }, cellClick: handleTreeToggleClick },
                { title: "제품/시술", field: "divi_name3", width: "17.75%", hozAlign: "left", formatter: overviewDepthFormatter(3), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 3; }, cellClick: handleTreeToggleClick },
                { title: "용량/출력", field: "divi_name4", width: "14.75%", hozAlign: "left", formatter: overviewDepthFormatter(4), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 4; }, cellClick: handleTreeToggleClick },
                { title: "부위", field: "divi_name5", width: "14.75%", hozAlign: "left", formatter: overviewDepthFormatter(5), editor: "input", editable: function (cell) { return cell.getRow().getData().divi_dept == 5; }, cellClick: handleTreeToggleClick },
                { title: "깊이", field: "divi_dept", width: "4%", hozAlign: "center", editor: "number", editorParams: { min: 1, max: 5, step: 1 } },
                { title: "단가", field: "kind_cost", width: "10%", formatter: costFormatter, hozAlign: "right", editor: "number" },
                { title: "할인가", field: "dc_cost", width: "10%", formatter: costFormatter, hozAlign: "right", editor: "number" },
                {
                    title: "단위", field: "kind_unit_nm", width: "8%", hozAlign: "center",
                    formatter: function (cell) {
                        var data = cell.getRow().getData();
                        return data.kind_unit_nm || data.kind_unit || '';
                    }
                },
                { title: "사용여부", field: "list_use", width: "6%", formatter: ynFormatter, hozAlign: "center", editor: "list", editorParams: { values: { "y": "Y", "n": "N" } } },
                { title: "면세여부", field: "tax_free", width: "6%", formatter: ynFormatter, hozAlign: "center", editor: "list", editorParams: { values: { "y": "Y", "n": "N" } } }
            ]
        });

        function handleTreeToggleClick(e, cell) {
            if ($(e.target).closest('.custom-tree-toggle').length > 0 || $(e.target).closest('.tabulator-data-tree-control').length > 0) {
                cell.getRow().treeToggle();
            }
        }

        tableOverview.on("tableBuilt", function () {
            if (typeof callback === 'function') callback();
        });

        // 인라인 편집 후 임시 저장 처리 (일괄 저장)
        tableOverview.on("cellEdited", function (cell) {
            var field = cell.getField();
            var val = (cell.getValue() || "").toString().trim();
            var oldVal = (cell.getOldValue() || "").toString().trim();

            if (val === oldVal) return;

            // 진료과목~부위 빈값 검증
            if (field.startsWith("divi_name")) {
                if (val === "") {
                    alert("항목명은 비워둘 수 없습니다.");
                    cell.restoreOldValue();
                    return;
                }
            }

            // 수정 발생 시 저장/취소 버튼 활성화
            $("#btnSaveOverview, #btnCancelOverview").show();
        });
    }

    // 전체보기 일괄 저장 / 취소 이벤트 바인딩
    $(document).on("click", "#btnSaveOverview", function () {
        var editedCells = tableOverview.getEditedCells();
        if (editedCells.length === 0) {
            alert("수정된 항목이 없습니다.");
            return;
        }

        var updateMap = {};
        editedCells.forEach(function (cell) {
            var data = cell.getRow().getData();
            var pid = data.pid;
            var field = cell.getField();
            var val = (cell.getValue() || "").toString().trim();

            if (!updateMap[pid]) {
                updateMap[pid] = { pid: pid };
            }

            if (field.startsWith("divi_name")) {
                updateMap[pid].diviName = val;
            } else if (field === "divi_dept") {
                updateMap[pid].diviDept = val;
            } else if (field === "kind_cost") {
                updateMap[pid].kindCost = parseFloat(val || 0);
            } else if (field === "kind_sale_cost") {
                updateMap[pid].kindSaleCost = parseFloat(val || 0);
            } else if (field === "kind_unit") {
                updateMap[pid].kindUnit = val;
            } else if (field === "list_use") {
                updateMap[pid].listUse = val;
            } else if (field === "tax_free") {
                updateMap[pid].taxFree = val;
            }
        });

        var updateList = Object.values(updateMap);

        if (!confirm("수정된 " + updateList.length + "건의 항목을 저장하시겠습니까?")) return;

        $.ajax({
            url: '/settings/medicalCategory/updateBatchMedicalCategory.do',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(updateList),
            success: function (res) {
                if (res.msgCode === '0') {
                    alert(res.msgDesc || "저장되었습니다.");
                    $("#btnSaveOverview, #btnCancelOverview").hide();
                    window.onChangeDepth1Overview();
                } else {
                    alert(res.msgDesc);
                }
            },
            error: function () {
                alert("저장 중 오류가 발생했습니다.");
            }
        });
    });

    $(document).on("click", "#btnCancelOverview", function () {
        if (confirm("수정 중인 내용을 취소하시겠습니까? (원래 데이터로 복귀합니다)")) {
            $("#btnSaveOverview, #btnCancelOverview").hide();
            window.loadData(true);
        }
    });

    // 도움말 버튼 토글 (전체보기)
    $(document).on("click", "#btnHelpOverview", function () {
        $("#overviewGuideBox").slideToggle(200);
    });

    // 도움말 버튼 토글 (진료유형 관리)
    $(document).on("click", "#btnHelpManage", function () {
        $("#manageGuideBox").slideToggle(200);
    });

    $(document).on("click", "#btnExpandAll", function () {
        if (tableOverview) {
            tableOverview.getRows().forEach(function (row) {
                row.treeExpand();
            });
        }
    });

    $(document).on("click", "#btnCollapseAll", function () {
        if (tableOverview) {
            tableOverview.getRows().forEach(function (row) {
                row.treeCollapse();
            });
        }
    });

    function overviewDepthFormatter(targetDepth) {
        return function (cell) {
            var data = cell.getRow().getData();
            if (parseInt(data.divi_dept, 10) !== targetDepth) return '';

            var row = cell.getRow();
            var nameStyle = data.list_use === 'y' ? 'font-weight:600;' : 'text-decoration:line-through; color:#aaa;';
            var color = data.divi_color || '#333';
            if (data.list_use !== 'y') color = '#aaa';

            var val = cell.getValue() || data.divi_name || '';
            var html = '<span style="' + nameStyle + ' color:' + color + '">' + val + '</span>';

            if (data.tax_free === 'y') {
                html += ' <span style="color:#ff0000; font-size:11px; margin-left: 5px;">[면세]</span>';
            }
            return html;
        };
    }

    function loadOverviewData() {
        if (globalTreeData.length === 0) {
            window.loadData();
        } else {
            window.onChangeDepth1Overview();
        }
    }

});
