/* ===== Permission Page Definitions ===== */
const SYSTEM1_PAGES = {
    '작업 관리': [
        { key: 's1.dashboard', title: '대시보드', icon: 'fa-chart-line', def: true },
        { key: 's1.work.tbm', title: 'TBM 관리', icon: 'fa-hard-hat', def: true },
        { key: 's1.work.report_create', title: '작업보고서 작성', icon: 'fa-file-pen', def: true },
        { key: 's1.work.analysis', title: '작업 분석', icon: 'fa-magnifying-glass-chart', def: false },
        { key: 's1.work.nonconformity', title: '부적합 현황', icon: 'fa-triangle-exclamation', def: true },
        { key: 's1.work.schedule', title: '공정표', icon: 'fa-calendar-alt', def: false },
        { key: 's1.work.meetings', title: '생산회의록', icon: 'fa-users', def: false },
        { key: 's1.work.daily_status', title: '입력 현황', icon: 'fa-chart-bar', def: false },
        { key: 's1.work.proxy_input', title: '대리입력', icon: 'fa-user-edit', def: false },
    ],
    '공장 관리': [
        { key: 's1.factory.repair_management', title: '시설설비 관리', icon: 'fa-wrench', def: false },
        { key: 's1.inspection.daily_patrol', title: '일일순회점검', icon: 'fa-clipboard-check', def: false },
        { key: 's1.inspection.checkin', title: '출근 체크', icon: 'fa-fingerprint', def: true },
        { key: 's1.inspection.work_status', title: '근무 현황', icon: 'fa-user-clock', def: false },
    ],
    '소모품 관리': [
        { key: 's1.purchase.request', title: '소모품 신청', icon: 'fa-shopping-cart', def: false },
        { key: 's1.purchase.analysis', title: '소모품 분석', icon: 'fa-chart-line', def: false },
    ],
    '근태 관리': [
        { key: 's1.attendance.monthly', title: '월간 근태', icon: 'fa-calendar-days', def: true },
        { key: 's1.attendance.my_vacation_info', title: '내 연차 정보', icon: 'fa-info-circle', def: true },
        { key: 's1.attendance.vacation_request', title: '휴가 신청', icon: 'fa-paper-plane', def: true },
        { key: 's1.attendance.vacation_management', title: '휴가 관리', icon: 'fa-cog', def: false },
        { key: 's1.attendance.vacation_allocation', title: '휴가 발생 입력', icon: 'fa-plus-circle', def: false },
        { key: 's1.attendance.annual_overview', title: '연간 휴가 현황', icon: 'fa-chart-pie', def: false },
        { key: 's1.attendance.monthly_comparison', title: '월간 비교·확인', icon: 'fa-scale-balanced', def: false },
    ],
    '시스템 관리': [
        { key: 's1.admin.workers', title: '작업자 관리', icon: 'fa-people-group', def: false },
        { key: 's1.admin.projects', title: '프로젝트 관리', icon: 'fa-folder-open', def: false },
        { key: 's1.admin.tasks', title: '작업 관리', icon: 'fa-list-check', def: false },
        { key: 's1.admin.workplaces', title: '작업장 관리', icon: 'fa-warehouse', def: false },
        { key: 's1.admin.equipments', title: '설비 관리', icon: 'fa-gears', def: false },
        { key: 's1.admin.issue_categories', title: '신고 카테고리', icon: 'fa-tags', def: false },
        { key: 's1.admin.attendance_report', title: '출퇴근-보고서 대조', icon: 'fa-scale-balanced', def: false },
        { key: 's1.admin.departments', title: '부서 관리', icon: 'fa-sitemap', def: false },
        { key: 's1.admin.notifications', title: '알림 관리', icon: 'fa-bell', def: false },
    ]
};

const SYSTEM3_PAGES = {
    '메인': [
        { key: 'issues_dashboard', title: '현황판', icon: 'fa-chart-line', def: true },
        { key: 'issues_inbox', title: '수신함', icon: 'fa-inbox', def: true },
        { key: 'issues_management', title: '관리함', icon: 'fa-cog', def: false },
        { key: 'issues_archive', title: '폐기함', icon: 'fa-archive', def: false },
    ],
    '업무': [
        { key: 'daily_work', title: '일일 공수', icon: 'fa-calendar-check', def: false },
        { key: 'projects_manage', title: '프로젝트 관리', icon: 'fa-folder-open', def: false },
    ],
    '보고서': [
        { key: 'reports', title: '보고서', icon: 'fa-chart-bar', def: false },
        { key: 'reports_daily', title: '일일보고서', icon: 'fa-file-excel', def: false },
        { key: 'reports_weekly', title: '주간보고서', icon: 'fa-calendar-week', def: false },
        { key: 'reports_monthly', title: '월간보고서', icon: 'fa-calendar-alt', def: false },
    ],
    'AI': [
        { key: 'ai_assistant', title: 'AI 어시스턴트', icon: 'fa-robot', def: false },
    ]
};

const TKPURCHASE_PAGES = {
    '구매 관리': [
        { key: 'purchasing_daylabor',   title: '일용공 관리',     icon: 'fa-hard-hat',     def: false },
        { key: 'purchasing_schedule',   title: '작업일정 관리',   icon: 'fa-calendar-alt', def: false },
        { key: 'purchasing_workreport', title: '업무현황 관리',   icon: 'fa-clipboard-list', def: false },
        { key: 'purchasing_accounts',   title: '협력업체 계정',   icon: 'fa-user-shield',  def: false },
    ],
    '협력업체': [
        { key: 'purchasing_partner_portal',  title: '협력업체 포털',   icon: 'fa-building', def: false },
        { key: 'purchasing_partner_checkin', title: '협력업체 체크인', icon: 'fa-check-circle', def: false },
    ]
};

const TKSAFETY_PAGES = {
    '출입 관리': [
        { key: 'safety_visit',            title: '방문 관리',   icon: 'fa-door-open',      def: true },
        { key: 'safety_visit_request',    title: '출입 신청',   icon: 'fa-file-signature', def: true },
        { key: 'safety_visit_management', title: '출입 승인',   icon: 'fa-clipboard-check', def: false },
        { key: 'safety_entry_dashboard',  title: '출입 현황판', icon: 'fa-tv',             def: false },
    ],
    '교육/점검': [
        { key: 'safety_education',       title: '안전교육',         icon: 'fa-graduation-cap',       def: true },
        { key: 'safety_training',        title: '안전교육 실시',   icon: 'fa-chalkboard-teacher',   def: false },
        { key: 'safety_risk_assessment', title: '위험성평가',       icon: 'fa-exclamation-triangle', def: false },
        { key: 'safety_checklist',       title: '체크리스트 관리', icon: 'fa-tasks',                def: false },
    ]
};

const TKSUPPORT_PAGES = {
    '일반': [
        { key: 'support_dashboard',        title: '대시보드',     icon: 'fa-home',           def: true },
        { key: 'support_vacation_request', title: '휴가 신청',   icon: 'fa-paper-plane',    def: true },
        { key: 'support_vacation_status',  title: '내 휴가 현황', icon: 'fa-calendar-check', def: true },
    ],
    '관리': [
        { key: 'support_vacation_approval',  title: '휴가 승인',       icon: 'fa-user-check',  def: false },
        { key: 'support_company_holidays',   title: '전사 휴가 관리',  icon: 'fa-calendar-day', def: false },
        { key: 'support_vacation_dashboard', title: '전체 휴가관리',   icon: 'fa-chart-bar',    def: false },
    ]
};

const TKUSER_PAGES = {
    '통합 관리': [
        { key: 'tkuser.users',                   title: '사용자 관리',      icon: 'fa-users',              def: false, tab: 'users' },
        { key: 'tkuser.projects',                title: '프로젝트 관리',    icon: 'fa-folder-open',        def: false, tab: 'projects' },
        { key: 'tkuser.workplaces',              title: '작업장 관리',      icon: 'fa-building',           def: false, tab: 'workplaces' },
        { key: 'tkuser.workers',                 title: '작업자 관리',      icon: 'fa-hard-hat',           def: false, tab: 'workers' },
        { key: 'tkuser.departments',             title: '부서 관리',        icon: 'fa-sitemap',            def: false, tab: 'departments' },
        { key: 'tkuser.issue_types',             title: '이슈 유형 관리',   icon: 'fa-exclamation-triangle', def: false, tab: 'issueTypes' },
        { key: 'tkuser.tasks',                   title: '작업 관리',        icon: 'fa-tasks',              def: false, tab: 'tasks' },
        { key: 'tkuser.vacations',               title: '휴가 관리',        icon: 'fa-umbrella-beach',     def: false, tab: 'vacations' },
        { key: 'tkuser.vacation_settings',       title: '연차 설정',        icon: 'fa-sliders',            def: false, tab: 'vacationSettings' },
        { key: 'tkuser.partners',                title: '협력업체 관리',    icon: 'fa-truck',              def: false, tab: 'partners' },
        { key: 'tkuser.notification_recipients', title: '알림 수신자 관리', icon: 'fa-bell',               def: false, tab: 'notificationRecipients' },
    ]
};

/* ===== Permissions Tab State ===== */
let permissionsTabLoaded = false;

function loadPermissionsTab() {
    populateDeptPermSelect();
    updatePermissionUserSelect();
    permissionsTabLoaded = true;
}

/* ===== Users State ===== */
let users = [], selectedUserId = null, currentPermissions = {}, currentPermSources = {}, currentDeptGranted = {};

/* ===== Users CRUD ===== */
async function loadUsers() {
    try {
        const r = await api('/users'); users = r.data || r;
        displayUsers(); updatePermissionUserSelect();
        populateUserDeptSelects(); populateUserDeptFilter();
        const hireDateInput = document.getElementById('newHireDate');
        if (hireDateInput && !hireDateInput.value) hireDateInput.value = getSeoulToday();
    } catch (err) {
        document.getElementById('userList').innerHTML = `<div class="text-red-500 text-center py-6"><i class="fas fa-exclamation-triangle text-xl"></i><p class="text-sm mt-2">${err.message}</p></div>`;
    }
}

function populateUserDeptSelects() {
    ['newDepartmentId','editDepartmentId'].forEach(id => {
        const sel = document.getElementById(id); if (!sel) return;
        const val = sel.value;
        sel.innerHTML = '<option value="">선택</option>';
        departmentsCache.forEach(d => { const o = document.createElement('option'); o.value = d.department_id; o.textContent = d.department_name; sel.appendChild(o); });
        sel.value = val;
    });
}
// 필터용 부서 셀렉트 (populateUserDeptSelects는 모달 폼용)
function populateUserDeptFilter() {
    const sel = document.getElementById('userDeptFilter');
    if (!sel) return;
    const val = sel.value;
    sel.innerHTML = '<option value="">전체 부서</option>';
    departmentsCache.forEach(d => { const o = document.createElement('option'); o.value = d.department_id; o.textContent = d.department_name; sel.appendChild(o); });
    sel.value = val;
}
function renderUserRow(u, isResigned) {
    return `<div class="flex items-center justify-between p-2.5 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
            <div class="flex-1 min-w-0">
                <div class="text-sm font-medium ${isResigned ? 'text-gray-400' : 'text-gray-800'} truncate"><i class="fas fa-user mr-1.5 text-gray-400 text-xs"></i>${u.name||u.username}</div>
                <div class="text-xs text-gray-500 flex items-center gap-1.5 mt-0.5 flex-wrap">
                    <span>${u.username}</span>
                    ${u.department||u.department_id?`<span class="px-1.5 py-0.5 rounded bg-green-50 text-green-600">${deptLabel(u.department, u.department_id)}</span>`:''}
                    <span class="px-1.5 py-0.5 rounded ${u.role==='admin'?'bg-red-50 text-red-600':'bg-slate-50 text-slate-500'}">${u.role==='admin'?'관리자':'사용자'}</span>
                    ${u.hire_date ? `<span class="px-1.5 py-0.5 rounded bg-blue-50 text-blue-600">입사 ${formatDate(u.hire_date)}</span>` : '<span class="px-1.5 py-0.5 rounded bg-orange-50 text-orange-500">입사일 미등록</span>'}
                    ${isResigned && u.resigned_date ? `<span class="px-1.5 py-0.5 rounded bg-gray-200 text-gray-500">퇴사 ${formatDate(u.resigned_date)}</span>` : ''}
                </div>
            </div>
            <div class="flex gap-1 ml-2 flex-shrink-0">
                <button onclick="editUser(${u.user_id})" class="p-1.5 text-slate-500 hover:text-slate-700 hover:bg-slate-200 rounded" title="편집"><i class="fas fa-pen-to-square text-xs"></i></button>
                ${isResigned ? `<button onclick="reactivateUser(${u.user_id},'${escHtml(u.name||u.username)}')" class="p-1.5 text-emerald-500 hover:text-emerald-700 hover:bg-emerald-100 rounded" title="재활성화"><i class="fas fa-user-check text-xs"></i></button>` : `
                <button onclick="resetPassword(${u.user_id},'${u.username}')" class="p-1.5 text-amber-500 hover:text-amber-700 hover:bg-amber-100 rounded" title="비밀번호 초기화"><i class="fas fa-key text-xs"></i></button>
                ${u.username!=='hyungi'?`<button onclick="deleteUser(${u.user_id},'${u.username}')" class="p-1.5 text-red-400 hover:text-red-600 hover:bg-red-100 rounded" title="삭제"><i class="fas fa-trash text-xs"></i></button>`:''}`}
            </div>
        </div>`;
}

function displayUsers() {
    const searchTerm = (document.getElementById('userSearchInput')?.value || '').trim().toLowerCase();
    const deptFilterVal = document.getElementById('userDeptFilter')?.value || '';

    let filtered = users;

    if (searchTerm) {
        filtered = filtered.filter(u => {
            const name = (u.name || '').toLowerCase();
            const username = (u.username || '').toLowerCase();
            return name.includes(searchTerm) || username.includes(searchTerm);
        });
    }

    if (deptFilterVal) {
        const deptId = parseInt(deptFilterVal);
        filtered = filtered.filter(u => u.department_id === deptId);
    }

    const activeUsers = filtered.filter(u => u.is_active !== 0 && u.is_active !== false);
    const resignedUsers = filtered.filter(u => u.is_active === 0 || u.is_active === false);

    const c = document.getElementById('userList');
    const countEl = document.getElementById('activeUserCount');
    if (countEl) countEl.textContent = `(${activeUsers.length}명)`;

    if (!activeUsers.length) {
        c.innerHTML = searchTerm || deptFilterVal
            ? '<p class="text-gray-400 text-center py-4 text-sm">검색 결과가 없습니다.</p>'
            : '<p class="text-gray-400 text-center py-4 text-sm">등록된 사용자가 없습니다.</p>';
    } else {
        c.innerHTML = activeUsers.map(u => renderUserRow(u, false)).join('');
    }

    const resignedSection = document.getElementById('resignedSection');
    const resignedList = document.getElementById('resignedUserList');
    const resignedCount = document.getElementById('resignedCount');
    if (resignedUsers.length > 0) {
        resignedSection.classList.remove('hidden');
        resignedCount.textContent = `(${resignedUsers.length}명)`;
        resignedList.innerHTML = resignedUsers.map(u => renderUserRow(u, true)).join('');
    } else {
        resignedSection.classList.add('hidden');
    }
}

function toggleResignedList() {
    const list = document.getElementById('resignedUserList');
    const btn = document.getElementById('resignedToggleBtn');
    if (list.classList.contains('hidden')) {
        list.classList.remove('hidden');
        btn.innerHTML = '<i class="fas fa-chevron-up mr-1"></i>접기';
    } else {
        list.classList.add('hidden');
        btn.innerHTML = '<i class="fas fa-chevron-down mr-1"></i>펼치기';
    }
}

async function reactivateUser(id, name) {
    if (!confirm(`${name}을(를) 재활성화하시겠습니까?`)) return;
    try {
        await api(`/users/${id}`, { method: 'PUT', body: JSON.stringify({ is_active: true, resigned_date: null }) });
        showToast('재활성화 완료');
        await loadUsers();
    } catch(e) { showToast(e.message, 'error'); }
}

document.getElementById('addUserForm').addEventListener('submit', async e => {
    e.preventDefault();
    const deptIdVal = document.getElementById('newDepartmentId').value;
    const hireDateVal = document.getElementById('newHireDate').value;
    try {
        await api('/users', { method:'POST', body: JSON.stringify({ username: document.getElementById('newUsername').value.trim(), name: document.getElementById('newFullName').value.trim(), password: document.getElementById('newPassword').value, department_id: deptIdVal ? parseInt(deptIdVal) : null, role: document.getElementById('newRole').value, hire_date: hireDateVal || null }) });
        showToast('사용자가 추가되었습니다.'); document.getElementById('addUserForm').reset(); document.getElementById('newHireDate').value = getSeoulToday(); await loadUsers();
    } catch(e) { showToast(e.message,'error'); }
});

function editUser(id) {
    const u = users.find(x=>x.user_id===id); if(!u) return;
    document.getElementById('editUserId').value=u.user_id; document.getElementById('editUsername').value=u.username;
    document.getElementById('editFullName').value=u.name||'';
    populateUserDeptSelects();
    document.getElementById('editDepartmentId').value=u.department_id||'';
    document.getElementById('editRole').value=u.role;
    document.getElementById('editHireDate').value = formatDate(u.hire_date);
    document.getElementById('editResignedDate').value = formatDate(u.resigned_date);
    document.getElementById('editUserModal').classList.remove('hidden');
}
function closeEditModal() { document.getElementById('editUserModal').classList.add('hidden'); }

document.getElementById('editUserForm').addEventListener('submit', async e => {
    e.preventDefault();
    const deptIdVal = document.getElementById('editDepartmentId').value;
    try {
        await api(`/users/${document.getElementById('editUserId').value}`, { method:'PUT', body: JSON.stringify({ name: document.getElementById('editFullName').value.trim()||null, department_id: deptIdVal ? parseInt(deptIdVal) : null, role: document.getElementById('editRole').value, hire_date: document.getElementById('editHireDate').value || null, resigned_date: document.getElementById('editResignedDate').value || null }) });
        showToast('수정되었습니다.'); closeEditModal(); await loadUsers();
    } catch(e) { showToast(e.message,'error'); }
});

async function resetPassword(id, name) {
    if (!confirm(`${name}의 비밀번호를 "000000"으로 초기화?`)) return;
    try { await api(`/users/${id}/reset-password`,{method:'POST',body:JSON.stringify({new_password:'000000'})}); showToast(`${name} 비밀번호 초기화 완료`); } catch(e) { showToast(e.message,'error'); }
}
async function deleteUser(id, name) {
    if (!confirm(`${name}을(를) 비활성화?`)) return;
    try { await api(`/users/${id}`,{method:'DELETE'}); showToast('비활성화 완료'); await loadUsers(); } catch(e) { showToast(e.message,'error'); }
}

document.getElementById('changePasswordForm').addEventListener('submit', async e => {
    e.preventDefault();
    const np = document.getElementById('newPasswordChange').value;
    if (np !== document.getElementById('confirmPassword').value) { showToast('비밀번호 불일치','error'); return; }
    try {
        await api('/users/change-password',{method:'POST',body:JSON.stringify({current_password:document.getElementById('currentPassword').value,new_password:np})});
        showToast('비밀번호 변경 완료'); document.getElementById('changePasswordForm').reset();
    } catch(e) { showToast(e.message,'error'); }
});

/* ===== Permissions ===== */
function updatePermissionUserSelect() {
    const sel = document.getElementById('permissionUserSelect');
    sel.innerHTML = '<option value="">사용자 선택</option>';
    users.filter(u=>u.role==='user').forEach(u => { const o=document.createElement('option'); o.value=u.user_id; o.textContent=`${u.name||u.username} (${u.username})`; sel.appendChild(o); });
}

document.getElementById('permissionUserSelect').addEventListener('change', async e => {
    selectedUserId = e.target.value;
    if (selectedUserId) {
        await loadUserPermissions(selectedUserId);
        renderPermissionGrid();
        document.getElementById('permissionPanel').classList.remove('hidden');
        document.getElementById('permissionEmpty').classList.add('hidden');
    } else {
        document.getElementById('permissionPanel').classList.add('hidden');
        document.getElementById('permissionEmpty').classList.remove('hidden');
    }
});

async function loadUserPermissions(userId) {
    currentPermissions = {};
    currentPermSources = {};
    currentDeptGranted = {};
    const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES, ...TKSAFETY_PAGES, ...TKSUPPORT_PAGES, ...TKUSER_PAGES };
    Object.values(allDefs).flat().forEach(p => { currentPermissions[p.key] = p.def; currentPermSources[p.key] = 'default'; currentDeptGranted[p.key] = false; });
    try {
        const result = await api(`/permissions/users/${userId}/effective-permissions`);
        if (result.permissions) {
            for (const [pageName, info] of Object.entries(result.permissions)) {
                currentPermissions[pageName] = info.can_access;
                currentPermSources[pageName] = info.source;
                currentDeptGranted[pageName] = !!info.dept_granted;
            }
        }
    } catch(e) { console.warn('권한 로드 실패:', e); }
}

function renderPermissionGrid() {
    renderSystemPerms('s1-perms', SYSTEM1_PAGES, 'blue');
    renderSystemPerms('s3-perms', SYSTEM3_PAGES, 'purple');
    renderSystemPerms('tkpurchase-perms', TKPURCHASE_PAGES, 'green');
    renderSystemPerms('tksafety-perms', TKSAFETY_PAGES, 'orange');
    renderSystemPerms('tksupport-perms', TKSUPPORT_PAGES, 'indigo');
    renderSystemPerms('tkuser-perms', TKUSER_PAGES, 'slate');
}

function sourceLabel(src) {
    if (src === 'explicit') return '<span class="ml-auto text-[10px] px-1.5 py-0.5 rounded bg-blue-50 text-blue-500">개인</span>';
    if (src === 'department') return '<span class="ml-auto text-[10px] px-1.5 py-0.5 rounded bg-gray-100 text-gray-500">부서</span>';
    return '';
}

function renderSystemPerms(containerId, pageDef, color) {
    const container = document.getElementById(containerId);
    let html = '';
    Object.entries(pageDef).forEach(([groupName, pages]) => {
        const groupId = containerId + '-' + groupName.replace(/\s/g,'');
        const allChecked = pages.every(p => currentPermissions[p.key]);
        html += `
            <div>
                <div class="group-header flex items-center justify-between py-2 px-1 rounded" onclick="toggleGroup('${groupId}')">
                    <div class="flex items-center gap-2">
                        <i class="fas fa-chevron-down text-xs text-gray-400 transition-transform" id="arrow-${groupId}"></i>
                        <span class="text-xs font-semibold text-gray-600 uppercase tracking-wide">${groupName}</span>
                        <span class="text-xs text-gray-400">${pages.length}</span>
                    </div>
                    <label class="flex items-center gap-1.5 text-xs text-gray-500 cursor-pointer" onclick="event.stopPropagation()">
                        <input type="checkbox" ${allChecked?'checked':''} onchange="toggleGroupAll('${groupId}', this.checked)"
                            class="h-3.5 w-3.5 text-${color}-500 rounded border-gray-300">
                        <span>전체</span>
                    </label>
                </div>
                <div id="${groupId}" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 mt-1">
                    ${pages.map(p => {
                        const checked = currentPermissions[p.key] || false;
                        const src = currentPermSources[p.key] || 'default';
                        const deptLocked = currentDeptGranted[p.key] || false;
                        if (deptLocked) {
                            return `
                            <label class="perm-item flex items-center gap-2.5 p-2.5 border rounded-lg opacity-75 cursor-not-allowed checked" data-group="${groupId}">
                                <input type="checkbox" id="perm_${p.key}" checked disabled class="h-4 w-4 text-${color}-500 rounded border-gray-300">
                                <i class="fas fa-lock text-xs text-gray-400"></i>
                                <i class="fas ${p.icon} text-sm text-${color}-500" data-color="${color}"></i>
                                <span class="text-sm text-gray-700">${p.title}</span>
                                <span class="ml-auto text-[10px] px-1.5 py-0.5 rounded bg-emerald-50 text-emerald-500"><i class="fas fa-lock text-[8px] mr-0.5"></i>부서</span>
                            </label>`;
                        }
                        return `
                        <label class="perm-item flex items-center gap-2.5 p-2.5 border rounded-lg cursor-pointer ${checked?'checked':'border-gray-200'}" data-group="${groupId}">
                            <input type="checkbox" id="perm_${p.key}" ${checked?'checked':''} class="h-4 w-4 text-${color}-500 rounded border-gray-300 focus:ring-${color}-400"
                                onchange="onPermChange(this)">
                            <i class="fas ${p.icon} text-sm ${checked?`text-${color}-500`:'text-gray-400'}" data-color="${color}"></i>
                            <span class="text-sm text-gray-700">${p.title}</span>
                            ${sourceLabel(src)}
                        </label>`;
                    }).join('')}
                </div>
            </div>`;
    });
    container.innerHTML = html;
}

function onPermChange(cb) {
    const item = cb.closest('.perm-item');
    const icon = item.querySelector('i[data-color]');
    const color = icon.dataset.color;
    item.classList.toggle('checked', cb.checked);
    icon.classList.toggle(`text-${color}-500`, cb.checked);
    icon.classList.toggle('text-gray-400', !cb.checked);
    // 그룹 전체 체크박스 동기화
    const group = item.dataset.group;
    const groupCbs = document.querySelectorAll(`[data-group="${group}"] input[type="checkbox"]`);
    const allChecked = [...groupCbs].every(c => c.checked);
    const groupHeader = document.getElementById(group)?.previousElementSibling;
    if (groupHeader) { const gc = groupHeader.querySelector('input[type="checkbox"]'); if(gc) gc.checked = allChecked; }
}

function toggleGroup(groupId) {
    const el = document.getElementById(groupId);
    const arrow = document.getElementById('arrow-' + groupId);
    el.classList.toggle('hidden');
    arrow?.classList.toggle('-rotate-90');
}

function toggleGroupAll(groupId, checked) {
    document.querySelectorAll(`#${groupId} input[type="checkbox"]:not(:disabled)`).forEach(cb => {
        cb.checked = checked;
        onPermChange(cb);
    });
}

function toggleSystemAll(prefix, checked) {
    const containerMap = { s1: 's1-perms', s3: 's3-perms', tkpurchase: 'tkpurchase-perms' };
    const containerId = containerMap[prefix] || prefix + '-perms';
    document.querySelectorAll(`#${containerId} input[type="checkbox"]:not(:disabled)`).forEach(cb => {
        cb.checked = checked;
        onPermChange(cb);
    });
    // 그룹 전체 체크박스도 동기화
    document.querySelectorAll(`#${containerId} .group-header input[type="checkbox"]`).forEach(cb => cb.checked = checked);
}

// 저장
document.getElementById('savePermissionsBtn').addEventListener('click', async () => {
    if (!selectedUserId) return;
    const btn = document.getElementById('savePermissionsBtn');
    const st = document.getElementById('permissionSaveStatus');
    btn.disabled = true; btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>저장 중...';

    try {
        const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat(), ...Object.values(TKSAFETY_PAGES).flat(), ...Object.values(TKSUPPORT_PAGES).flat(), ...Object.values(TKUSER_PAGES).flat()];
        const permissions = allPages
            .filter(p => !currentDeptGranted[p.key])
            .map(p => {
                const cb = document.getElementById('perm_' + p.key);
                return { page_name: p.key, can_access: cb ? cb.checked : false };
            });
        await api('/permissions/bulk-grant', { method:'POST', body: JSON.stringify({ user_id: parseInt(selectedUserId), permissions }) });
        st.textContent = '저장 완료'; st.className = 'text-sm text-emerald-600';
        showToast('권한이 저장되었습니다.');
        setTimeout(() => { st.textContent = ''; }, 3000);
    } catch(e) {
        st.textContent = e.message; st.className = 'text-sm text-red-500';
        showToast('저장 실패: ' + e.message, 'error');
    } finally { btn.disabled = false; btn.innerHTML = '<i class="fas fa-save mr-2"></i>권한 저장'; }
});

/* ===== Department Permissions ===== */
let selectedDeptId = null, deptPermissions = {};

function populateDeptPermSelect() {
    const sel = document.getElementById('deptPermSelect'); if (!sel) return;
    sel.innerHTML = '<option value="">부서 선택</option>';
    departmentsCache.forEach(d => { const o = document.createElement('option'); o.value = d.department_id; o.textContent = d.department_name; sel.appendChild(o); });
}

document.addEventListener('DOMContentLoaded', () => {
    // 사용자 검색 + 부서 필터
    let userSearchTimeout;
    const userSearchEl = document.getElementById('userSearchInput');
    if (userSearchEl) userSearchEl.addEventListener('input', () => {
        clearTimeout(userSearchTimeout);
        userSearchTimeout = setTimeout(displayUsers, 300);
    });
    const userDeptFilterEl = document.getElementById('userDeptFilter');
    if (userDeptFilterEl) userDeptFilterEl.addEventListener('change', displayUsers);

    const sel = document.getElementById('deptPermSelect');
    if (sel) sel.addEventListener('change', async e => {
        selectedDeptId = e.target.value;
        if (selectedDeptId) {
            await loadDeptPermissions(selectedDeptId);
            renderDeptPermissionGrid();
            document.getElementById('deptPermPanel').classList.remove('hidden');
            document.getElementById('deptPermEmpty').classList.add('hidden');
        } else {
            document.getElementById('deptPermPanel').classList.add('hidden');
            document.getElementById('deptPermEmpty').classList.remove('hidden');
        }
    });

    const saveBtn = document.getElementById('saveDeptPermBtn');
    if (saveBtn) saveBtn.addEventListener('click', saveDeptPermissions);

    const resetBtn = document.getElementById('resetToDefaultBtn');
    if (resetBtn) resetBtn.addEventListener('click', resetUserPermToDefault);
});

async function loadDeptPermissions(deptId) {
    deptPermissions = {};
    const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES, ...TKSAFETY_PAGES, ...TKSUPPORT_PAGES, ...TKUSER_PAGES };
    Object.values(allDefs).flat().forEach(p => { deptPermissions[p.key] = p.def; });
    try {
        const result = await api(`/permissions/departments/${deptId}/permissions`);
        (result.data || []).forEach(p => { deptPermissions[p.page_name] = !!p.can_access; });
    } catch(e) { console.warn('부서 권한 로드 실패:', e); }
}

function renderDeptPermissionGrid() {
    renderDeptSystemPerms('dept-s1-perms', SYSTEM1_PAGES, 'blue');
    renderDeptSystemPerms('dept-s3-perms', SYSTEM3_PAGES, 'purple');
    renderDeptSystemPerms('dept-tkpurchase-perms', TKPURCHASE_PAGES, 'green');
    renderDeptSystemPerms('dept-tksafety-perms', TKSAFETY_PAGES, 'orange');
    renderDeptSystemPerms('dept-tksupport-perms', TKSUPPORT_PAGES, 'indigo');
    renderDeptSystemPerms('dept-tkuser-perms', TKUSER_PAGES, 'slate');
}

function renderDeptSystemPerms(containerId, pageDef, color) {
    const container = document.getElementById(containerId);
    if (!container) return;
    let html = '';
    Object.entries(pageDef).forEach(([groupName, pages]) => {
        const groupId = containerId + '-' + groupName.replace(/\s/g,'');
        const allChecked = pages.every(p => deptPermissions[p.key]);
        html += `
            <div>
                <div class="group-header flex items-center justify-between py-2 px-1 rounded" onclick="toggleGroup('${groupId}')">
                    <div class="flex items-center gap-2">
                        <i class="fas fa-chevron-down text-xs text-gray-400 transition-transform" id="arrow-${groupId}"></i>
                        <span class="text-xs font-semibold text-gray-600 uppercase tracking-wide">${groupName}</span>
                        <span class="text-xs text-gray-400">${pages.length}</span>
                    </div>
                    <label class="flex items-center gap-1.5 text-xs text-gray-500 cursor-pointer" onclick="event.stopPropagation()">
                        <input type="checkbox" ${allChecked?'checked':''} onchange="toggleDeptGroupAll('${groupId}', this.checked)"
                            class="h-3.5 w-3.5 text-${color}-500 rounded border-gray-300">
                        <span>전체</span>
                    </label>
                </div>
                <div id="${groupId}" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 mt-1">
                    ${pages.map(p => {
                        const checked = deptPermissions[p.key] || false;
                        return `
                        <label class="perm-item flex items-center gap-2.5 p-2.5 border rounded-lg cursor-pointer ${checked?'checked':'border-gray-200'}" data-group="${groupId}">
                            <input type="checkbox" id="dperm_${p.key}" ${checked?'checked':''} class="h-4 w-4 text-${color}-500 rounded border-gray-300 focus:ring-${color}-400"
                                onchange="onDeptPermChange(this)">
                            <i class="fas ${p.icon} text-sm ${checked?`text-${color}-500`:'text-gray-400'}" data-color="${color}"></i>
                            <span class="text-sm text-gray-700">${p.title}</span>
                        </label>`;
                    }).join('')}
                </div>
            </div>`;
    });
    container.innerHTML = html;
}

function onDeptPermChange(cb) {
    const item = cb.closest('.perm-item');
    const icon = item.querySelector('i[data-color]');
    const color = icon.dataset.color;
    item.classList.toggle('checked', cb.checked);
    icon.classList.toggle(`text-${color}-500`, cb.checked);
    icon.classList.toggle('text-gray-400', !cb.checked);
    const group = item.dataset.group;
    const groupCbs = document.querySelectorAll(`[data-group="${group}"] input[type="checkbox"]`);
    const allChecked = [...groupCbs].every(c => c.checked);
    const groupHeader = document.getElementById(group)?.previousElementSibling;
    if (groupHeader) { const gc = groupHeader.querySelector('input[type="checkbox"]'); if(gc) gc.checked = allChecked; }
}

function toggleDeptGroupAll(groupId, checked) {
    document.querySelectorAll(`#${groupId} input[type="checkbox"]`).forEach(cb => {
        cb.checked = checked;
        onDeptPermChange(cb);
    });
}

function toggleDeptSystemAll(prefix, checked) {
    const containerMap = { s1: 'dept-s1-perms', s3: 'dept-s3-perms', tkpurchase: 'dept-tkpurchase-perms' };
    const containerId = containerMap[prefix] || 'dept-' + prefix + '-perms';
    document.querySelectorAll(`#${containerId} input[type="checkbox"]`).forEach(cb => {
        cb.checked = checked;
        onDeptPermChange(cb);
    });
    document.querySelectorAll(`#${containerId} .group-header input[type="checkbox"]`).forEach(cb => cb.checked = checked);
}

async function saveDeptPermissions() {
    if (!selectedDeptId) return;
    const btn = document.getElementById('saveDeptPermBtn');
    const st = document.getElementById('deptPermSaveStatus');
    btn.disabled = true; btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>저장 중...';

    try {
        const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat(), ...Object.values(TKSAFETY_PAGES).flat(), ...Object.values(TKSUPPORT_PAGES).flat(), ...Object.values(TKUSER_PAGES).flat()];
        const permissions = allPages.map(p => {
            const cb = document.getElementById('dperm_' + p.key);
            return { page_name: p.key, can_access: cb ? cb.checked : false };
        });
        await api(`/permissions/departments/${selectedDeptId}/bulk-set`, { method:'POST', body: JSON.stringify({ permissions }) });
        st.textContent = '저장 완료'; st.className = 'text-sm text-emerald-600';
        showToast('부서 권한이 저장되었습니다.');
        setTimeout(() => { st.textContent = ''; }, 3000);
    } catch(e) {
        st.textContent = e.message; st.className = 'text-sm text-red-500';
        showToast('저장 실패: ' + e.message, 'error');
    } finally { btn.disabled = false; btn.innerHTML = '<i class="fas fa-save mr-2"></i>부서 권한 저장'; }
}

async function resetUserPermToDefault() {
    if (!selectedUserId) return;
    if (!confirm('이 사용자의 개인 권한을 모두 삭제하고 부서 기본 권한으로 되돌리시겠습니까?')) return;
    try {
        const perms = await api(`/users/${selectedUserId}/page-permissions`);
        const permArr = Array.isArray(perms) ? perms : [];
        for (const p of permArr) {
            await api(`/permissions/${p.id}`, { method: 'DELETE' });
        }
        showToast('부서 기본 권한으로 초기화되었습니다.');
        await loadUserPermissions(selectedUserId);
        renderPermissionGrid();
    } catch(e) { showToast('초기화 실패: ' + e.message, 'error'); }
}

/* ===== Workers CRUD ===== */
let workers = [], workersLoaded = false, departmentsForSelect = [];

const JOB_TYPE = { leader: '반장', worker: '작업자' };
function jobTypeBadge(t) {
    if (t === 'leader') return '<span class="px-1.5 py-0.5 rounded text-xs bg-amber-50 text-amber-600">반장</span>';
    if (t === 'worker') return '<span class="px-1.5 py-0.5 rounded text-xs bg-blue-50 text-blue-600">작업자</span>';
    return t ? `<span class="px-1.5 py-0.5 rounded text-xs bg-gray-50 text-gray-500">${t}</span>` : '';
}
function workerStatusBadge(s) {
    if (s === 'inactive') return '<span class="px-1.5 py-0.5 rounded text-xs bg-gray-100 text-gray-400">비활성</span>';
    return '<span class="px-1.5 py-0.5 rounded text-xs bg-emerald-50 text-emerald-600">재직</span>';
}

async function loadDepartmentsForSelect() {
    try {
        const r = await api('/departments'); departmentsForSelect = (r.data || r).filter(d => d.is_active !== 0 && d.is_active !== false);
        populateDeptSelects();
    } catch(e) { console.warn('부서 로드 실패:', e); }
}
function populateDeptSelects() {
    ['newWorkerDept','editWorkerDept'].forEach(id => {
        const sel = document.getElementById(id); if (!sel) return;
        const val = sel.value;
        sel.innerHTML = '<option value="">선택</option>';
        departmentsForSelect.forEach(d => { const o = document.createElement('option'); o.value = d.department_id; o.textContent = d.department_name; sel.appendChild(o); });
        sel.value = val;
    });
}

async function loadWorkers() {
    await loadDepartmentsForSelect();
    try {
        const r = await api('/workers'); workers = r.data || r;
        workersLoaded = true;
        displayWorkers();
    } catch (err) {
        document.getElementById('workerList').innerHTML = `<div class="text-red-500 text-center py-6"><i class="fas fa-exclamation-triangle text-xl"></i><p class="text-sm mt-2">${err.message}</p></div>`;
    }
}

function displayWorkers() {
    const c = document.getElementById('workerList');
    if (!workers.length) { c.innerHTML = '<p class="text-gray-400 text-center py-4 text-sm">등록된 작업자가 없습니다.</p>'; return; }
    c.innerHTML = workers.map(w => `
        <div class="flex items-center justify-between p-2.5 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
            <div class="flex-1 min-w-0">
                <div class="text-sm font-medium text-gray-800 truncate"><i class="fas fa-hard-hat mr-1.5 text-gray-400 text-xs"></i>${w.worker_name}</div>
                <div class="text-xs text-gray-500 flex items-center gap-1.5 mt-0.5 flex-wrap">
                    ${jobTypeBadge(w.job_type)}
                    ${w.department_name ? `<span class="px-1.5 py-0.5 rounded bg-green-50 text-green-600">${w.department_name}</span>` : ''}
                    ${workerStatusBadge(w.status)}
                    ${w.phone_number ? `<span class="text-gray-400">${w.phone_number}</span>` : ''}
                </div>
            </div>
            <div class="flex gap-1 ml-2 flex-shrink-0">
                <button onclick="editWorker(${w.worker_id})" class="p-1.5 text-slate-500 hover:text-slate-700 hover:bg-slate-200 rounded" title="편집"><i class="fas fa-pen-to-square text-xs"></i></button>
                ${w.status !== 'inactive' ? `<button onclick="deactivateWorker(${w.worker_id},'${(w.worker_name||'').replace(/'/g,"\\'")}')" class="p-1.5 text-red-400 hover:text-red-600 hover:bg-red-100 rounded" title="비활성화"><i class="fas fa-ban text-xs"></i></button>` : ''}
            </div>
        </div>`).join('');
}

document.getElementById('addWorkerForm').addEventListener('submit', async e => {
    e.preventDefault();
    try {
        await api('/workers', { method: 'POST', body: JSON.stringify({
            worker_name: document.getElementById('newWorkerName').value.trim(),
            job_type: document.getElementById('newJobType').value || null,
            department_id: document.getElementById('newWorkerDept').value ? parseInt(document.getElementById('newWorkerDept').value) : null,
            phone_number: document.getElementById('newWorkerPhone').value.trim() || null,
            hire_date: document.getElementById('newWorkerHireDate').value || null,
            notes: document.getElementById('newWorkerNotes').value.trim() || null
        })});
        showToast('작업자가 추가되었습니다.'); document.getElementById('addWorkerForm').reset(); await loadWorkers();
    } catch(e) { showToast(e.message, 'error'); }
});

function editWorker(id) {
    const w = workers.find(x => x.worker_id === id); if (!w) return;
    document.getElementById('editWorkerId').value = w.worker_id;
    document.getElementById('editWorkerName').value = w.worker_name;
    document.getElementById('editJobType').value = w.job_type || '';
    document.getElementById('editWorkerDept').value = w.department_id || '';
    document.getElementById('editWorkerPhone').value = w.phone_number || '';
    document.getElementById('editWorkerHireDate').value = formatDate(w.hire_date);
    document.getElementById('editWorkerNotes').value = w.notes || '';
    document.getElementById('editWorkerStatus').value = w.status || 'active';
    document.getElementById('editEmploymentStatus').value = w.employment_status || 'employed';
    populateDeptSelects();
    document.getElementById('editWorkerDept').value = w.department_id || '';
    document.getElementById('editWorkerModal').classList.remove('hidden');
}
function closeWorkerModal() { document.getElementById('editWorkerModal').classList.add('hidden'); }

document.getElementById('editWorkerForm').addEventListener('submit', async e => {
    e.preventDefault();
    try {
        await api(`/workers/${document.getElementById('editWorkerId').value}`, { method: 'PUT', body: JSON.stringify({
            worker_name: document.getElementById('editWorkerName').value.trim(),
            job_type: document.getElementById('editJobType').value || null,
            department_id: document.getElementById('editWorkerDept').value ? parseInt(document.getElementById('editWorkerDept').value) : null,
            phone_number: document.getElementById('editWorkerPhone').value.trim() || null,
            hire_date: document.getElementById('editWorkerHireDate').value || null,
            notes: document.getElementById('editWorkerNotes').value.trim() || null,
            status: document.getElementById('editWorkerStatus').value,
            employment_status: document.getElementById('editEmploymentStatus').value
        })});
        showToast('수정되었습니다.'); closeWorkerModal(); await loadWorkers();
    } catch(e) { showToast(e.message, 'error'); }
});

async function deactivateWorker(id, name) {
    if (!confirm(`"${name}" 작업자를 비활성화?`)) return;
    try { await api(`/workers/${id}`, { method: 'DELETE' }); showToast('작업자 비활성화 완료'); await loadWorkers(); } catch(e) { showToast(e.message, 'error'); }
}
