/* ===== Vacation CRUD ===== */
let vacTypes = [], vacBalances = [], vacationsLoaded = false, vacUsers = [];

const BALANCE_TYPE_STYLES = {
    AUTO: { label: '기본연차', cls: 'bg-blue-50 text-blue-600' },
    MANUAL: { label: '추가부여', cls: 'bg-purple-50 text-purple-600' },
    CARRY_OVER: { label: '이월연차', cls: 'bg-orange-50 text-orange-600' },
    LONG_SERVICE: { label: '장기근속', cls: 'bg-emerald-50 text-emerald-600' },
    COMPANY_GRANT: { label: '회사부여', cls: 'bg-yellow-50 text-yellow-600' },
};

async function loadVacationsTab() {
    // 연도 셀렉트 초기화
    const sel = document.getElementById('vacYear');
    if (sel && !sel.children.length) {
        const curYear = new Date().getFullYear();
        for (let y = curYear + 1; y >= curYear - 2; y--) {
            const o = document.createElement('option');
            o.value = y; o.textContent = y + '년';
            if (y === curYear) o.selected = true;
            sel.appendChild(o);
        }
    }
    await loadVacTypes();
    await loadVacUsers();
    populateVacDeptFilter();
    await loadVacBalances();
    vacationsLoaded = true;
}

async function loadVacTypes() {
    try {
        const r = await api('/vacations/types?all=true');
        vacTypes = r.data || [];
        renderVacTypeSidebar();
    } catch(e) { console.warn('휴가 유형 로드 실패:', e); }
}

async function loadVacUsers() {
    try {
        const r = await api('/users');
        vacUsers = ((r.data || r) || []).filter(u => u.is_active !== 0 && u.is_active !== false);
    } catch(e) { console.warn('사용자 로드 실패:', e); }
}

function populateVacDeptFilter() {
    const sel = document.getElementById('vacDeptFilter');
    if (!sel) return;
    sel.innerHTML = '<option value="">전체 부서</option>';
    const depts = departmentsCache && departmentsCache.length ? departmentsCache : [];
    depts.forEach(d => {
        sel.innerHTML += `<option value="${d.department_id}">${escHtml(d.department_name)}</option>`;
    });
}

function filterVacBalances() {
    renderVacBalanceTable();
}

function renderVacTypeSidebar() {
    const c = document.getElementById('vacTypeSidebar');
    if (!c) return;
    if (!vacTypes.length) { c.innerHTML = '<p class="text-gray-400 text-center py-4 text-sm">등록된 유형이 없습니다.</p>'; return; }
    c.innerHTML = vacTypes.map(vt => `
        <div class="group flex items-center justify-between p-2 rounded-lg ${vt.is_active ? 'bg-gray-50' : 'bg-gray-50 opacity-50'} hover:bg-blue-50 transition-colors">
            <div class="flex-1 min-w-0">
                <div class="text-sm font-medium text-gray-800 truncate flex items-center gap-1.5">
                    ${escHtml(vt.type_name)}
                    ${vt.is_system ? '<span class="text-[10px] px-1 py-0.5 rounded bg-blue-50 text-blue-500">시스템</span>' : ''}
                    ${vt.is_special ? '<span class="text-[10px] px-1 py-0.5 rounded bg-purple-50 text-purple-500">특별</span>' : ''}
                    ${!vt.is_active ? '<span class="text-[10px] px-1 py-0.5 rounded bg-gray-100 text-gray-400">비활성</span>' : ''}
                </div>
                <div class="text-xs text-gray-400 mt-0.5">
                    ${escHtml(vt.type_code)} | 차감 ${vt.deduct_days}일 | 우선순위 ${vt.priority}
                </div>
            </div>
            <div class="flex gap-0.5 ml-1 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
                <button onclick="editVacType(${vt.id})" class="p-1 text-slate-400 hover:text-slate-600 rounded" title="수정"><i class="fas fa-pen text-[10px]"></i></button>
                ${!vt.is_system ? `<button onclick="deleteVacType(${vt.id},'${(vt.type_name||'').replace(/'/g,"\\'")}')" class="p-1 text-red-300 hover:text-red-500 rounded" title="비활성화"><i class="fas fa-ban text-[10px]"></i></button>` : ''}
            </div>
        </div>`).join('');
}

// 유형 모달
function openVacTypeModal(editId) {
    document.getElementById('vtEditId').value = '';
    document.getElementById('vacTypeForm').reset();
    document.getElementById('vtDeductDays').value = '1.0';
    document.getElementById('vtPriority').value = '99';
    document.getElementById('vacTypeModalTitle').textContent = '휴가 유형 추가';
    document.getElementById('vtCode').readOnly = false;
    if (editId) {
        const vt = vacTypes.find(v => v.id === editId);
        if (!vt) return;
        document.getElementById('vacTypeModalTitle').textContent = '휴가 유형 수정';
        document.getElementById('vtEditId').value = vt.id;
        document.getElementById('vtCode').value = vt.type_code;
        document.getElementById('vtCode').readOnly = !!vt.is_system;
        document.getElementById('vtName').value = vt.type_name;
        document.getElementById('vtDeductDays').value = vt.deduct_days;
        document.getElementById('vtPriority').value = vt.priority;
        document.getElementById('vtDescription').value = vt.description || '';
        document.getElementById('vtSpecial').checked = !!vt.is_special;
    }
    document.getElementById('vacTypeModal').classList.remove('hidden');
}
function closeVacTypeModal() { document.getElementById('vacTypeModal').classList.add('hidden'); }
function editVacType(id) { openVacTypeModal(id); }

document.getElementById('vacTypeForm').addEventListener('submit', async e => {
    e.preventDefault();
    const editId = document.getElementById('vtEditId').value;
    const body = {
        type_code: document.getElementById('vtCode').value.trim().toUpperCase(),
        type_name: document.getElementById('vtName').value.trim(),
        deduct_days: parseFloat(document.getElementById('vtDeductDays').value) || 1.0,
        priority: parseInt(document.getElementById('vtPriority').value) || 99,
        description: document.getElementById('vtDescription').value.trim() || null,
        is_special: document.getElementById('vtSpecial').checked
    };
    try {
        if (editId) {
            await api(`/vacations/types/${editId}`, { method: 'PUT', body: JSON.stringify(body) });
            showToast('휴가 유형이 수정되었습니다.');
        } else {
            await api('/vacations/types', { method: 'POST', body: JSON.stringify(body) });
            showToast('휴가 유형이 추가되었습니다.');
        }
        closeVacTypeModal(); await loadVacTypes();
    } catch(e) { showToast(e.message, 'error'); }
});

async function deleteVacType(id, name) {
    if (!confirm(`"${name}" 유형을 비활성화하시겠습니까?`)) return;
    try { await api(`/vacations/types/${id}`, { method: 'DELETE' }); showToast('비활성화되었습니다.'); await loadVacTypes(); }
    catch(e) { showToast(e.message, 'error'); }
}

// 연차 배정 테이블
async function loadVacBalances() {
    const year = document.getElementById('vacYear')?.value || new Date().getFullYear();
    try {
        const r = await api(`/vacations/balances/year/${year}`);
        // 필드명 정규화 (과도기 호환: worker_id → user_id)
        vacBalances = (r.data || []).map(b => ({
            ...b,
            user_id: b.user_id || b.worker_id,
            user_name: b.user_name || b.worker_name,
        }));
        renderVacBalanceTable();
    } catch(e) {
        document.getElementById('vacBalanceTable').innerHTML = `<div class="text-red-500 text-center py-6"><p class="text-sm">${e.message}</p></div>`;
    }
}

let vacDeptCollapsed = {};

function toggleVacDept(deptName) {
    vacDeptCollapsed[deptName] = !vacDeptCollapsed[deptName];
    const body = document.getElementById('vacDept_' + CSS.escape(deptName));
    const icon = document.getElementById('vacDeptIcon_' + CSS.escape(deptName));
    if (body) body.classList.toggle('hidden');
    if (icon) icon.style.transform = vacDeptCollapsed[deptName] ? 'rotate(-90deg)' : '';
}

function showLongServiceCheckbox(user) {
    // 백엔드 플래그 우선
    if ('long_service_excluded' in user) return true;
    // fallback: hire_date 기준 5년 계산
    if (!user.hire_date) return false;
    const years = (Date.now() - new Date(user.hire_date).getTime()) / (365.25 * 24 * 60 * 60 * 1000);
    return years >= 5;
}

function renderVacBalanceTable() {
    const c = document.getElementById('vacBalanceTable');

    // Apply filters
    const deptFilter = document.getElementById('vacDeptFilter')?.value || '';
    const searchTerm = (document.getElementById('vacSearch')?.value || '').toLowerCase().trim();

    let filtered = [...vacBalances];
    if (deptFilter) filtered = filtered.filter(b => String(b.department_id) === deptFilter);
    if (searchTerm) filtered = filtered.filter(b => (b.user_name || '').toLowerCase().includes(searchTerm));

    // Hide LONG_SERVICE with total_days <= 0 or long_service_excluded
    filtered = filtered.filter(b => {
        if (b.balance_type === 'LONG_SERVICE' && (parseFloat(b.total_days) <= 0 || b.long_service_excluded === true)) return false;
        return true;
    });

    if (!filtered.length) {
        c.innerHTML = '<div class="text-gray-400 text-center py-8 text-sm"><i class="fas fa-calendar-xmark text-3xl mb-2"></i><p>배정된 연차가 없습니다. "자동 계산" 또는 "개별 배정"을 이용하세요.</p></div>';
        return;
    }
    // 부서 -> 사용자 -> 휴가유형 그룹핑
    const deptMap = {};
    filtered.forEach(b => {
        const deptName = b.department_name || '미배정';
        if (!deptMap[deptName]) deptMap[deptName] = {};
        const uid = b.user_id;
        if (!deptMap[deptName][uid]) deptMap[deptName][uid] = { name: b.user_name, hire_date: b.hire_date, department_id: b.department_id, long_service_excluded: b.long_service_excluded, items: [] };
        deptMap[deptName][uid].items.push(b);
    });

    const deptNames = Object.keys(deptMap).sort((a, b) => a === '미배정' ? 1 : b === '미배정' ? -1 : a.localeCompare(b));
    let html = '<div class="space-y-3">';

    deptNames.forEach(deptName => {
        const usersMap = deptMap[deptName];
        const userCount = Object.keys(usersMap).length;
        // 부서 합계
        let dTotal = 0, dUsed = 0;
        Object.values(usersMap).forEach(g => g.items.forEach(b => { dTotal += parseFloat(b.total_days) || 0; dUsed += parseFloat(b.used_days) || 0; }));
        const dRemain = dTotal - dUsed;
        const usagePct = dTotal > 0 ? Math.round((dUsed / dTotal) * 100) : 0;
        const barColor = usagePct >= 80 ? 'bg-red-400' : usagePct >= 50 ? 'bg-amber-400' : 'bg-emerald-400';
        const collapsed = vacDeptCollapsed[deptName];
        const eid = CSS.escape(deptName);

        html += `<div class="border border-gray-200 rounded-lg overflow-hidden">`;
        // 헤더 (클릭으로 접기/펼치기)
        html += `<div onclick="toggleVacDept('${escHtml(deptName).replace(/'/g, "\\'")}')" class="flex items-center justify-between px-4 py-3 bg-slate-50 cursor-pointer hover:bg-slate-100 select-none transition-colors">
            <div class="flex items-center gap-3">
                <i id="vacDeptIcon_${eid}" class="fas fa-chevron-down text-xs text-gray-400 transition-transform" style="${collapsed ? 'transform:rotate(-90deg)' : ''}"></i>
                <span class="text-sm font-bold text-gray-700"><i class="fas fa-building mr-1.5 text-blue-400"></i>${escHtml(deptName)}</span>
                <span class="text-xs text-gray-400">${userCount}명</span>
            </div>
            <div class="flex items-center gap-4">
                <div class="flex items-center gap-2 text-xs">
                    <span class="text-gray-400">배정 <b class="text-gray-600">${dTotal}</b></span>
                    <span class="text-gray-400">사용 <b class="text-gray-600">${dUsed}</b></span>
                    <span class="text-gray-400">잔여 <b class="${dRemain <= 0 ? 'text-red-500' : 'text-emerald-600'}">${dRemain}</b></span>
                </div>
                <div class="w-24 h-2 bg-gray-200 rounded-full overflow-hidden">
                    <div class="${barColor} h-full rounded-full transition-all" style="width:${usagePct}%"></div>
                </div>
                <span class="text-xs font-medium ${usagePct >= 80 ? 'text-red-500' : usagePct >= 50 ? 'text-amber-500' : 'text-emerald-600'}">${usagePct}%</span>
            </div>
        </div>`;
        // 테이블 본문
        html += `<div id="vacDept_${eid}" class="${collapsed ? 'hidden' : ''}">`;
        html += '<table class="w-full text-sm"><thead class="bg-gray-50"><tr>';
        html += '<th class="text-left px-3 py-2 text-xs font-semibold text-gray-500">사용자</th>';
        html += '<th class="text-left px-3 py-2 text-xs font-semibold text-gray-500">입사일</th>';
        html += '<th class="text-left px-3 py-2 text-xs font-semibold text-gray-500">휴가유형</th>';
        html += '<th class="text-center px-3 py-2 text-xs font-semibold text-gray-500">배정</th>';
        html += '<th class="text-center px-3 py-2 text-xs font-semibold text-gray-500">사용</th>';
        html += '<th class="text-center px-3 py-2 text-xs font-semibold text-gray-500">잔여</th>';
        html += '<th class="text-left px-3 py-2 text-xs font-semibold text-gray-500">비고</th>';
        html += '<th class="px-3 py-2 text-xs font-semibold text-gray-500 w-16"></th>';
        html += '</tr></thead><tbody>';

        Object.entries(usersMap).forEach(([uid, g]) => {
            const showLsCheckbox = showLongServiceCheckbox(g);
            g.items.forEach((b, i) => {
                const remaining = parseFloat(b.remaining_days || (b.total_days - b.used_days));
                const remClass = remaining <= 0 ? 'text-red-500 font-semibold' : remaining <= 3 ? 'text-amber-500 font-medium' : 'text-emerald-600';
                const btStyle = b.balance_type && BALANCE_TYPE_STYLES[b.balance_type] ? BALANCE_TYPE_STYLES[b.balance_type] : null;
                html += `<tr class="border-t border-gray-100 hover:bg-gray-50">`;
                if (i === 0) {
                    const rowspan = g.items.length;
                    html += `<td class="px-3 py-2 font-medium text-gray-800" rowspan="${rowspan}">
                        ${escHtml(g.name)}
                        ${showLsCheckbox ? `<div class="mt-1"><label class="flex items-center gap-1 text-xs text-gray-400 cursor-pointer" title="장기근속 제외"><input type="checkbox" class="rounded" ${g.long_service_excluded ? 'checked' : ''} onchange="toggleLongServiceExclusion(${uid}, this.checked)"><span>장기근속 제외</span></label></div>` : ''}
                    </td>`;
                    html += `<td class="px-3 py-2 text-xs text-gray-400" rowspan="${rowspan}">${g.hire_date ? new Date(g.hire_date).toISOString().substring(0,10) : '-'}</td>`;
                }
                html += `<td class="px-3 py-2">
                    <span class="px-1.5 py-0.5 rounded text-xs bg-slate-50 text-slate-600">${escHtml(b.type_name)}</span>
                    ${btStyle ? `<span class="ml-1 px-1.5 py-0.5 rounded text-[10px] ${btStyle.cls}">${btStyle.label}</span>` : ''}
                </td>`;
                html += `<td class="px-3 py-2 text-center">${b.total_days}</td>`;
                html += `<td class="px-3 py-2 text-center">${b.used_days}</td>`;
                html += `<td class="px-3 py-2 text-center ${remClass}">${remaining}</td>`;
                html += `<td class="px-3 py-2 text-xs text-gray-400 truncate max-w-[150px]" title="${escHtml(b.notes||'')}">${escHtml(b.notes||'')}</td>`;
                html += `<td class="px-3 py-2 text-center">
                    <button onclick="editVacBalance(${b.id})" class="p-1 text-slate-400 hover:text-slate-600" title="수정"><i class="fas fa-pen text-xs"></i></button>
                    <button onclick="deleteVacBalance(${b.id})" class="p-1 text-red-300 hover:text-red-500" title="삭제"><i class="fas fa-trash-alt text-xs"></i></button>
                </td>`;
                html += '</tr>';
            });
        });
        html += '</tbody></table></div></div>';
    });
    html += '</div>';
    c.innerHTML = html;
}

// 장기근속 제외 토글
async function toggleLongServiceExclusion(userId, excluded) {
    try {
        await api('/vacations/long-service-exclusion', { method: 'PUT', body: JSON.stringify({ user_id: userId, excluded: excluded }) });
        showToast(excluded ? '장기근속 제외 설정됨' : '장기근속 제외 해제됨');
        await loadVacBalances();
    } catch (e) {
        showToast(e.message, 'error');
        await loadVacBalances(); // revert checkbox state
    }
}

// 자동 계산
async function autoCalcVacation() {
    const year = document.getElementById('vacYear')?.value || new Date().getFullYear();
    const deptFilter = document.getElementById('vacDeptFilter')?.value || '';
    let msg = `${year}년 전체 사용자 연차를 입사일 기준으로 자동 계산합니다.\n기존 배정이 있으면 덮어씁니다. 진행하시겠습니까?`;
    if (deptFilter) {
        const deptName = document.getElementById('vacDeptFilter')?.selectedOptions?.[0]?.textContent || '';
        msg = `${year}년 "${deptName}" 부서 사용자 연차를 자동 계산합니다.\n진행하시겠습니까?`;
    }
    if (!confirm(msg)) return;
    try {
        const body = { year: parseInt(year) };
        if (deptFilter) body.department_id = parseInt(deptFilter);
        const r = await api('/vacations/balances/auto-calculate', { method: 'POST', body: JSON.stringify(body) });
        const count = (r.data && (r.data.calculated || r.data.count)) || 0;
        const skipped = (r.data && r.data.skipped) || 0;
        showToast(`${count}명 자동 배정 완료${skipped ? `, ${skipped}명 건너뜀` : ''}`);
        await loadVacBalances();
    } catch(e) { showToast(e.message, 'error'); }
}

// balance_type 변경 시 expires_at 기본값 조정
function onBalanceTypeChange() {
    const bt = document.getElementById('vbBalanceType').value;
    const expiresInput = document.getElementById('vbExpiresAt');
    const year = document.getElementById('vacYear')?.value || new Date().getFullYear();

    if (bt === 'LONG_SERVICE') {
        expiresInput.disabled = true;
        expiresInput.value = '';
    } else {
        expiresInput.disabled = false;
        if (bt === 'CARRY_OVER') {
            // 해당연 2월말
            const febEnd = new Date(parseInt(year), 2, 0); // month=2, day=0 = last day of Feb
            expiresInput.value = febEnd.toISOString().substring(0, 10);
        } else {
            // 연말
            expiresInput.value = `${year}-12-31`;
        }
    }
}

// 개별 배정 모달
function openVacBalanceModal(editId) {
    document.getElementById('vbEditId').value = '';
    document.getElementById('vacBalanceForm').reset();
    document.getElementById('vbTotalDays').value = '0';
    document.getElementById('vbUsedDays').value = '0';
    document.getElementById('vbBalanceType').value = 'AUTO';
    document.getElementById('vbExpiresAt').disabled = false;
    document.getElementById('vacBalModalTitle').textContent = '연차 배정';

    const year = document.getElementById('vacYear')?.value || new Date().getFullYear();
    document.getElementById('vbExpiresAt').value = `${year}-12-31`;

    // 사용자 셀렉트 (부서별 optgroup)
    const uSel = document.getElementById('vbUser');
    uSel.innerHTML = '<option value="">선택</option>';
    const byDept = {};
    vacUsers.forEach(u => {
        const dept = u.department_name || '부서 미지정';
        if (!byDept[dept]) byDept[dept] = [];
        byDept[dept].push(u);
    });
    Object.keys(byDept).sort().forEach(dept => {
        const group = document.createElement('optgroup');
        group.label = dept;
        byDept[dept].forEach(u => {
            const o = document.createElement('option');
            o.value = u.id;
            o.textContent = u.name || u.username;
            group.appendChild(o);
        });
        uSel.appendChild(group);
    });
    // 유형 셀렉트
    const tSel = document.getElementById('vbType');
    tSel.innerHTML = '<option value="">선택</option>';
    vacTypes.filter(t => t.is_active).forEach(t => { tSel.innerHTML += `<option value="${t.id}">${escHtml(t.type_name)} (${escHtml(t.type_code)})</option>`; });
    if (editId) {
        const b = vacBalances.find(x => x.id === editId);
        if (!b) return;
        document.getElementById('vacBalModalTitle').textContent = '배정 수정';
        document.getElementById('vbEditId').value = b.id;
        uSel.value = b.user_id;
        uSel.disabled = true;
        tSel.value = b.vacation_type_id;
        tSel.disabled = true;
        if (b.balance_type) document.getElementById('vbBalanceType').value = b.balance_type;
        document.getElementById('vbTotalDays').value = b.total_days;
        document.getElementById('vbUsedDays').value = b.used_days;
        if (b.expires_at) document.getElementById('vbExpiresAt').value = b.expires_at.substring(0, 10);
        document.getElementById('vbNotes').value = b.notes || '';
        if (b.balance_type === 'LONG_SERVICE') document.getElementById('vbExpiresAt').disabled = true;
    } else {
        uSel.disabled = false;
        tSel.disabled = false;
    }
    document.getElementById('vacBalanceModal').classList.remove('hidden');
}
function closeVacBalanceModal() {
    document.getElementById('vacBalanceModal').classList.add('hidden');
    document.getElementById('vbUser').disabled = false;
    document.getElementById('vbType').disabled = false;
    document.getElementById('vbExpiresAt').disabled = false;
}
function editVacBalance(id) { openVacBalanceModal(id); }

document.getElementById('vacBalanceForm').addEventListener('submit', async e => {
    e.preventDefault();
    const editId = document.getElementById('vbEditId').value;
    try {
        if (editId) {
            await api(`/vacations/balances/${editId}`, { method: 'PUT', body: JSON.stringify({
                total_days: parseFloat(document.getElementById('vbTotalDays').value) || 0,
                used_days: parseFloat(document.getElementById('vbUsedDays').value) || 0,
                balance_type: document.getElementById('vbBalanceType').value,
                expires_at: document.getElementById('vbExpiresAt').value || null,
                notes: document.getElementById('vbNotes').value.trim() || null
            })});
            showToast('수정되었습니다.');
        } else {
            const year = document.getElementById('vacYear')?.value || new Date().getFullYear();
            await api('/vacations/balances', { method: 'POST', body: JSON.stringify({
                user_id: parseInt(document.getElementById('vbUser').value),
                vacation_type_id: parseInt(document.getElementById('vbType').value),
                year: parseInt(year),
                total_days: parseFloat(document.getElementById('vbTotalDays').value) || 0,
                used_days: parseFloat(document.getElementById('vbUsedDays').value) || 0,
                balance_type: document.getElementById('vbBalanceType').value,
                expires_at: document.getElementById('vbExpiresAt').value || null,
                notes: document.getElementById('vbNotes').value.trim() || null
            })});
            showToast('배정되었습니다.');
        }
        closeVacBalanceModal(); await loadVacBalances();
    } catch(e) { showToast(e.message, 'error'); }
});

async function deleteVacBalance(id) {
    if (!confirm('이 배정을 삭제하시겠습니까?')) return;
    try { await api(`/vacations/balances/${id}`, { method: 'DELETE' }); showToast('삭제되었습니다.'); await loadVacBalances(); }
    catch(e) { showToast(e.message, 'error'); }
}
