<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- Main body -->
<div class="main_body">
    <section id="section8" class="main_bars">
        <div class="bgs-main">
            <section id="section5">
                <div class="sub_title"></div>
            </section>
        </div>
    </section>

    <div class="contants_body">
        <div class="gs_b_top">
            <ul class="lef">
                <li class="th">검색어</li>
                <li><input type="text" id="masterSearchKeyword" name="searchKeyword" class="input" placeholder="코드그룹ID/코드그룹명" style="width: 150px;"/></li>
                <li class="th">사용여부</li>
                <li>
                    <select id="masterSearchUseYn" name="searchUseYn" class="input">
                        <option value="">전체</option>
                        <option value="Y">사용</option>
                        <option value="N">미사용</option>
                    </select>
                </li>
                <li>
                    <button type="button" id="master_search_btn" class="newbtnss bg1">검색</button>
                </li>
            </ul>
            <ul class="rig2">
                <li>
                    <select id="masterPerPageSelect" class="input">
                        <option value="10">페이지당 10</option>
                        <option value="20">페이지당 20</option>
                    </select>
                    <span class="page_number"><span id="masterCurrentPage"></span><span class="bar">/</span><span id="masterTotalPages">1</span> Pages</span>
                </li>
            </ul>
        </div>

        <!-- 상단 영역 (그룹코드 관리) -->
        <div class="gs_booking">
            <div class="row">
                <div class="col-sm-12">
                    <div class="box_column">
                        <ul class="box_title">
                            <li class="tit">그룹 코드</li>
                            <li class="rig">
                                <button type="button" id="addMasterBtn" class="newbtn bg1">행 추가</button>
                                <button type="button" id="deleteMasterBtn" class="newbtn bg2">삭제</button>
                                <button type="button" id="cancelMasterBtn" class="newbtn bg3">취소</button>
                                <button type="button" id="saveMasterBtn" class="newbtn bg4">저장</button>
                            </li>
                        </ul>
                        <div class="containers">
                            <div id="masterGrid"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- //상단 영역 (그룹코드 관리) -->

        <!-- 하단 영역 (상세그룹 코드 관리) -->
        <div class="gs_booking" style="margin-top: 30px;">
            <div class="row">
                <div class="col-sm-12">
                    <div class="box_column">
                        <ul class="box_title">
                            <li class="tit">상세 코드</li>
                            <li class="rig">
                                <button type="button" id="addDetailBtn" class="newbtn bg1" style="display: none;">행 추가</button>
                                <button type="button" id="deleteDetailBtn" class="newbtn bg2" style="display: none;">삭제</button>
                                <button type="button" id="cancelDetailBtn" class="newbtn bg3" style="display: none;">취소</button>
                                <button type="button" id="saveDetailBtn" class="newbtn bg4" style="display: none;">저장</button>
                            </li>
                        </ul>
                        <div class="containers">
                            <div id="detailGrid"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- //하단 영역 (상세그룹 코드 관리) -->

    </div>

</div>
<!-- /Main body -->

<script type="text/javascript">
/**
 * 코드 통합 관리 모듈
 * 코드 마스터와 코드 상세를 한 화면에서 관리하는 기능을 제공합니다.
 * 
 * 주요 기능:
 * 1. 그룹코드 목록 조회 및 검색 (상단 그리드)
 * 2. 그룹코드 등록/수정/삭제 (상단 그리드)
 * 3. 상세코드 목록 조회 및 검색 (하단 그리드)
 * 4. 상세코드 등록/수정/삭제 (하단 그리드)
 */
(function(window, $) {
    'use strict';

    var SEARCH_COND = {};

    // 검색정보 셋팅
    var setSearchCond = function() {
        var masterSearchKeyword = $.trim(nvl($("#masterSearchKeyword").val(), ""));
        var masterSearchUseYn = $.trim(nvl($("#masterSearchUseYn").val(), ""));
        var detailSearchKeyword = $.trim(nvl($("#detailSearchKeyword").val(), ""));
        var detailSearchUseYn = $.trim(nvl($("#detailSearchUseYn").val(), ""));

        SEARCH_COND.masterSearchKeyword = masterSearchKeyword;
        SEARCH_COND.masterSearchUseYn = masterSearchUseYn;
        SEARCH_COND.detailSearchKeyword = detailSearchKeyword;
        SEARCH_COND.detailSearchUseYn = detailSearchUseYn;
    };

    /**
     * 코드 통합 관리 네임스페이스
     */
    var CodeIntegratedManage = {
        /**
         * 현재 선택된 코드 그룹 ID
         */
        selectCdGroupId: '',

        /**
         * 현재 선택된 코드 그룹명
         */
        selectedCdGroupNm: '',

        /**
         * 그룹코드 그리드 관련 객체
         */
        masterGrid: {
            /**
             * 그리드 인스턴스
             */
            instance: null,

            /**
             * 그리드 설정 초기화
             * @returns {Object} 그리드 설정 객체
             */
            initConfig: function() {
                // 데이터 소스 설정
                var dataSource = this.createDataSource();

                // 현재 선택된 perPage 값 가져오기
                var perPage = parseInt($('#masterPerPageSelect').val() || 10, 10);

                // 그리드 설정 객체 생성
                var gridConfig = new XitTuiGridConfig();

                // 기본 설정
                gridConfig.setOptDataSource(dataSource);            // 데이터소스 연결
                gridConfig.setOptGridId('masterGrid');              // 그리드를 출력할 Element ID
                gridConfig.setOptGridHeight(390);                   // 그리드 높이(단위: px)
                gridConfig.setOptRowHeight(30);                     // 그리드 행 높이(단위: px)
                gridConfig.setOptRowHeaderType('checkbox');         // 행 첫번째 셀 타입(rowNum: 순번, checkbox: 체크박스, '': 출력 안함)

                // 페이징 옵션 설정
                gridConfig.setOptPageOptions({
                    useClient: false,                               // 클라이언트 페이징 여부(false: 서버 페이징)
                    perPage: perPage                                // 페이지당 표시 건수
                });
                gridConfig.setOptUseClientSort(false);              // 서버사이드 정렬 false

                gridConfig.setOptColumns(this.getGridColumns());

                return gridConfig;
            },

            /**
             * 컬럼 정의
             * @returns {Array} 컬럼 정의 배열
             */
            getGridColumns: function() {
                return [
                    {
                        header: '코드그룹ID',
                        name: 'cdGroupId',
                        width: 250,
                        sortable: true,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '코드그룹명',
                        name: 'cdGroupNm',
                        width: 250,
                        sortable: true,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '코드그룹설명',
                        name: 'cdGroupDc',
                        sortable: false,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '사용여부',
                        name: 'useYn',
                        width: 120,
                        align: 'center',
                        editor: {
                            type: 'select',
                            options: {
                                listItems: [
                                    {text: '사용', value: 'Y'},
                                    {text: '미사용', value: 'N'}
                                ]
                            }
                        },
                        formatter: function(props) {
                            return props.value === 'Y' ? '사용' : '미사용';
                        }
                    },
                    {
                        header: '등록일시',
                        name: 'regDttm',
                        width: 150,
                        align: 'center'
                    }
                ];
            },

            /**
             * 데이터 소스 생성
             * @returns {Object} 데이터 소스 객체
             */
            createDataSource: function() {
                return {
                    api: {
                        readData: {
                            url: '<c:url value="/system/code/group/list.ajax"/>',
                            method: 'POST',
                            contentType: 'application/x-www-form-urlencoded',
                            processData: true
                        }
                    },
                    initialRequest: true,                           // 초기 데이터 요청 여부
                    serializer: function(params) {
                        // 기본 파라미터 (페이지 정보 등)
                        var defaultParams = $.param(params);
                        // 검색 폼 데이터
                        setSearchCond();
                        var searchParams = $.param({
                            searchKeyword: SEARCH_COND.masterSearchKeyword,
                            searchUseYn: SEARCH_COND.masterSearchUseYn
                        });
                        // 모든 파라미터 조합
                        return defaultParams + '&' + searchParams;
                    }
                };
            },

            /**
             * 그리드 인스턴스 생성
             */
            create: function() {
                var gridConfig = this.initConfig();
                var Grid = tui.Grid;
                this.instance = gridConfig.instance(Grid);

                // 그리드 테마 설정
                Grid.applyTheme('striped');

                // 그리드 이벤트 바인딩
                this.bindEvents();
            },

            /**
             * 그리드 이벤트 바인딩
             */
            bindEvents: function() {
                var self = this;
                var parent = CodeIntegratedManage;

                // 요청 성공 시 총 건수 표시
                this.instance.on('successResponse', function(ev) {
                    var responseObj = JSON.parse(ev.xhr.response);
                    if (responseObj.data && responseObj.data.pagination) {
                        $("#masterCurrentPage").text(responseObj.data.pagination.page);
                        $("#masterTotalPages").text(responseObj.data.pagination.totalPages);
                    }
                    //하단 그리드 초기화
                    CodeIntegratedManage.selectCdGroupId = '';
                    CodeIntegratedManage.detailGrid.instance.readData(1);
                });

                // 행 클릭 이벤트
                this.instance.on('click', function(ev) {
                    if (ev.rowKey === undefined) return;

                    var rowData = self.instance.getRow(ev.rowKey);
                    if (!rowData) return;

                    // 선택된 코드 그룹 ID 저장
                    parent.selectCdGroupId = rowData.cdGroupId;
                    parent.selectedCdGroupNm = rowData.cdGroupNm;

                    // 상세코드 그리드 업데이트
                    parent.detailGrid.instance.readData(1);
                    // 상세코드 버튼 표시
                    $('#addDetailBtn, #deleteDetailBtn, #cancelDetailBtn, #saveDetailBtn').show();
                });

                // 셀 편집 시작 전 이벤트
                this.instance.on('editingStart', function(ev) {
                    var { rowKey, columnName } = ev;
                    // 행 데이터 가져오기
                    var rowData = self.instance.getRow(rowKey);
                    // 기존 행인지 확인 (regDt가 있으면 기존 행)
                    if (columnName === "cdGroupId" && rowData.regDttm) {
                        // 기존 행의 cdGroupId는 편집 불가
                        alert('기존 코드그룹의 ID는 수정할 수 없습니다.');
                        ev.stop(); // 편집 취소
                    }
                });
            },

            /**
             * 새 행 추가
             */
            addRow: function() {
                // 새 행 추가
                this.instance.appendRow({
                    cdGroupId: '',
                    cdGroupNm: '',
                    cdGroupDc: '',
                    useYn: 'Y',
                    regDttm: null
                }, {
                    focus: true       // 새 행에 포커스 설정
                });
                // 첫 번째 셀(cdGroupId)로 에디터 포커스 이동
                var rowKey = this.instance.getRowCount() - 1;
                this.instance.startEditing(rowKey, 'cdGroupId');
            },

            /**
             * 선택된 행 삭제
             */
            deleteSelectedRows: function() {
                var checkedRows = this.instance.getCheckedRows();
                if (checkedRows.length === 0) {
                    alert('삭제할 그룹코드를 선택해주세요.');
                    return;
                }

                if (confirm('선택한 그룹코드를 삭제하시겠습니까?')) {
                    // 선택된 행의 rowKey 배열 생성
                    var rowKeys = checkedRows.map(function(row) {
                        return row.rowKey;
                    });

                    // 여러 행 삭제 (rowKey 배열을 이용)
                    rowKeys.forEach(function(rowKey) {
                        this.instance.removeRow(rowKey);
                    }.bind(this));
                }
            },

            /**
             * 그리드 변경사항 취소
             */
            cancelChanges: function() {
                var modifiedRows = this.instance.getModifiedRows();

                // 변경된 데이터가 없으면 알림
                if (modifiedRows.createdRows.length === 0 &&
                    modifiedRows.updatedRows.length === 0 &&
                    modifiedRows.deletedRows.length === 0) {
                    alert('취소할 변경사항이 없습니다.');
                    return;
                }

                // 취소 확인
                if (confirm('모든 변경사항을 취소하시겠습니까?')) {
                    // 현재 페이지 저장
                    var currentPage = this.instance.getPagination().getCurrentPage();

                    // 그리드 데이터를 다시 로드하여 모든 변경사항 취소
                    this.instance.readData(currentPage);

                    //alert('변경사항이 취소되었습니다.');
                }
            },

            /**
             * 그리드 데이터 유효성 검증
             * @param {Object} modifiedRows 변경된 행 데이터
             * @returns {boolean} 유효성 검증 결과
             */
            validateData: function(modifiedRows) {
                var validRows = [].concat(
                    modifiedRows.createdRows || [],
                    modifiedRows.updatedRows || []
                );

                // 필수 입력 필드
                var requiredFields = ['cdGroupId', 'cdGroupNm', 'useYn'];

                // 최대 길이 제한
                var maxLengths = {
                    cdGroupId: 20,
                    cdGroupNm: 100,
                    cdGroupDc: 200
                };

                // 정규식 패턴
                var patterns = {
                    cdGroupId: /^[A-Za-z0-9_]*$/
                };

                for (var i = 0; i < validRows.length; i++) {
                    var row = validRows[i];

                    // 필수 입력 검증
                    for (var j = 0; j < requiredFields.length; j++) {
                        var field = requiredFields[j];
                        if (!row[field]) {
                            var columnInfo = this.getGridColumns().find(function(col) {
                                return col.name === field;
                            });
                            alert(columnInfo.header + '은(는) 필수 입력 항목입니다.');
                            return false;
                        }
                    }

                    // 최대 길이 검증
                    for (var field in maxLengths) {
                        if (row[field] && row[field].toString().length > maxLengths[field]) {
                            var columnInfo = this.getGridColumns().find(function(col) {
                                return col.name === field;
                            });
                            alert(columnInfo.header + '은(는) 최대 ' + maxLengths[field] + '자까지 입력 가능합니다.');
                            return false;
                        }
                    }

                    // 패턴 검증
                    if (row.cdGroupId && !patterns.cdGroupId.test(row.cdGroupId)) {
                        alert('코드그룹ID는 영문, 숫자, 언더스코어(_)만 사용 가능합니다.');
                        return false;
                    }
                }

                return true;
            },

            /**
             * 그리드 변경사항 저장
             */
            saveData: function() {
                var self = this;
                var modifiedRows = this.instance.getModifiedRows();

                // 변경된 데이터가 없으면 저장하지 않음
                if (modifiedRows.createdRows.length === 0 &&
                    modifiedRows.updatedRows.length === 0 &&
                    modifiedRows.deletedRows.length === 0) {
                    alert('저장할 데이터가 없습니다.');
                    return;
                }

                // 유효성 검증
                if (!this.validateData(modifiedRows)) {
                    return;
                }

                // 저장 확인
                if (confirm('변경된 내용을 저장하시겠습니까?')) {
                    $.ajax({
                        url: '<c:url value="/system/code/group/saveAll.ajax"/>',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify(modifiedRows),
                        success: function(response) {
                            if (response.result) {
                                alert(response.message || '그룹코드 정보가 성공적으로 저장되었습니다.');
                                self.instance.readData(1);
                            } else {
                                alert(response.message || '그룹코드 정보 저장에 실패했습니다.');
                            }
                        }
                    });
                }
            }
        },

        /**
         * 상세코드 그리드 관련 객체
         */
        detailGrid: {
            /**
             * 그리드 인스턴스
             */
            instance: null,

            /**
             * 그리드 설정 초기화
             * @returns {Object} 그리드 설정 객체
             */
            initConfig: function() {
                // 데이터 소스 설정
                var dataSource = this.createDataSource();

                // 그리드 설정 객체 생성
                var gridConfig = new XitTuiGridConfig();

                // 기본 설정
                gridConfig.setOptDataSource(dataSource);            // 데이터소스 연결
                gridConfig.setOptGridId('detailGrid');              // 그리드를 출력할 Element ID
                gridConfig.setOptGridHeight(390);                   // 그리드 높이(단위: px)
                gridConfig.setOptRowHeight(30);                     // 그리드 행 높이(단위: px)
                gridConfig.setOptRowHeaderType('checkbox');         // 행 첫번째 셀 타입(rowNum: 순번, checkbox: 체크박스, '': 출력 안함)

                gridConfig.setOptUseClientSort(true);              // 클라이언트 사이드 정렬 사용

                gridConfig.setOptColumns(this.getGridColumns());

                return gridConfig;
            },

            /**
             * 컬럼 정의
             * @returns {Array} 컬럼 정의 배열
             */
            getGridColumns: function() {
                return [
                    {
                        header: '코드ID',
                        name: 'cdId',
                        width: 200,
                        sortable: true,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '코드명',
                        name: 'cdNm',
                        width: 250,
                        sortable: true,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '코드설명',
                        name: 'cdDc',
                        width: 350,
                        sortable: false,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '정렬순서',
                        name: 'sortOrdr',
                        width: 120,
                        sortable: true,
                        align: 'center',
                        editor: 'text'
                    },
                    {
                        header: '사용여부',
                        name: 'useYn',
                        width: 120,
                        align: 'center',
                        editor: {
                            type: 'select',
                            options: {
                                listItems: [
                                    {text: '사용', value: 'Y'},
                                    {text: '미사용', value: 'N'}
                                ]
                            }
                        },
                        formatter: function(value) {
                            return value.value === 'Y' ? '사용' : '미사용';
                        }
                    },
                    {
                        header: '등록일시',
                        name: 'regDttm',
                        width: 150,
                        align: 'center'
                    },
                    {
                        header: '기타1',
                        name: 'attribute1',
                        width: 150,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '기타2',
                        name: 'attribute2',
                        width: 150,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '기타3',
                        name: 'attribute3',
                        width: 150,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '기타4',
                        name: 'attribute4',
                        width: 150,
                        align: 'left',
                        editor: 'text'
                    },
                    {
                        header: '기타5',
                        name: 'attribute5',
                        width: 150,
                        align: 'left',
                        editor: 'text'
                    }
                ];
            },

            /**
             * 데이터 소스 생성
             * @returns {Object} 데이터 소스 객체
             */
            createDataSource: function() {
                return {
                    api: {
                        readData: {
                            url: '<c:url value="/system/code/detail/list.ajax"/>',
                            method: 'POST',
                            contentType: 'application/x-www-form-urlencoded',
                            processData: true
                        }
                    },
                    initialRequest: false,                          // 초기 데이터 요청 여부 (그룹코드 선택 후 요청)
                    serializer: function(params) {
                        // 기본 파라미터 (페이지 정보 등)
                        var defaultParams = $.param(params);
                        // 검색 폼 데이터
                        setSearchCond();
                        var searchParams = $.param({
                            selectCdGroupId: CodeIntegratedManage.selectCdGroupId,
                            searchKeyword: SEARCH_COND.detailSearchKeyword,
                            searchUseYn: SEARCH_COND.detailSearchUseYn
                        });
                        // 모든 파라미터 조합
                        return defaultParams + '&' + searchParams;
                    }
                };
            },

            /**
             * 그리드 인스턴스 생성
             */
            create: function() {
                var gridConfig = this.initConfig();
                var Grid = tui.Grid;
                this.instance = gridConfig.instance(Grid);

                // 그리드 테마 설정
                Grid.applyTheme('striped');

                // 그리드 이벤트 바인딩
                this.bindEvents();
            },

            /**
             * 그리드 이벤트 바인딩
             */
            bindEvents: function() {
                var self = this;
                var parent = CodeIntegratedManage;

                // 셀 편집 시작 전 이벤트
                this.instance.on('editingStart', function(ev) {
                    var { rowKey, columnName } = ev;
                    // 행 데이터 가져오기
                    var rowData = self.instance.getRow(rowKey);
                    // 기존 행인지 확인 (regDt가 있으면 기존 행)
                    if (columnName === "cdId" && rowData.regDttm) {
                        // 기존 행의 cdId는 편집 불가
                        alert('기존 코드의 ID는 수정할 수 없습니다.');
                        ev.stop(); // 편집 취소
                    }
                });
            },

            /**
             * 새 행 추가
             */
            addRow: function() {
                var parent = CodeIntegratedManage;

                // 코드 그룹이 선택되지 않은 경우
                if (!parent.selectCdGroupId) {
                    alert('코드 그룹을 먼저 선택해주세요.');
                    return;
                }

                // 새 행 추가
                this.instance.appendRow({
                    cdGroupId: parent.selectCdGroupId,
                    cdGroupNm: parent.selectedCdGroupNm,
                    cdId: '',
                    cdNm: '',
                    cdDc: '',
                    sortOrdr: '1',
                    useYn: 'Y',
                    regDttm: null
                }, {
                    focus: true       // 새 행에 포커스 설정
                });
                // 첫 번째 셀(cdId)로 에디터 포커스 이동
                var rowKey = this.instance.getRowCount() - 1;
                this.instance.startEditing(rowKey, 'cdId');
            },

            /**
             * 선택된 행 삭제
             */
            deleteSelectedRows: function() {
                var checkedRows = this.instance.getCheckedRows();
                if (checkedRows.length === 0) {
                    alert('삭제할 상세코드를 선택해주세요.');
                    return;
                }

                if (confirm('선택한 상세코드를 삭제하시겠습니까?')) {
                    // 선택된 행의 rowKey 배열 생성
                    var rowKeys = checkedRows.map(function(row) {
                        return row.rowKey;
                    });

                    // 여러 행 삭제 (rowKey 배열을 이용)
                    rowKeys.forEach(function(rowKey) {
                        this.instance.removeRow(rowKey);
                    }.bind(this));
                }
            },

            /**
             * 그리드 변경사항 취소
             */
            cancelChanges: function() {
                var modifiedRows = this.instance.getModifiedRows();

                // 변경된 데이터가 없으면 알림
                if (modifiedRows.createdRows.length === 0 &&
                    modifiedRows.updatedRows.length === 0 &&
                    modifiedRows.deletedRows.length === 0) {
                    alert('취소할 변경사항이 없습니다.');
                    return;
                }

                // 취소 확인
                if (confirm('모든 변경사항을 취소하시겠습니까?')) {
                    // 그리드 데이터를 다시 로드하여 모든 변경사항 취소
                    this.instance.readData(1);
                    //alert('변경사항이 취소되었습니다.');
                }
            },

            /**
             * 그리드 데이터 유효성 검증
             * @param {Object} modifiedRows 변경된 행 데이터
             * @returns {boolean} 유효성 검증 결과
             */
            validateData: function(modifiedRows) {
                var validRows = [].concat(
                    modifiedRows.createdRows || [],
                    modifiedRows.updatedRows || []
                );

                // 필수 입력 필드
                var requiredFields = ['cdId', 'cdNm', 'sortOrdr', 'useYn'];

                // 최대 길이 제한
                var maxLengths = {
                    cdId: 20,
                    cdNm: 100,
                    cdDc: 200,
                    sortOrdr: 3
                };

                // 정규식 패턴
                var patterns = {
                    cdId: /^[A-Za-z0-9_]*$/,
                    sortOrdr: /^\d+$/
                };

                for (var i = 0; i < validRows.length; i++) {
                    var row = validRows[i];

                    // 필수 입력 검증
                    for (var j = 0; j < requiredFields.length; j++) {
                        var field = requiredFields[j];
                        if (!row[field]) {
                            var columnInfo = this.getGridColumns().find(function(col) {
                                return col.name === field;
                            });
                            alert(columnInfo.header + '은(는) 필수 입력 항목입니다.');
                            return false;
                        }
                    }

                    // 최대 길이 검증
                    for (var field in maxLengths) {
                        if (row[field] && row[field].toString().length > maxLengths[field]) {
                            var columnInfo = this.getGridColumns().find(function(col) {
                                return col.name === field;
                            });
                            alert(columnInfo.header + '은(는) 최대 ' + maxLengths[field] + '자까지 입력 가능합니다.');
                            return false;
                        }
                    }

                    // 패턴 검증
                    if (row.cdId && !patterns.cdId.test(row.cdId)) {
                        alert('코드ID는 영문, 숫자, 언더스코어(_)만 사용 가능합니다.');
                        return false;
                    }

                    if (row.sortOrdr && !patterns.sortOrdr.test(row.sortOrdr)) {
                        alert('정렬순서는 숫자만 입력 가능합니다.');
                        return false;
                    }
                }

                return true;
            },

            /**
             * 그리드 변경사항 저장
             */
            saveData: function() {
                var self = this;
                var modifiedRows = this.instance.getModifiedRows();

                // 변경된 데이터가 없으면 저장하지 않음
                if (modifiedRows.createdRows.length === 0 &&
                    modifiedRows.updatedRows.length === 0 &&
                    modifiedRows.deletedRows.length === 0) {
                    alert('저장할 데이터가 없습니다.');
                    return;
                }

                // 유효성 검증
                if (!this.validateData(modifiedRows)) {
                    return;
                }

                // 저장 확인
                if (confirm('변경된 내용을 저장하시겠습니까?')) {
                    $.ajax({
                        url: '<c:url value="/system/code/detail/saveAll.ajax"/>',
                        type: 'POST',
                        contentType: 'application/json',
                        data: JSON.stringify(modifiedRows),
                        success: function(response) {
                            if (response.result) {
                                alert(response.message || '상세코드 정보가 성공적으로 저장되었습니다.');
                                self.instance.readData(1);
                            } else {
                                alert(response.message || '상세코드 정보 저장에 실패했습니다.');
                            }
                        }
                    });
                }
            }
        },

        /**
         * 이벤트 핸들러 설정
         */
        bindEvents: function() {
            var self = this;

            // 그룹코드 검색 버튼 클릭 이벤트
            $('#master_search_btn').on('click', function() {
                self.masterGrid.instance.readData(1);

            });

            // 그룹코드 perPage 변경 이벤트
            $('#masterPerPageSelect').on('change', function() {
                var perPage = parseInt($(this).val(), 10);
                self.masterGrid.instance.setPerPage(perPage);
            });

            // 그룹코드 등록 버튼 클릭 이벤트
            $('#addMasterBtn').on('click', function(e) {
                e.preventDefault();
                self.masterGrid.addRow();
            });

            // 그룹코드 삭제 버튼 클릭 이벤트
            $('#deleteMasterBtn').on('click', function(e) {
                e.preventDefault();
                self.masterGrid.deleteSelectedRows();
                // 하단 그리드 초기화
                CodeIntegratedManage.selectCdGroupId = '';
                self.detailGrid.instance.readData(1);
            });

            // 그룹코드 취소 버튼 클릭 이벤트
            $('#cancelMasterBtn').on('click', function(e) {
                e.preventDefault();
                self.masterGrid.cancelChanges();
            });

            // 그룹코드 저장 버튼 클릭 이벤트
            $('#saveMasterBtn').on('click', function(e) {
                e.preventDefault();
                self.masterGrid.saveData();
            });

            // 상세코드 검색 버튼 클릭 이벤트
            $('#detail_search_btn').on('click', function() {
                if (self.selectCdGroupId) {
                    self.detailGrid.instance.readData(1);
                } else {
                    alert('코드 그룹을 먼저 선택해주세요.');
                }
            });

            // 상세코드 등록 버튼 클릭 이벤트
            $('#addDetailBtn').on('click', function(e) {
                e.preventDefault();
                self.detailGrid.addRow();
            });

            // 상세코드 삭제 버튼 클릭 이벤트
            $('#deleteDetailBtn').on('click', function(e) {
                e.preventDefault();
                self.detailGrid.deleteSelectedRows();
            });

            // 상세코드 취소 버튼 클릭 이벤트
            $('#cancelDetailBtn').on('click', function(e) {
                e.preventDefault();
                self.detailGrid.cancelChanges();
            });

            // 상세코드 저장 버튼 클릭 이벤트
            $('#saveDetailBtn').on('click', function(e) {
                e.preventDefault();
                self.detailGrid.saveData();
            });

            // 검색어 입력 필드에서 엔터키 이벤트 처리 함수
            function handleEnterKey(inputSelector, buttonSelector) {
                $(inputSelector).on('keypress', function(e) {
                    if (e.which === 13) { // 엔터키 코드는 13
                        e.preventDefault(); // 기본 이벤트 방지
                        $(buttonSelector).trigger('click'); // 검색 버튼 클릭 이벤트 트리거
                    }
                });
            }

            // 마스터 검색 필드 엔터키 이벤트 처리
            handleEnterKey('#masterSearchKeyword', '#master_search_btn');
            handleEnterKey('#masterSearchUseYn', '#master_search_btn');

            // 상세 검색 필드 엔터키 이벤트 처리
            handleEnterKey('#detailSearchKeyword', '#detail_search_btn');
            handleEnterKey('#detailSearchUseYn', '#detail_search_btn');
        },

        /**
         * 모듈 초기화
         */
        init: function() {
            // 그리드 생성
            this.masterGrid.create();
            this.detailGrid.create();

            // 이벤트 핸들러 설정
            this.bindEvents();
        }
    };

    // 페이지 로드 시 초기화
    $(function() {
        CodeIntegratedManage.init();
    });

    // 전역 네임스페이스에 모듈 노출
    window.CodeIntegratedManage = CodeIntegratedManage;

})(window, jQuery);
</script>
