@extends('layouts.app')

@section('title', '기안 작성')

@section('content')
    <div class="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 mb-6">
        <h1 class="text-2xl font-bold text-gray-800">기안 작성</h1>
        <a href="{{ route('approvals.drafts') }}" class="text-gray-600 hover:text-gray-800 text-sm">
            &larr; 기안함으로 돌아가기
        </a>
    </div>

    <div>
        <div class="bg-white rounded-lg shadow-sm p-6">
            <h2 class="text-lg font-semibold text-gray-800 mb-4">문서 내용</h2>

            {{-- 양식 선택 (2단계: 분류 → 양식) + 설명 카드 --}}
            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-1">양식 <span class="text-red-500">*</span></label>
                <div class="flex gap-3" style="align-items: flex-start;">
                    <div style="width: 30%; min-width: 180px;" class="shrink-0">
                        <select id="form_category" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 font-medium">
                        </select>
                        <select id="form_id" class="mt-2 w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
                            @foreach($forms as $form)
                                <option value="{{ $form->id }}">{{ $form->name }}</option>
                            @endforeach
                        </select>
                        <button type="button" id="expense-load-btn" style="display: none;" onclick="openExpenseLoadModal()"
                                class="mt-2 w-full px-3 py-2 bg-amber-50 text-amber-700 hover:bg-amber-100 border border-amber-200 rounded-lg text-sm font-medium transition inline-flex items-center justify-center gap-1">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/>
                            </svg>
                            불러오기
                        </button>
                    </div>
                    <div id="form-description-card" style="flex: 1; display: none;">
                        <div class="rounded-lg border p-3 text-sm transition-all" id="form-desc-inner">
                            <div class="flex items-start gap-2">
                                <div id="form-desc-icon" class="shrink-0 mt-0.5"></div>
                                <div>
                                    <div id="form-desc-title" class="font-semibold text-sm mb-1"></div>
                                    <div id="form-desc-text" class="text-xs leading-relaxed"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            {{-- 제목 --}}
            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-1">제목 <span class="text-red-500">*</span></label>
                <input type="text" id="title" maxlength="200" placeholder="결재 제목을 입력하세요"
                       class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
            </div>

            {{-- 결재선 --}}
            <div class="mb-4">
                <div class="flex items-center justify-between mb-1">
                    <label class="block text-sm font-medium text-gray-700">결재선</label>
                    <div class="flex items-center gap-2">
                        <select id="quick-line-select" onchange="applyQuickLine(this.value)"
                                class="px-2 py-1.5 border border-gray-300 rounded-lg text-xs focus:outline-none focus:ring-2 focus:ring-blue-500"
                                style="min-width: 160px;">
                            <option value="">결재선 선택</option>
                            @foreach($lines as $line)
                                <option value="{{ $line->id }}" {{ ($defaultLine?->id ?? '') == $line->id ? 'selected' : '' }}>
                                    {{ $line->name }} ({{ count($line->steps ?? []) }}단계)
                                </option>
                            @endforeach
                        </select>
                        <button type="button" onclick="openApprovalLineModal()"
                                class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-100 rounded-lg text-xs font-medium transition whitespace-nowrap">
                            세부 설정
                        </button>
                    </div>
                </div>
                <div id="approval-line-summary" class="p-3 bg-gray-50 rounded-lg border border-gray-200 flex items-center">
                    <span class="text-sm text-gray-400">결재선이 설정되지 않았습니다.</span>
                </div>
            </div>

            {{-- 긴급 여부 --}}
            <div class="mb-4">
                <label class="inline-flex items-center gap-2 cursor-pointer">
                    <input type="checkbox" id="is_urgent" class="rounded border-gray-300 text-red-600 focus:ring-red-500">
                    <span class="text-sm text-gray-700">긴급</span>
                </label>
            </div>

            {{-- 본문 (일반 양식) --}}
            <div id="body-area" class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-1">
                    본문
                    <label class="inline-flex items-center gap-1 ml-3 cursor-pointer">
                        <input type="checkbox" id="useEditor" onchange="toggleEditor()"
                               class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
                        <span class="text-xs text-gray-500 font-normal">편집기</span>
                    </label>
                </label>
                <textarea id="body" rows="12" placeholder="기안 내용을 입력하세요..."
                          class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                          style="min-height: 300px;"></textarea>
                <div id="quill-container" style="display: none; min-height: 300px;"></div>
            </div>

            {{-- 휴가/근태신청/사유서 전용 폼 --}}
            @include('approvals.partials._leave-form', [
                'employees' => $employees ?? collect(),
            ])

            {{-- 재직증명서 전용 폼 --}}
            @include('approvals.partials._certificate-form', [
                'employees' => $employees ?? collect(),
            ])

            {{-- 경력증명서 전용 폼 --}}
            @include('approvals.partials._career-cert-form', [
                'employees' => $employees ?? collect(),
            ])

            {{-- 위촉증명서 전용 폼 --}}
            @include('approvals.partials._appointment-cert-form', [
                'employees' => $employees ?? collect(),
            ])

            {{-- 사직서 전용 폼 --}}
            @include('approvals.partials._resignation-form', [
                'employees' => $employees ?? collect(),
            ])

            {{-- 사용인감계 전용 폼 --}}
            @include('approvals.partials._seal-usage-form', [
                'tenantInfo' => $tenantInfo ?? [],
            ])

            {{-- 위임장 전용 폼 --}}
            @include('approvals.partials._delegation-form', [
                'tenantInfo' => $tenantInfo ?? [],
            ])

            {{-- 이사회의사록 전용 폼 --}}
            @include('approvals.partials._board-minutes-form', [
                'tenantInfo' => $tenantInfo ?? [],
            ])

            {{-- 공문서 전용 폼 --}}
            @include('approvals.partials._official-letter-form', [
                'tenantInfo' => $tenantInfo ?? [],
            ])

            {{-- 연차사용촉진 1차 통지서 --}}
            @include('approvals.partials._leave-promotion-1st-form', [
                'tenantInfo' => $tenantInfo ?? [],
                'employees' => $employees ?? collect(),
            ])

            {{-- 연차사용촉진 2차 통지서 --}}
            @include('approvals.partials._leave-promotion-2nd-form', [
                'tenantInfo' => $tenantInfo ?? [],
                'employees' => $employees ?? collect(),
            ])

            {{-- 견적서 전용 폼 --}}
            @include('approvals.partials._quotation-form', [
                'tenantInfo' => $tenantInfo ?? [],
            ])

            {{-- 지출결의서 전용 폼 --}}
            @include('approvals.partials._expense-form', [
                'initialData' => [],
                'cards' => $cards ?? collect(),
                'accounts' => $accounts ?? collect(),
            ])

            {{-- 품의서 전용 폼 --}}
            @include('approvals.partials._purchase-request-form', [
                'initialData' => [],
            ])

            {{-- 액션 버튼 --}}
            <div class="border-t pt-4 mt-4 flex gap-2 justify-end">
                <button onclick="saveApproval('draft')"
                        class="bg-gray-600 hover:bg-gray-700 text-white px-6 py-2 rounded-lg transition text-sm font-medium">
                    임시저장
                </button>
                <button onclick="saveApproval('submit')"
                        class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg transition text-sm font-medium">
                    상신
                </button>
            </div>
        </div>
    </div>

    {{-- 결재선 모달 --}}
    <div id="approval-line-modal" style="display: none;" class="fixed inset-0 z-50">
        <div class="absolute inset-0 bg-black/50" onclick="closeApprovalLineModal()"></div>
        <div class="relative flex items-center justify-center min-h-full p-4">
            <div class="bg-white rounded-xl shadow-2xl w-full overflow-hidden relative" style="max-width: 720px;">
                <button type="button" onclick="closeApprovalLineModal()"
                        class="absolute top-3 right-3 z-10 p-1 text-gray-400 hover:text-gray-600 transition bg-white rounded-full shadow-sm">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                    </svg>
                </button>
                <div class="overflow-y-auto" style="max-height: 70vh;">
                    @php
                        $defaultLine = collect($lines)->firstWhere('is_default', true);
                    @endphp
                    @include('approvals.partials._approval-line-editor', [
                        'lines' => $lines,
                        'initialSteps' => $defaultLine?->steps ?? [],
                        'selectedLineId' => $defaultLine?->id ?? '',
                    ])
                </div>
                <div class="px-5 py-3 border-t border-gray-200 flex justify-end">
                    <button type="button" onclick="closeApprovalLineModal()"
                            class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm font-medium transition">
                        확인
                    </button>
                </div>
            </div>
        </div>
    </div>
    {{-- 지출결의서 불러오기 모달 --}}
    <div id="expense-load-modal" style="display: none;" class="fixed inset-0 z-50">
        <div class="absolute inset-0 bg-black/50" onclick="closeExpenseLoadModal()"></div>
        <div class="relative flex items-center justify-center min-h-full p-4">
            <div class="bg-white rounded-xl shadow-2xl w-full overflow-hidden relative" style="max-width: 640px;">
                <div class="px-5 py-4 border-b border-gray-200 flex items-center justify-between">
                    <h3 class="text-lg font-semibold text-gray-800">지출결의서 불러오기</h3>
                    <button type="button" onclick="closeExpenseLoadModal()"
                            class="p-1 text-gray-400 hover:text-gray-600 transition">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                        </svg>
                    </button>
                </div>
                <div class="overflow-y-auto" style="max-height: 60vh;">
                    <div id="expense-load-list" class="p-4">
                        <div class="text-center text-sm text-gray-400 py-8">불러오는 중...</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@push('styles')
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet">
<style>
    #quill-container .ql-editor { min-height: 260px; font-size: 0.875rem; }
    #quill-container .ql-toolbar { border-radius: 0.5rem 0.5rem 0 0; border-color: #d1d5db; }
    #quill-container .ql-container { border-radius: 0 0 0.5rem 0.5rem; border-color: #d1d5db; }
    #summary-sortable .step-card {
        cursor: grab;
        position: relative;
        margin-right: 24px;
        user-select: none;
        transition: transform 0.15s ease, box-shadow 0.15s ease;
    }
    #summary-sortable .step-card:last-child { margin-right: 0; }
    #summary-sortable .step-card:not(:last-child)::after {
        content: '→';
        position: absolute;
        right: -18px;
        top: 50%;
        transform: translateY(-50%);
        color: #d1d5db;
        font-size: 14px;
        pointer-events: none;
    }
    #summary-sortable .step-card:hover {
        box-shadow: 0 2px 8px rgba(0,0,0,0.08);
        transform: translateY(-1px);
    }
    #summary-sortable .step-card:active { cursor: grabbing; }
    #summary-sortable .step-card.sortable-ghost { opacity: 0.3; }
    #summary-sortable .step-card.sortable-chosen {
        box-shadow: 0 4px 12px rgba(0,0,0,0.15);
        transform: translateY(-2px);
    }
</style>
@endpush

@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
<script>
let quillInstance = null;
var summarySortableInstance = null;
const formBodyTemplates = @json($forms->pluck('body_template', 'id'));
const formCodes = @json($forms->pluck('code', 'id'));
const linesData = @json($lines);
let isExpenseForm = false;
let isPurchaseRequestForm = false;

const formDescriptions = {
    BUSINESS_DRAFT: {
        title: '업무기안서', icon: '📄',
        color: 'border-slate-200 bg-slate-50', titleColor: 'text-slate-800', textColor: 'text-slate-600',
        text: '업무 추진에 필요한 사항을 기안하여 결재를 받는 기본 문서입니다. 프로젝트 계획, 업무 협조 요청, 내부 제안 등 정형화된 양식이 없는 일반적인 업무 보고·요청에 사용합니다.',
    },
    official_letter: {
        title: '공문서', icon: '📨',
        color: 'border-blue-200 bg-blue-50', titleColor: 'text-blue-800', textColor: 'text-blue-600',
        text: '외부 기관이나 거래처에 발송하는 공식 문서입니다. 문서번호, 수신처, 제목, 본문, 붙임 서류를 기재하며, 승인 후 회사 직인이 날인된 공문서로 사용합니다.',
    },
    leave: {
        title: '휴가신청', icon: '🏖️',
        color: 'border-sky-200 bg-sky-50', titleColor: 'text-sky-800', textColor: 'text-sky-600',
        text: '연차, 반차, 병가, 경조사 등 휴가를 사전에 신청하는 문서입니다. 휴가 유형, 기간, 사유를 기재하며, 승인 후 근태에 자동 반영됩니다.',
    },
    attendance_request: {
        title: '근태신청', icon: '🕐',
        color: 'border-indigo-200 bg-indigo-50', titleColor: 'text-indigo-800', textColor: 'text-indigo-600',
        text: '외근, 출장, 조퇴, 지각 등 정상 근무 외 근태 변경 사항을 신청하는 문서입니다. 근태 유형과 해당 일시를 기재하여 승인을 받습니다.',
    },
    reason_report: {
        title: '사유서', icon: '✏️',
        color: 'border-rose-200 bg-rose-50', titleColor: 'text-rose-800', textColor: 'text-rose-600',
        text: '지각, 결근, 조퇴 등 근태 이상 사항에 대한 사유를 소명하는 문서입니다. 사유 발생일과 상세 사유를 기재하여 사후 보고합니다.',
    },
    expense: {
        title: '지출결의서', icon: '💰',
        color: 'border-amber-200 bg-amber-50', titleColor: 'text-amber-800', textColor: 'text-amber-700',
        text: '이미 발생한 지출에 대해 사후 보고하는 문서입니다. 법인카드 사용 내역, 계좌이체 등 실제 지출이 완료된 건에 대해 증빙자료와 함께 결재를 요청합니다.',
    },
    employment_cert: {
        title: '재직증명서', icon: '🏢',
        color: 'border-cyan-200 bg-cyan-50', titleColor: 'text-cyan-800', textColor: 'text-cyan-600',
        text: '현재 재직 중임을 증명하는 공식 문서입니다. 은행 제출, 관공서 제출, 비자 신청 등의 용도로 발급하며, 승인 후 PDF로 출력할 수 있습니다.',
    },
    career_cert: {
        title: '경력증명서', icon: '📊',
        color: 'border-violet-200 bg-violet-50', titleColor: 'text-violet-800', textColor: 'text-violet-600',
        text: '재직 또는 퇴직 사원의 경력 사항을 증명하는 문서입니다. 근무 기간, 부서, 직위 등을 포함하며, 승인 후 PDF로 출력할 수 있습니다.',
    },
    appointment_cert: {
        title: '위촉증명서', icon: '🤝',
        color: 'border-emerald-200 bg-emerald-50', titleColor: 'text-emerald-800', textColor: 'text-emerald-600',
        text: '위촉직(프리랜서, 자문위원 등)의 위촉 사실을 증명하는 문서입니다. 위촉 기간, 담당 업무 등을 포함하며, 승인 후 PDF로 출력할 수 있습니다.',
    },
    resignation: {
        title: '사직서', icon: '📮',
        color: 'border-gray-300 bg-gray-50', titleColor: 'text-gray-800', textColor: 'text-gray-600',
        text: '퇴직 의사를 공식적으로 표명하는 문서입니다. 사직 사유와 희망 퇴직일을 기재하며, 결재 완료 후 퇴직 절차가 진행됩니다.',
    },
    seal_usage: {
        title: '사용인감계', icon: '🔏',
        color: 'border-rose-200 bg-rose-50', titleColor: 'text-rose-800', textColor: 'text-rose-600',
        text: '법인인감, 사용인감 등 회사 인감의 사용을 신청하는 문서입니다. 인감 종류, 용도, 제출처를 기재하며, 승인 후 인감을 사용할 수 있습니다.',
    },
    delegation: {
        title: '위임장', icon: '📜',
        color: 'border-amber-200 bg-amber-50', titleColor: 'text-amber-800', textColor: 'text-amber-600',
        text: '법인의 업무를 대리인에게 위임하는 문서입니다. 위임인(회사), 수임인(대리인), 위임사항, 위임기간을 기재하며, 승인 후 위임장으로 사용할 수 있습니다.',
    },
    board_minutes: {
        title: '이사회의사록', icon: '📋',
        color: 'border-slate-300 bg-slate-50', titleColor: 'text-slate-800', textColor: 'text-slate-600',
        text: '이사회 개최 내용을 기록하는 공식 문서입니다. 일시, 장소, 출석현황, 의안, 의사경과, 기명날인 등을 기재하며, 법적 효력을 갖는 회의록입니다.',
    },
    leave_promotion_1st: {
        title: '연차사용촉진 통지서 (1차)', icon: '📅',
        color: 'border-orange-200 bg-orange-50', titleColor: 'text-orange-800', textColor: 'text-orange-600',
        text: '근로기준법 제61조에 따른 연차 사용 촉진 1차 통지서입니다. 잔여 연차 현황을 안내하고, 사용계획 제출기한을 지정하여 직원에게 통보합니다.',
    },
    leave_promotion_2nd: {
        title: '연차사용촉진 통지서 (2차)', icon: '🚨',
        color: 'border-red-200 bg-red-50', titleColor: 'text-red-800', textColor: 'text-red-600',
        text: '1차 통지 후에도 사용 시기를 제출하지 않은 직원에게 회사가 휴가일을 지정하는 2차 통지서입니다. 근로기준법 제61조에 따른 법적 효력이 있습니다.',
    },
    quotation: {
        title: '견적서', icon: '💵',
        color: 'border-green-200 bg-green-50', titleColor: 'text-green-800', textColor: 'text-green-600',
        text: '고객에게 제공할 물품/서비스의 가격을 견적하는 문서입니다. 품목, 수량, 단가, 공급가액, 세액을 기재하며, 승인 후 견적서로 사용할 수 있습니다.',
    },
    pr_expense: {
        title: '지출품의서', icon: '📋',
        color: 'border-orange-200 bg-orange-50', titleColor: 'text-orange-800', textColor: 'text-orange-700',
        text: '지출이 발생하기 전 사전 승인을 받는 문서입니다. 예산 범위 내에서 지출 항목과 금액을 기재하여 사전에 승락을 받습니다.',
    },
    pr_contract: {
        title: '계약체결품의서', icon: '📝',
        color: 'border-purple-200 bg-purple-50', titleColor: 'text-purple-800', textColor: 'text-purple-700',
        text: '외부 업체와의 계약 체결 전 승인을 받는 문서입니다. 계약 상대방, 계약 내용, 기간, 금액, 주요 조건 등을 명시하여 계약 진행에 대한 사전 승락을 받습니다.',
    },
    pr_purchase: {
        title: '구매품의서', icon: '🛒',
        color: 'border-blue-200 bg-blue-50', titleColor: 'text-blue-800', textColor: 'text-blue-700',
        text: '물품 구매 전 사전 승인을 받는 문서입니다. 구매할 품목, 수량, 단가, 납품업체 등을 기재하여 구매 진행에 대한 사전 승락을 받습니다.',
    },
    pr_trip: {
        title: '출장품의서', icon: '✈️',
        color: 'border-green-200 bg-green-50', titleColor: 'text-green-800', textColor: 'text-green-700',
        text: '출장 전 계획 승인을 받는 문서입니다. 출장지, 기간, 업무 내용, 예상 경비(교통비·숙박비·식비 등)를 기재하여 출장 진행에 대한 사전 승락을 받습니다.',
    },
    pr_settlement: {
        title: '비용정산품의서', icon: '🧾',
        color: 'border-teal-200 bg-teal-50', titleColor: 'text-teal-800', textColor: 'text-teal-700',
        text: '업무 수행 중 발생한 비용의 정산 승인을 받는 문서입니다. 사용일자별 항목과 금액을 기재하고, 법인카드 사용 또는 개인 선지출 여부를 명시합니다.',
    },
};

// 2단계 분류 정의 (코드 → 카테고리)
const formCategoryMap = {
    BUSINESS_DRAFT: '일반', official_letter: '일반',
    leave: '인사/근태', attendance_request: '인사/근태', resignation: '인사/근태', reason_report: '인사/근태', delegation: '인사/근태', board_minutes: '인사/근태', leave_promotion_1st: '인사/근태', leave_promotion_2nd: '인사/근태',
    employment_cert: '증명서', career_cert: '증명서', appointment_cert: '증명서', seal_usage: '증명서',
    pr_expense: '품의', pr_contract: '품의', pr_purchase: '품의', pr_trip: '품의', pr_settlement: '품의',
    quotation: '재무', expense: '재무',
};
const categoryIcons = {
    '일반': '📄', '인사/근태': '👤', '증명서': '📜', '품의': '📋', '재무': '💰',
};
const categoryOrder = ['일반', '인사/근태', '증명서', '품의', '재무'];

// formId → code 역맵, formId → name
const formNames = @json($forms->pluck('name', 'id'));

function buildCategoryOptions() {
    const catSelect = document.getElementById('form_category');
    const formSelect = document.getElementById('form_id');
    const usedCategories = new Set();

    // form_id의 옵션에서 사용 가능한 카테고리 수집
    Array.from(formSelect.options).forEach(opt => {
        const code = formCodes[opt.value];
        const cat = formCategoryMap[code];
        if (cat) usedCategories.add(cat);
    });

    catSelect.innerHTML = '';
    categoryOrder.forEach(cat => {
        if (!usedCategories.has(cat)) return;
        const opt = document.createElement('option');
        opt.value = cat;
        opt.textContent = (categoryIcons[cat] || '') + ' ' + cat;
        catSelect.appendChild(opt);
    });
}

function filterFormsByCategory(category) {
    const formSelect = document.getElementById('form_id');
    const currentVal = formSelect.value;
    let firstMatch = null;
    let hasCurrentInCategory = false;

    Array.from(formSelect.options).forEach(opt => {
        const code = formCodes[opt.value];
        const cat = formCategoryMap[code] || '일반';
        const show = cat === category;
        opt.style.display = show ? '' : 'none';
        opt.disabled = !show;
        if (show && !firstMatch) firstMatch = opt.value;
        if (show && opt.value === currentVal) hasCurrentInCategory = true;
    });

    if (!hasCurrentInCategory && firstMatch) {
        formSelect.value = firstMatch;
    }

    formSelect.dispatchEvent(new Event('change'));
}

function selectCategoryByFormId(formId) {
    const code = formCodes[formId];
    const cat = formCategoryMap[code];
    if (cat) {
        document.getElementById('form_category').value = cat;
        filterFormsByCategory(cat);
    }
}

function updateFormDescription(formId) {
    const code = formCodes[formId];
    const desc = formDescriptions[code];
    const card = document.getElementById('form-description-card');
    if (!desc) { card.style.display = 'none'; return; }

    const inner = document.getElementById('form-desc-inner');
    inner.className = 'rounded-lg border p-3 text-sm transition-all ' + desc.color;
    document.getElementById('form-desc-icon').innerHTML = '<span style="font-size: 1.25rem;">' + desc.icon + '</span>';
    document.getElementById('form-desc-title').className = 'font-semibold text-sm mb-1 ' + desc.titleColor;
    document.getElementById('form-desc-title').textContent = desc.title;
    document.getElementById('form-desc-text').className = 'text-xs leading-relaxed ' + desc.textColor;
    document.getElementById('form-desc-text').textContent = desc.text;
    card.style.display = '';
}
let isLeaveForm = false;
let isCertForm = false;
let isCareerCertForm = false;
let isAppointmentCertForm = false;
let isResignationForm = false;
let isSealUsageForm = false;
let isDelegationForm = false;
let isBoardMinutesForm = false;
let isQuotationForm = false;
let isOfficialLetterForm = false;
let isLeavePromotion1stForm = false;
let isLeavePromotion2ndForm = false;

// 양식코드별 표시할 유형 목록
const leaveTypesByFormCode = {
    leave: [
        { value: 'annual', label: '연차' },
        { value: 'half_am', label: '오전반차' },
        { value: 'half_pm', label: '오후반차' },
        { value: 'sick', label: '병가' },
        { value: 'family', label: '경조사' },
        { value: 'maternity', label: '출산' },
        { value: 'parental', label: '육아' },
    ],
    attendance_request: [
        { value: 'business_trip', label: '출장' },
        { value: 'remote', label: '재택근무' },
        { value: 'field_work', label: '외근' },
        { value: 'early_leave', label: '조퇴' },
    ],
    reason_report: [
        { value: 'late_reason', label: '지각사유서' },
        { value: 'absent_reason', label: '결근사유서' },
    ],
};

function populateLeaveTypes(formCode) {
    const select = document.getElementById('leave-type');
    select.innerHTML = '';
    const types = leaveTypesByFormCode[formCode] || [];
    types.forEach(t => {
        const opt = document.createElement('option');
        opt.value = t.value;
        opt.textContent = t.label;
        select.appendChild(opt);
    });
}

function getLeaveFormData() {
    return {
        user_id: parseInt(document.getElementById('leave-user-id').value),
        leave_type: document.getElementById('leave-type').value,
        start_date: document.getElementById('leave-start-date').value,
        end_date: document.getElementById('leave-end-date').value,
        reason: document.getElementById('leave-reason').value.trim() || null,
    };
}

function buildLeaveBody(data) {
    const typeSelect = document.getElementById('leave-type');
    const userSelect = document.getElementById('leave-user-id');
    const typeName = typeSelect.options[typeSelect.selectedIndex]?.text || data.leave_type;
    const userName = userSelect.options[userSelect.selectedIndex]?.text || '';

    const rows = [
        ['신청자', userName],
        ['유형', typeName],
    ];

    const fmtDate = (d) => (d || '').replace('T', ' ');
    if (data.start_date === data.end_date) {
        rows.push(['대상일', fmtDate(data.start_date)]);
    } else {
        rows.push(['기간', fmtDate(data.start_date) + ' ~ ' + fmtDate(data.end_date)]);
    }

    if (data.reason) {
        rows.push(['사유', data.reason]);
    }

    let html = '<p>아래와 같이 신청합니다.</p>';
    html += '<table style="border-collapse:collapse; width:100%; margin-top:12px; font-size:14px;">';
    rows.forEach(([label, value]) => {
        html += '<tr><th style="padding:8px 12px; background:#f8f9fa; border:1px solid #dee2e6; text-align:left; width:120px; font-weight:600;">'
            + escapeHtml(label) + '</th><td style="padding:8px 12px; border:1px solid #dee2e6;">'
            + escapeHtml(value) + '</td></tr>';
    });
    html += '</table>';
    return html;
}

function escapeHtml(str) {
    if (!str) return '';
    const div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
}

function toggleEditor() {
    const useEditor = document.getElementById('useEditor').checked;
    const textarea = document.getElementById('body');
    const container = document.getElementById('quill-container');

    if (useEditor) {
        container.style.display = '';
        textarea.style.display = 'none';
        if (!quillInstance) {
            quillInstance = new Quill('#quill-container', {
                theme: 'snow',
                modules: {
                    toolbar: [
                        [{ 'header': [1, 2, 3, false] }],
                        ['bold', 'italic', 'underline', 'strike'],
                        [{ 'color': [] }, { 'background': [] }],
                        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
                        [{ 'align': [] }],
                        ['blockquote', 'code-block'],
                        ['link'],
                        ['clean'],
                    ],
                },
                placeholder: '기안 내용을 입력하세요...',
            });
        }
        const text = textarea.value.trim();
        if (text) {
            if (/<[a-z][\s\S]*>/i.test(text)) {
                quillInstance.root.innerHTML = text;
            } else {
                quillInstance.setText(text);
            }
        }
    } else {
        container.style.display = 'none';
        textarea.style.display = '';
        if (quillInstance) {
            const html = quillInstance.root.innerHTML;
            textarea.value = (html === '<p><br></p>') ? '' : html;
        }
    }
}

function getBodyContent() {
    const useEditor = document.getElementById('useEditor')?.checked;
    if (useEditor && quillInstance) {
        const html = quillInstance.root.innerHTML;
        return (html === '<p><br></p>') ? '' : html;
    }
    return document.getElementById('body').value;
}

function openApprovalLineModal() {
    document.getElementById('approval-line-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeApprovalLineModal() {
    document.getElementById('approval-line-modal').style.display = 'none';
    document.body.style.overflow = '';
    updateApprovalLineSummary();

    // 모달 내부 결재선 선택과 외부 드롭다운 동기화
    const editorEl = document.getElementById('approval-line-editor');
    if (editorEl && editorEl._x_dataStack) {
        document.getElementById('quick-line-select').value = editorEl._x_dataStack[0].selectedLineId || '';
    }
}

function updateApprovalLineSummary() {
    const editorEl = document.getElementById('approval-line-editor');
    if (!editorEl || !editorEl._x_dataStack) return;

    const alpineData = editorEl._x_dataStack[0];
    const steps = alpineData.steps;
    const references = alpineData.references || [];
    const summaryEl = document.getElementById('approval-line-summary');

    if (summarySortableInstance) { summarySortableInstance.destroy(); summarySortableInstance = null; }

    if ((!steps || steps.length === 0) && references.length === 0) {
        summaryEl.className = 'p-3 bg-gray-50 rounded-lg border border-gray-200 flex items-center';
        summaryEl.innerHTML = '<span class="text-sm text-gray-400">결재선이 설정되지 않았습니다.</span>';
        return;
    }

    const typeCounters = { approval: 0, agreement: 0 };
    const typeLabels = { approval: '결재', agreement: '합의' };
    const typeBg = { approval: 'bg-blue-50 border-blue-100', agreement: 'bg-green-50 border-green-100' };
    const typeLabelColor = { approval: 'text-blue-600', agreement: 'text-green-600' };

    // 결재선 카드
    const approvalCards = [];
    steps.forEach(function(s, i) {
        typeCounters[s.step_type] = (typeCounters[s.step_type] || 0) + 1;
        var count = typeCounters[s.step_type];
        var label = typeLabels[s.step_type] || s.step_type;
        var bg = typeBg[s.step_type] || 'bg-blue-50 border-blue-100';
        var labelColor = typeLabelColor[s.step_type] || 'text-blue-600';
        var stepLabel = count + '차 ' + label;
        var position = s.position || '';

        approvalCards.push(
            '<div class="step-card text-center px-3 py-2 rounded-lg border ' + bg + '" data-index="' + i + '" style="min-width: 72px;">' +
            '<div class="text-xs font-medium ' + labelColor + '">' + escapeHtml(stepLabel) + '</div>' +
            (position ? '<div class="text-xs text-gray-400 mt-0.5">' + escapeHtml(position) + '</div>' : '') +
            '<div class="text-sm font-semibold text-gray-800 mt-0.5">' + escapeHtml(s.user_name) + '</div>' +
            '</div>'
        );
    });

    // 참조선 카드
    const refCards = [];
    references.forEach(function(r) {
        var position = r.position || '';
        refCards.push(
            '<div class="text-center px-3 py-2 rounded-lg border bg-gray-50 border-gray-200" style="min-width: 72px;">' +
            '<div class="text-xs font-medium text-gray-500">참조</div>' +
            (position ? '<div class="text-xs text-gray-400 mt-0.5">' + escapeHtml(position) + '</div>' : '') +
            '<div class="text-sm font-semibold text-gray-800 mt-0.5">' + escapeHtml(r.user_name) + '</div>' +
            '</div>'
        );
    });

    // 가로 2분할 레이아웃
    var html = '<div class="grid gap-3" style="grid-template-columns: ' + (refCards.length > 0 ? '1fr 1fr' : '1fr') + ';">';

    // 좌측: 결재선
    html += '<div>';
    html += '<div class="flex items-center gap-1.5 mb-2"><svg class="w-3.5 h-3.5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg><span class="text-xs font-semibold text-gray-600">결재선</span><span class="text-xs text-gray-400">(' + steps.length + '명)</span></div>';
    if (approvalCards.length > 0) {
        html += '<div id="summary-sortable" class="flex flex-wrap gap-2">' + approvalCards.join('') + '</div>';
        if (steps.length > 1) html += '<div class="text-xs text-gray-400 mt-1.5">드래그하여 순서 변경</div>';
    } else {
        html += '<div class="text-xs text-gray-400 py-2">결재자가 없습니다</div>';
    }
    html += '</div>';

    // 우측: 참조선
    if (refCards.length > 0) {
        html += '<div class="border-l border-gray-200 pl-3">';
        html += '<div class="flex items-center gap-1.5 mb-2"><svg class="w-3.5 h-3.5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg><span class="text-xs font-semibold text-gray-600">참조</span><span class="text-xs text-gray-400">(' + references.length + '명)</span></div>';
        html += '<div class="flex flex-wrap gap-2">' + refCards.join('') + '</div>';
        html += '</div>';
    }

    html += '</div>';

    summaryEl.className = 'p-3 bg-gray-50 rounded-lg border border-gray-200';
    summaryEl.innerHTML = html;

    initSummarySortable();
}

function initSummarySortable() {
    if (summarySortableInstance) { summarySortableInstance.destroy(); summarySortableInstance = null; }
    var el = document.getElementById('summary-sortable');
    if (!el || typeof Sortable === 'undefined') return;

    summarySortableInstance = Sortable.create(el, {
        animation: 150,
        ghostClass: 'sortable-ghost',
        chosenClass: 'sortable-chosen',
        onEnd: function(evt) {
            if (evt.oldIndex === evt.newIndex) return;
            var editorEl = document.getElementById('approval-line-editor');
            if (!editorEl || !editorEl._x_dataStack) return;
            var steps = editorEl._x_dataStack[0].steps;
            var item = steps.splice(evt.oldIndex, 1)[0];
            steps.splice(evt.newIndex, 0, item);
            updateApprovalLineSummary();
        }
    });
}

function applyQuickLine(lineId) {
    const editorEl = document.getElementById('approval-line-editor');
    if (!editorEl || !editorEl._x_dataStack) return;
    const alpineData = editorEl._x_dataStack[0];

    if (!lineId) {
        alpineData.selectedLineId = '';
        alpineData.steps = [];
    } else {
        alpineData.selectedLineId = lineId;
        alpineData.loadLine();
    }

    setTimeout(updateApprovalLineSummary, 100);
}

function switchFormMode(formId) {
    const code = formCodes[formId];
    const expenseContainer = document.getElementById('expense-form-container');
    const purchaseRequestContainer = document.getElementById('purchase-request-form-container');
    const leaveContainer = document.getElementById('leave-form-container');
    const certContainer = document.getElementById('cert-form-container');
    const careerCertContainer = document.getElementById('career-cert-form-container');
    const appointmentCertContainer = document.getElementById('appointment-cert-form-container');
    const resignationContainer = document.getElementById('resignation-form-container');
    const sealUsageContainer = document.getElementById('seal-usage-form-container');
    const delegationContainer = document.getElementById('delegation-form-container');
    const boardMinutesContainer = document.getElementById('board-minutes-form-container');
    const quotationContainer = document.getElementById('quotation-form-container');
    const officialLetterContainer = document.getElementById('official-letter-form-container');
    const lp1Container = document.getElementById('leave-promotion-1st-form-container');
    const lp2Container = document.getElementById('leave-promotion-2nd-form-container');
    const bodyArea = document.getElementById('body-area');
    const expenseLoadBtn = document.getElementById('expense-load-btn');

    const leaveFormCodes = ['leave', 'attendance_request', 'reason_report'];

    // 모두 숨기기
    expenseContainer.style.display = 'none';
    purchaseRequestContainer.style.display = 'none';
    leaveContainer.style.display = 'none';
    certContainer.style.display = 'none';
    careerCertContainer.style.display = 'none';
    appointmentCertContainer.style.display = 'none';
    resignationContainer.style.display = 'none';
    sealUsageContainer.style.display = 'none';
    delegationContainer.style.display = 'none';
    boardMinutesContainer.style.display = 'none';
    quotationContainer.style.display = 'none';
    officialLetterContainer.style.display = 'none';
    lp1Container.style.display = 'none';
    lp2Container.style.display = 'none';
    expenseLoadBtn.style.display = 'none';
    bodyArea.style.display = 'none';
    isExpenseForm = false;
    isPurchaseRequestForm = false;
    isLeaveForm = false;
    isCertForm = false;
    isCareerCertForm = false;
    isAppointmentCertForm = false;
    isResignationForm = false;
    isSealUsageForm = false;
    isDelegationForm = false;
    isBoardMinutesForm = false;
    isQuotationForm = false;
    isOfficialLetterForm = false;
    isLeavePromotion1stForm = false;
    isLeavePromotion2ndForm = false;

    if (code === 'expense') {
        isExpenseForm = true;
        expenseContainer.style.display = '';
        expenseLoadBtn.style.display = '';
    } else if (code && code.startsWith('pr_')) {
        isPurchaseRequestForm = true;
        purchaseRequestContainer.style.display = '';
        setTimeout(() => {
            const prData = purchaseRequestContainer._x_dataStack?.[0];
            if (prData) prData.setPrType(code);
        }, 50);
    } else if (leaveFormCodes.includes(code)) {
        isLeaveForm = true;
        leaveContainer.style.display = '';
        populateLeaveTypes(code);

        const startEl = document.getElementById('leave-start-date');
        const endEl = document.getElementById('leave-end-date');
        const startLabel = document.getElementById('leave-start-label');
        const endLabel = document.getElementById('leave-end-label');

        // 근태신청은 시작일/종료일에 시간 선택 가능
        if (code === 'attendance_request') {
            startEl.type = 'datetime-local';
            endEl.type = 'datetime-local';
            if (startLabel) startLabel.textContent = '시작일시';
            if (endLabel) endLabel.textContent = '종료일시';
            if (!startEl.value) startEl.value = new Date().toISOString().slice(0, 16);
            if (!endEl.value) endEl.value = new Date().toISOString().slice(0, 16);
        } else {
            startEl.type = 'date';
            endEl.type = 'date';
            if (startLabel) startLabel.textContent = '시작일';
            if (endLabel) endLabel.textContent = '종료일';
            const today = new Date().toISOString().slice(0, 10);
            if (!startEl.value) startEl.value = today;
            if (!endEl.value) endEl.value = today;
        }
    } else if (code === 'employment_cert') {
        isCertForm = true;
        certContainer.style.display = '';
        const certUserId = document.getElementById('cert-user-id').value;
        if (certUserId) loadCertInfo(certUserId);
    } else if (code === 'career_cert') {
        isCareerCertForm = true;
        careerCertContainer.style.display = '';
        const ccUserId = document.getElementById('cc-user-id').value;
        if (ccUserId) loadCareerCertInfo(ccUserId);
    } else if (code === 'appointment_cert') {
        isAppointmentCertForm = true;
        appointmentCertContainer.style.display = '';
        const acUserId = document.getElementById('ac-user-id').value;
        if (acUserId) loadAppointmentCertInfo(acUserId);
    } else if (code === 'resignation') {
        isResignationForm = true;
        resignationContainer.style.display = '';
        const rgUserId = document.getElementById('rg-user-id').value;
        if (rgUserId) loadResignationInfo(rgUserId);
    } else if (code === 'seal_usage') {
        isSealUsageForm = true;
        sealUsageContainer.style.display = '';
    } else if (code === 'delegation') {
        isDelegationForm = true;
        delegationContainer.style.display = '';
    } else if (code === 'board_minutes') {
        isBoardMinutesForm = true;
        boardMinutesContainer.style.display = '';
    } else if (code === 'quotation') {
        isQuotationForm = true;
        quotationContainer.style.display = '';
    } else if (code === 'official_letter') {
        isOfficialLetterForm = true;
        officialLetterContainer.style.display = '';
    } else if (code === 'leave_promotion_1st') {
        isLeavePromotion1stForm = true;
        lp1Container.style.display = '';
    } else if (code === 'leave_promotion_2nd') {
        isLeavePromotion2ndForm = true;
        lp2Container.style.display = '';
    } else {
        bodyArea.style.display = '';
    }
}

function applyBodyTemplate(formId) {
    // 먼저 폼 모드 전환
    switchFormMode(formId);

    // 전용 폼이면 제목을 양식명으로 설정하고 body template 적용 건너뜀
    if (isExpenseForm || isPurchaseRequestForm || isLeaveForm || isCertForm || isCareerCertForm || isAppointmentCertForm || isResignationForm || isSealUsageForm || isDelegationForm || isBoardMinutesForm || isQuotationForm || isOfficialLetterForm || isLeavePromotion1stForm || isLeavePromotion2ndForm) {
        const titleEl = document.getElementById('title');
        const formSelect = document.getElementById('form_id');
        titleEl.value = formSelect.options[formSelect.selectedIndex].text;
        return;
    }

    const template = formBodyTemplates[formId];
    if (!template) return;

    const bodyContent = getBodyContent();
    if (bodyContent.trim()) {
        if (!confirm('현재 본문 내용을 양식 템플릿으로 교체하시겠습니까?')) return;
    }

    // 제목 자동 설정 (비어있을 때만)
    const titleEl = document.getElementById('title');
    if (!titleEl.value.trim()) {
        const formSelect = document.getElementById('form_id');
        titleEl.value = formSelect.options[formSelect.selectedIndex].text;
    }

    // 편집기 활성화 후 HTML 삽입
    const useEditorEl = document.getElementById('useEditor');
    if (!useEditorEl.checked) {
        useEditorEl.checked = true;
        toggleEditor();
    }

    if (quillInstance) {
        quillInstance.root.innerHTML = template;
    }
    document.getElementById('body').value = template;
}

document.addEventListener('keydown', function(e) {
    if (e.key === 'Escape') {
        const expModal = document.getElementById('expense-load-modal');
        if (expModal && expModal.style.display !== 'none') {
            closeExpenseLoadModal();
            return;
        }
        const modal = document.getElementById('approval-line-modal');
        if (modal && modal.style.display !== 'none') {
            closeApprovalLineModal();
        }
    }
});

document.addEventListener('DOMContentLoaded', function() {
    setTimeout(updateApprovalLineSummary, 200);

    // 2단계 분류 초기화
    buildCategoryOptions();
    const initialFormId = document.getElementById('form_id').value;
    selectCategoryByFormId(initialFormId);
    switchFormMode(initialFormId);
    updateFormDescription(initialFormId);

    // 분류 변경 → 양식 필터링
    document.getElementById('form_category').addEventListener('change', function() {
        filterFormsByCategory(this.value);
    });

    // 양식 변경 시 본문 템플릿 자동 채움 + 설명 카드 업데이트
    document.getElementById('form_id').addEventListener('change', function() {
        applyBodyTemplate(this.value);
        updateFormDescription(this.value);
    });
});

async function saveApproval(action) {
    const title = document.getElementById('title').value.trim();
    if (!title) {
        showToast('제목을 입력해주세요.', 'warning');
        return;
    }

    const editorEl = document.getElementById('approval-line-editor');
    const steps = editorEl._x_dataStack[0].getStepsData();

    if (action === 'submit' && steps.filter(s => s.step_type !== 'reference').length === 0) {
        showToast('결재자를 1명 이상 추가해주세요.', 'warning');
        return;
    }

    let formContent = {};
    let formBody = getBodyContent();
    let attachmentFileIds = [];

    if (isExpenseForm) {
        const expenseEl = document.getElementById('expense-form-container');
        if (expenseEl && expenseEl._x_dataStack) {
            formContent = expenseEl._x_dataStack[0].getFormData();
            attachmentFileIds = expenseEl._x_dataStack[0].getFileIds();
        }
        formBody = null;
    } else if (isPurchaseRequestForm) {
        const prEl = document.getElementById('purchase-request-form-container');
        if (prEl && prEl._x_dataStack) {
            formContent = prEl._x_dataStack[0].getFormData();
            attachmentFileIds = prEl._x_dataStack[0].getFileIds();
        }
        formBody = null;
    } else if (isLeaveForm) {
        const leaveData = getLeaveFormData();

        if (!leaveData.leave_type) {
            showToast('유형을 선택해주세요.', 'warning');
            return;
        }
        if (!leaveData.start_date || !leaveData.end_date) {
            showToast('시작일과 종료일을 입력해주세요.', 'warning');
            return;
        }
        if (leaveData.start_date > leaveData.end_date) {
            showToast('종료일이 시작일보다 이전입니다.', 'warning');
            return;
        }

        formContent = leaveData;
        formBody = buildLeaveBody(leaveData);
    } else if (isCertForm) {
        const purpose = getCertPurpose();
        if (!purpose) {
            showToast('사용용도를 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            cert_user_id: document.getElementById('cert-user-id').value,
            name: document.getElementById('cert-name').value,
            resident_number: document.getElementById('cert-resident').value,
            address: document.getElementById('cert-address').value,
            department: document.getElementById('cert-department').value,
            position: document.getElementById('cert-position').value,
            hire_date: document.getElementById('cert-hire-date').value,
            company_name: document.getElementById('cert-company').value,
            business_num: document.getElementById('cert-business-num').value,
            ceo_name: document.getElementById('cert-ceo-name').value,
            company_address: document.getElementById('cert-company-address').value,
            purpose: purpose,
            issue_date: document.getElementById('cert-issue-date').value,
        };
        formBody = null;
    } else if (isCareerCertForm) {
        const purpose = getCareerCertPurpose();
        if (!purpose) {
            showToast('사용용도를 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            cert_user_id: document.getElementById('cc-user-id').value,
            name: document.getElementById('cc-name').value,
            resident_number: document.getElementById('cc-resident').value,
            birth_date: document.getElementById('cc-birth-date').value,
            address: document.getElementById('cc-address').value,
            department: document.getElementById('cc-department').value,
            position: document.getElementById('cc-position').value,
            hire_date: document.getElementById('cc-hire-date').value,
            resign_date: document.getElementById('cc-resign-date').value,
            job_description: document.getElementById('cc-job-description').value,
            company_name: document.getElementById('cc-company').value,
            business_num: document.getElementById('cc-business-num').value,
            ceo_name: document.getElementById('cc-ceo-name').value,
            phone: document.getElementById('cc-phone').value,
            company_address: document.getElementById('cc-company-address').value,
            purpose: purpose,
            issue_date: document.getElementById('cc-issue-date').value,
        };
        formBody = null;
    } else if (isAppointmentCertForm) {
        const purpose = getAppointmentCertPurpose();
        if (!purpose) {
            showToast('용도를 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            cert_user_id: document.getElementById('ac-user-id').value,
            name: document.getElementById('ac-name').value,
            resident_number: document.getElementById('ac-resident').value,
            department: document.getElementById('ac-department').value,
            phone: document.getElementById('ac-phone').value,
            hire_date: document.getElementById('ac-hire-date').value,
            resign_date: document.getElementById('ac-resign-date').value,
            contract_type: document.getElementById('ac-contract-type').value,
            company_name: document.getElementById('ac-company-name').value,
            ceo_name: document.getElementById('ac-ceo-name').value,
            purpose: purpose,
            issue_date: document.getElementById('ac-issue-date').value,
        };
        formBody = null;
    } else if (isSealUsageForm) {
        const suPurpose = document.getElementById('su-purpose').value.trim();
        if (!suPurpose) {
            showToast('용도를 입력해주세요.', 'warning');
            return;
        }
        const suSubmitTo = document.getElementById('su-submit-to').value.trim();
        if (!suSubmitTo) {
            showToast('제출처를 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            usage_date: document.getElementById('su-usage-date').value,
            purpose: suPurpose,
            submit_to: suSubmitTo,
            attachment_desc: document.getElementById('su-attachment-desc').value.trim(),
            company_name: document.getElementById('su-company-name').value,
            business_num: document.getElementById('su-business-num').value,
            ceo_name: document.getElementById('su-ceo-name').value,
            company_address: document.getElementById('su-company-address').value,
        };
        formBody = null;
    } else if (isBoardMinutesForm) {
        const bmDatetime = document.getElementById('bm-meeting-datetime').value;
        if (!bmDatetime) {
            showToast('일시를 입력해주세요.', 'warning');
            return;
        }
        const bmPlace = document.getElementById('bm-meeting-place').value.trim();
        if (!bmPlace) {
            showToast('장소를 입력해주세요.', 'warning');
            return;
        }
        const bmChairman = document.getElementById('bm-chairman-name').value.trim();
        if (!bmChairman) {
            showToast('의장(대표이사) 성명을 입력해주세요.', 'warning');
            return;
        }

        const bmContainer = document.getElementById('board-minutes-form-container');
        const bmAlpine = bmContainer._x_dataStack?.[0];
        const bmAgendas = bmAlpine ? bmAlpine.agendas : [];
        const bmSigners = bmAlpine ? bmAlpine.signers : [];

        if (bmAgendas.length === 0 || !bmAgendas[0].title.trim()) {
            showToast('의안을 1건 이상 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            meeting_datetime: bmDatetime,
            meeting_place: bmPlace,
            total_directors: parseInt(document.getElementById('bm-total-directors').value) || 0,
            present_directors: parseInt(document.getElementById('bm-present-directors').value) || 0,
            total_auditors: parseInt(document.getElementById('bm-total-auditors').value) || 0,
            present_auditors: parseInt(document.getElementById('bm-present-auditors').value) || 0,
            chairman_name: bmChairman,
            agendas: bmAgendas.filter(a => a.title.trim()).map(a => ({ no: a.no, title: a.title.trim(), result: a.result.trim() })),
            proceedings: document.getElementById('bm-proceedings').value.trim(),
            closing_time: document.getElementById('bm-closing-time').value,
            signers: bmSigners.filter(s => s.name.trim()).map(s => ({ role: s.role.trim(), name: s.name.trim() })),
            company_name: document.getElementById('bm-company-name').value,
            business_num: document.getElementById('bm-business-num').value,
            ceo_name: document.getElementById('bm-ceo-name').value,
            company_address: document.getElementById('bm-company-address').value,
            meeting_date: bmDatetime.split('T')[0],
        };
        formBody = null;
    } else if (isQuotationForm) {
        const qtClientName = document.getElementById('qt-client-name').value.trim();
        if (!qtClientName) {
            showToast('수신(고객명)을 입력해주세요.', 'warning');
            return;
        }
        const qtQuoteDate = document.getElementById('qt-quote-date').value;
        if (!qtQuoteDate) {
            showToast('견적일자를 입력해주세요.', 'warning');
            return;
        }

        const qtContainer = document.getElementById('quotation-form-container');
        const qtAlpine = qtContainer._x_dataStack?.[0];
        const qtItems = qtAlpine ? qtAlpine.items : [];

        if (qtItems.length === 0 || !qtItems[0].name.trim()) {
            showToast('품목을 1건 이상 입력해주세요.', 'warning');
            return;
        }

        const mappedItems = qtItems.filter(i => i.name.trim()).map(i => ({
            name: i.name.trim(),
            spec: (i.spec || '').trim(),
            qty: parseInt(i.qty) || 0,
            unit_price: parseInt(i.unit_price) || 0,
            supply_amount: (parseInt(i.qty) || 0) * (parseInt(i.unit_price) || 0),
            tax: qtAlpine.itemTax(i),
            note: (i.note || '').trim(),
        }));

        formContent = {
            client_name: qtClientName,
            quote_date: qtQuoteDate,
            company_name: document.getElementById('qt-company-name').value,
            business_num: document.getElementById('qt-business-num').value,
            ceo_name: document.getElementById('qt-ceo-name').value,
            company_address: document.getElementById('qt-company-address').value,
            business_type: document.getElementById('qt-business-type-input')?.value || document.getElementById('qt-business-type').value,
            business_item: document.getElementById('qt-business-item-input')?.value || document.getElementById('qt-business-item').value,
            phone: document.getElementById('qt-phone-input')?.value || document.getElementById('qt-phone').value,
            bank_account: document.getElementById('qt-bank-input')?.value || document.getElementById('qt-bank-account').value,
            items: mappedItems,
            total_supply: qtAlpine ? qtAlpine.totalSupply() : 0,
            total_tax: qtAlpine ? qtAlpine.totalTax() : 0,
            total_amount: qtAlpine ? qtAlpine.totalAmount() : 0,
            remarks: document.getElementById('qt-remarks').value.trim(),
        };
        formBody = null;
    } else if (isOfficialLetterForm) {
        const olRecipient = document.getElementById('ol-recipient').value.trim();
        if (!olRecipient) { showToast('수신처를 입력해주세요.', 'warning'); return; }
        const olSubject = document.getElementById('ol-subject').value.trim();
        if (!olSubject) { showToast('제목을 입력해주세요.', 'warning'); return; }
        const olBody = document.getElementById('ol-body').value.trim();
        if (!olBody) { showToast('본문을 입력해주세요.', 'warning'); return; }

        formContent = {
            doc_number: document.getElementById('ol-doc-number').value.trim(),
            doc_date: document.getElementById('ol-doc-date').value,
            recipient: olRecipient,
            reference: document.getElementById('ol-reference').value.trim(),
            subject: olSubject,
            body: olBody,
            attachments_desc: document.getElementById('ol-attachments-desc').value.trim(),
            company_name: document.getElementById('ol-company-name').value,
            ceo_name: document.getElementById('ol-ceo-name').value,
            company_address: document.getElementById('ol-company-address').value,
            phone: document.getElementById('ol-phone-input')?.value || document.getElementById('ol-phone').value,
            fax: document.getElementById('ol-fax-input')?.value || document.getElementById('ol-fax').value,
            email: document.getElementById('ol-email-input')?.value || document.getElementById('ol-email').value,
        };
        formBody = null;
    } else if (isLeavePromotion1stForm) {
        const lp1UserId = document.getElementById('lp1-user-id').value;
        if (!lp1UserId) { showToast('대상 직원을 선택해주세요.', 'warning'); return; }
        const lp1Deadline = document.getElementById('lp1-deadline').value;
        if (!lp1Deadline) { showToast('사용계획 제출기한을 입력해주세요.', 'warning'); return; }

        formContent = getLp1Data();
        formBody = null;
    } else if (isLeavePromotion2ndForm) {
        const lp2UserId = document.getElementById('lp2-user-id').value;
        if (!lp2UserId) { showToast('대상 직원을 선택해주세요.', 'warning'); return; }
        const lp2Dates = getLp2Dates();
        if (lp2Dates.length === 0) { showToast('지정 휴가일을 1건 이상 입력해주세요.', 'warning'); return; }

        formContent = getLp2Data();
        formBody = null;
    } else if (isDelegationForm) {
        const dlAgentName = document.getElementById('dl-agent-name').value.trim();
        if (!dlAgentName) {
            showToast('수임인(대리인) 성명을 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            company_name: document.getElementById('dl-company-name').value,
            business_num: document.getElementById('dl-business-num').value,
            ceo_name: document.getElementById('dl-ceo-name').value,
            company_address: document.getElementById('dl-company-address').value,
            agent_name: dlAgentName,
            agent_birth: document.getElementById('dl-agent-birth').value,
            agent_address: document.getElementById('dl-agent-address').value.trim(),
            agent_phone: document.getElementById('dl-agent-phone').value.trim(),
            agent_department: document.getElementById('dl-agent-department').value.trim(),
            delegation_detail: document.getElementById('dl-delegation-detail').value.trim(),
            period_start: document.getElementById('dl-period-start').value,
            period_end: document.getElementById('dl-period-end').value,
            attachments_desc: document.getElementById('dl-attachments-desc').value.trim(),
        };
        formBody = null;
    } else if (isResignationForm) {
        const reason = getResignationReason();
        if (!reason) {
            showToast('사직사유를 입력해주세요.', 'warning');
            return;
        }
        const resignDate = document.getElementById('rg-resign-date').value;
        if (!resignDate) {
            showToast('퇴사(예정)일을 입력해주세요.', 'warning');
            return;
        }

        formContent = {
            cert_user_id: document.getElementById('rg-user-id').value,
            name: document.getElementById('rg-name').value,
            resident_number: document.getElementById('rg-resident').value,
            department: document.getElementById('rg-department').value,
            position: document.getElementById('rg-position').value,
            hire_date: document.getElementById('rg-hire-date').value,
            resign_date: resignDate,
            address: document.getElementById('rg-address').value,
            reason: reason,
            company_name: document.getElementById('rg-company-name').value,
            ceo_name: document.getElementById('rg-ceo-name').value,
            issue_date: document.getElementById('rg-issue-date').value,
        };
        formBody = null;
    }

    const payload = {
        form_id: document.getElementById('form_id').value,
        title: title,
        body: formBody,
        content: formContent,
        attachment_file_ids: attachmentFileIds,
        is_urgent: document.getElementById('is_urgent').checked,
        steps: steps,
    };

    try {
        const response = await fetch('/api/admin/approvals', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-TOKEN': '{{ csrf_token() }}',
                'Accept': 'application/json',
            },
            body: JSON.stringify(payload),
        });

        const data = await response.json();

        if (!data.success && !data.data) {
            showToast(data.message || '저장에 실패했습니다.', 'error');
            return;
        }

        if (action === 'submit') {
            const submitResponse = await fetch(`/api/admin/approvals/${data.data.id}/submit`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': '{{ csrf_token() }}',
                    'Accept': 'application/json',
                },
            });

            const submitData = await submitResponse.json();

            if (submitData.success) {
                showToast('결재가 상신되었습니다.', 'success');
                setTimeout(() => location.href = '/approval-mgmt/drafts', 500);
            } else {
                showToast(submitData.message || '상신에 실패했습니다.', 'error');
            }
        } else {
            showToast('임시저장되었습니다.', 'success');
            setTimeout(() => location.href = `/approval-mgmt/${data.data.id}/edit`, 500);
        }
    } catch (e) {
        showToast('서버 오류가 발생했습니다.', 'error');
    }
}

// =========================================================================
// 지출결의서 불러오기
// =========================================================================

const expenseTypeLabels = {
    corporate_card: '법인카드', transfer: '송금', auto_transfer: '자동이체 출금',
    cash_advance: '현금/가지급정산',
};
const statusColors = {
    draft: 'bg-gray-100 text-gray-600', pending: 'bg-blue-100 text-blue-600',
    approved: 'bg-green-100 text-green-600', rejected: 'bg-red-100 text-red-600',
    cancelled: 'bg-yellow-100 text-yellow-600',
};

async function openExpenseLoadModal() {
    const modal = document.getElementById('expense-load-modal');
    const list = document.getElementById('expense-load-list');
    modal.style.display = '';
    document.body.style.overflow = 'hidden';
    list.innerHTML = '<div class="text-center text-sm text-gray-400 py-8">불러오는 중...</div>';

    try {
        const res = await fetch('/api/admin/approvals/expense-history', {
            headers: { 'Accept': 'application/json' },
        });
        const json = await res.json();

        if (!json.success || !json.data.length) {
            list.innerHTML = '<div class="text-center text-sm text-gray-400 py-8">이전 지출결의서가 없습니다.</div>';
            return;
        }

        list.innerHTML = json.data.map(item => {
            const amount = parseInt(item.total_amount || 0).toLocaleString('ko-KR');
            const typeLabel = expenseTypeLabels[item.expense_type] || item.expense_type;
            const color = statusColors[item.status] || statusColors.draft;
            return `<div class="flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:bg-blue-50 cursor-pointer transition mb-2" onclick="loadExpenseData(${item.id})">
                <div class="flex-1 min-w-0">
                    <div class="flex items-center gap-2">
                        <span class="text-sm font-medium text-gray-800 truncate">${escapeHtml(item.title)}</span>
                        <span class="shrink-0 px-1.5 py-0.5 rounded text-xs font-medium ${color}">${escapeHtml(item.status_label)}</span>
                    </div>
                    <div class="flex items-center gap-3 mt-1 text-xs text-gray-500">
                        <span>${escapeHtml(item.created_at)}</span>
                        <span>${escapeHtml(typeLabel)}</span>
                        <span class="font-medium text-gray-700">${amount}원</span>
                    </div>
                </div>
                <svg class="w-4 h-4 text-gray-400 shrink-0 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
                </svg>
            </div>`;
        }).join('');
    } catch (e) {
        list.innerHTML = '<div class="text-center text-sm text-red-400 py-8">불러오기 실패</div>';
    }
}

function closeExpenseLoadModal() {
    document.getElementById('expense-load-modal').style.display = 'none';
    document.body.style.overflow = '';
}

async function loadExpenseData(approvalId) {
    try {
        const res = await fetch(`/api/admin/approvals/${approvalId}`, {
            headers: { 'Accept': 'application/json' },
        });
        const json = await res.json();

        if (!json.success || !json.data?.content) {
            showToast('데이터를 불러올 수 없습니다.', 'error');
            return;
        }

        const content = json.data.content;
        const expenseEl = document.getElementById('expense-form-container');
        if (!expenseEl || !expenseEl._x_dataStack) return;

        const alpine = expenseEl._x_dataStack[0];
        const today = new Date().toISOString().slice(0, 10);

        // 폼 데이터 복사 (날짜는 오늘로 초기화)
        alpine.formData.expense_type = content.expense_type || 'corporate_card';
        alpine.formData.tax_invoice = content.tax_invoice || 'normal';
        alpine.formData.write_date = today;
        alpine.formData.approval_date = today;
        alpine.formData.department = content.department || '경리부';
        alpine.formData.writer_name = content.writer_name || '';
        alpine.formData.attachment_memo = content.attachment_memo || '';
        alpine.formData.selected_card = content.selected_card || null;
        alpine.formData.selected_account = content.selected_account || null;

        // 내역 항목 복사 (날짜는 오늘로)
        if (content.items && content.items.length > 0) {
            let keyCounter = alpine.formData.items.length + 100;
            alpine.formData.items = content.items.map(item => ({
                _key: ++keyCounter,
                date: today,
                description: item.description || '',
                amount: parseInt(item.amount) || 0,
                vendor: item.vendor || '',
                bank: item.bank || '',
                account_no: item.account_no || '',
                depositor: item.depositor || '',
                remark: item.remark || '',
            }));
        }

        // 제목 설정
        const titleEl = document.getElementById('title');
        if (!titleEl.value.trim()) {
            titleEl.value = json.data.title || '지출결의서';
        }

        closeExpenseLoadModal();
        showToast('지출결의서를 불러왔습니다. 내용을 확인 후 수정해주세요.', 'success');
    } catch (e) {
        showToast('불러오기 실패', 'error');
    }
}

// =========================================================================
// 재직증명서 관련 함수
// =========================================================================

async function loadCertInfo(userId) {
    if (!userId) return;

    try {
        const resp = await fetch(`/api/admin/approvals/cert-info/${userId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
        });
        const data = await resp.json();

        if (data.success) {
            const d = data.data;
            document.getElementById('cert-name').value = d.name || '';
            document.getElementById('cert-resident').value = d.resident_number || '';
            document.getElementById('cert-address').value = d.address || '';
            document.getElementById('cert-company').value = d.company_name || '';
            document.getElementById('cert-business-num').value = d.business_num || '';
            document.getElementById('cert-department').value = d.department || '';
            document.getElementById('cert-position').value = d.position || '';
            document.getElementById('cert-hire-date').value = d.hire_date ? d.hire_date + ' ~' : '';
            document.getElementById('cert-ceo-name').value = d.ceo_name || '';
            document.getElementById('cert-company-address').value = d.company_address || '';
        } else {
            showToast(data.message || '사원 정보를 불러올 수 없습니다.', 'error');
        }
    } catch (e) {
        showToast('사원 정보 조회 중 오류가 발생했습니다.', 'error');
    }
}

function onCertPurposeChange() {
    const sel = document.getElementById('cert-purpose-select');
    const customWrap = document.getElementById('cert-purpose-custom-wrap');
    if (sel.value === '__custom__') {
        customWrap.style.display = '';
        document.getElementById('cert-purpose-custom').focus();
    } else {
        customWrap.style.display = 'none';
    }
}

function getCertPurpose() {
    const sel = document.getElementById('cert-purpose-select');
    if (sel.value === '__custom__') {
        return document.getElementById('cert-purpose-custom').value.trim();
    }
    return sel.value;
}

function openCertPreview() {
    const name = document.getElementById('cert-name').value || '-';
    const resident = document.getElementById('cert-resident').value || '-';
    const address = document.getElementById('cert-address').value || '-';
    const company = document.getElementById('cert-company').value || '-';
    const businessNum = document.getElementById('cert-business-num').value || '-';
    const department = document.getElementById('cert-department').value || '-';
    const position = document.getElementById('cert-position').value || '-';
    const hireDate = document.getElementById('cert-hire-date').value || '-';
    const purpose = getCertPurpose() || '-';
    const issueDate = document.getElementById('cert-issue-date').value || '-';
    const ceoName = document.getElementById('cert-ceo-name').value || '-';

    const issueDateFormatted = issueDate !== '-' ? issueDate.replace(/-/g, function(m, i) { return i === 4 ? '년 ' : '월 '; }) + '일' : '-';

    const el = document.getElementById('cert-preview-content');
    el.innerHTML = buildCertPreviewHtml({ name, resident, address, company, businessNum, department, position, hireDate, purpose, issueDateFormatted, ceoName });

    document.getElementById('cert-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeCertPreview() {
    document.getElementById('cert-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printCertPreview() {
    const content = document.getElementById('cert-preview-content').innerHTML;
    const win = window.open('', '_blank', 'width=800,height=1000');
    win.document.write('<html><head><title>재직증명서</title>');
    win.document.write('<style>@page{size:A4;margin:0;} body{font-family:"Pretendard","Malgun Gothic",sans-serif;margin:0;padding:0;} .cert-page{padding:80px 56px 60px;box-sizing:border-box;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:14px 16px;font-size:15px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:130px;}</style>');
    win.document.write('</head><body><div class="cert-page">');
    win.document.write(content);
    win.document.write('</div></body></html>');
    win.document.close();
    win.onload = function() { win.print(); };
}

// =========================================================================
// 경력증명서 관련 함수
// =========================================================================

async function loadCareerCertInfo(userId) {
    if (!userId) return;

    try {
        const resp = await fetch(`/api/admin/approvals/career-cert-info/${userId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
        });
        const data = await resp.json();

        if (data.success) {
            const d = data.data;
            document.getElementById('cc-name').value = d.name || '';
            document.getElementById('cc-resident').value = d.resident_number || '';
            document.getElementById('cc-birth-date').value = d.birth_date || '';
            document.getElementById('cc-address').value = d.address || '';
            document.getElementById('cc-company').value = d.company_name || '';
            document.getElementById('cc-business-num').value = d.business_num || '';
            document.getElementById('cc-ceo-name').value = d.ceo_name || '';
            document.getElementById('cc-phone').value = d.phone || '';
            document.getElementById('cc-company-address').value = d.company_address || '';
            document.getElementById('cc-department').value = d.department || '';
            document.getElementById('cc-position').value = d.position || '';
            document.getElementById('cc-hire-date').value = d.hire_date || '';
            document.getElementById('cc-resign-date').value = d.resign_date || '';
            document.getElementById('cc-job-description').value = d.job_description || '';
        } else {
            showToast(data.message || '사원 정보를 불러올 수 없습니다.', 'error');
        }
    } catch (e) {
        showToast('사원 정보 조회 중 오류가 발생했습니다.', 'error');
    }
}

function onCareerCertPurposeChange() {
    const sel = document.getElementById('cc-purpose-select');
    const customWrap = document.getElementById('cc-purpose-custom-wrap');
    if (sel.value === '__custom__') {
        customWrap.style.display = '';
        document.getElementById('cc-purpose-custom').focus();
    } else {
        customWrap.style.display = 'none';
    }
}

function getCareerCertPurpose() {
    const sel = document.getElementById('cc-purpose-select');
    if (sel.value === '__custom__') {
        return document.getElementById('cc-purpose-custom').value.trim();
    }
    return sel.value;
}

function openCareerCertPreview() {
    const name = document.getElementById('cc-name').value || '-';
    const residentNumber = document.getElementById('cc-resident').value || '-';
    const birthDate = document.getElementById('cc-birth-date').value || '-';
    const address = document.getElementById('cc-address').value || '-';
    const company = document.getElementById('cc-company').value || '-';
    const businessNum = document.getElementById('cc-business-num').value || '-';
    const ceoName = document.getElementById('cc-ceo-name').value || '-';
    const phone = document.getElementById('cc-phone').value || '-';
    const companyAddress = document.getElementById('cc-company-address').value || '-';
    const department = document.getElementById('cc-department').value || '-';
    const position = document.getElementById('cc-position').value || '-';
    const hireDate = document.getElementById('cc-hire-date').value || '-';
    const resignDate = document.getElementById('cc-resign-date').value || '현재';
    const jobDescription = document.getElementById('cc-job-description').value || '-';
    const purpose = getCareerCertPurpose() || '-';
    const issueDate = document.getElementById('cc-issue-date').value || '-';
    const issueDateFormatted = issueDate !== '-' ? issueDate.replace(/-/g, function(m, i) { return i === 4 ? '년 ' : '월 '; }) + '일' : '-';

    const el = document.getElementById('career-cert-preview-content');
    el.innerHTML = buildCareerCertPreviewHtml({ name, residentNumber, birthDate, address, company, businessNum, ceoName, phone, companyAddress, department, position, hireDate, resignDate, jobDescription, purpose, issueDateFormatted });

    document.getElementById('career-cert-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeCareerCertPreview() {
    document.getElementById('career-cert-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printCareerCertPreview() {
    const content = document.getElementById('career-cert-preview-content').innerHTML;
    const win = window.open('', '_blank', 'width=800,height=1000');
    win.document.write('<html><head><title>경력증명서</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:10px 14px;font-size:14px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:120px;} @media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.onload = function() { win.print(); };
}

function buildCareerCertPreviewHtml(d) {
    const e = (s) => { const div = document.createElement('div'); div.textContent = s; return div.innerHTML; };
    const thStyle = 'border:1px solid #333; padding:10px 14px; background:#f8f9fa; font-weight:600; text-align:left; white-space:nowrap; width:120px; font-size:14px;';
    const tdStyle = 'border:1px solid #333; padding:10px 14px; font-size:14px;';

    return `
        <h1 style="text-align:center; font-size:28px; font-weight:700; letter-spacing:12px; margin-bottom:40px;">경 력 증 명 서</h1>

        <h3 style="font-size:15px; font-weight:600; margin:24px 0 10px; color:#333;">1. 인적사항</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:20px;">
            <tr>
                <th style="${thStyle}">성 명</th>
                <td style="${tdStyle}">${e(d.name)}</td>
                <th style="${thStyle}">주민등록번호</th>
                <td style="${tdStyle}">${e(d.residentNumber)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">생년월일</th>
                <td style="${tdStyle}">${e(d.birthDate)}</td>
                <th style="${thStyle}"></th>
                <td style="${tdStyle}"></td>
            </tr>
            <tr>
                <th style="${thStyle}">주 소</th>
                <td style="${tdStyle}" colspan="3">${e(d.address)}</td>
            </tr>
        </table>

        <h3 style="font-size:15px; font-weight:600; margin:24px 0 10px; color:#333;">2. 경력사항</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:20px;">
            <tr>
                <th style="${thStyle}">회 사 명</th>
                <td style="${tdStyle}">${e(d.company)}</td>
                <th style="${thStyle}">사업자번호</th>
                <td style="${tdStyle}">${e(d.businessNum)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">대 표 자</th>
                <td style="${tdStyle}">${e(d.ceoName)}</td>
                <th style="${thStyle}">대표전화</th>
                <td style="${tdStyle}">${e(d.phone)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">소 재 지</th>
                <td style="${tdStyle}" colspan="3">${e(d.companyAddress)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">소속부서</th>
                <td style="${tdStyle}">${e(d.department)}</td>
                <th style="${thStyle}">직위/직급</th>
                <td style="${tdStyle}">${e(d.position)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">근무기간</th>
                <td style="${tdStyle}" colspan="3">${e(d.hireDate)} ~ ${e(d.resignDate)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">담당업무</th>
                <td style="${tdStyle}" colspan="3">${e(d.jobDescription)}</td>
            </tr>
        </table>

        <h3 style="font-size:15px; font-weight:600; margin:24px 0 10px; color:#333;">3. 발급정보</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:32px;">
            <tr>
                <th style="${thStyle}">사용용도</th>
                <td style="${tdStyle}" colspan="3">${e(d.purpose)}</td>
            </tr>
        </table>

        <p style="text-align:center; font-size:15px; line-height:2; margin:36px 0;">
            ${d.resignDate && d.resignDate !== '-' && d.resignDate !== '현재' ? '위 사람은 당사에 재직(근무) 하였음을 증명합니다.' : '위 사람은 당사에서 재직(근무) 하고 있음을 증명합니다.'}
        </p>

        <p style="text-align:center; font-size:15px; font-weight:500; margin-bottom:48px;">
            ${e(d.issueDateFormatted)}
        </p>

        <div style="text-align:center; margin-top:32px;">
            <p style="font-size:16px; font-weight:600; margin-bottom:8px;">${e(d.company)}</p>
            <p style="font-size:14px; color:#555;">대표이사 &nbsp;&nbsp; ${e(d.ceoName)} &nbsp;&nbsp; (인)</p>
        </div>
    `;
}

// =========================================================================
// 위촉증명서 관련 함수
// =========================================================================

async function loadAppointmentCertInfo(userId) {
    if (!userId) return;

    try {
        const resp = await fetch(`/api/admin/approvals/appointment-cert-info/${userId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
        });
        const data = await resp.json();

        if (data.success) {
            const d = data.data;
            document.getElementById('ac-name').value = d.name || '';
            document.getElementById('ac-resident').value = d.resident_number || '';
            document.getElementById('ac-department').value = d.department || '';
            document.getElementById('ac-phone').value = d.phone || '';
            document.getElementById('ac-hire-date').value = d.hire_date || '';
            document.getElementById('ac-resign-date').value = d.resign_date || '';
            document.getElementById('ac-contract-type').value = d.contract_type || '';
            document.getElementById('ac-company-name').value = d.company_name || '';
            document.getElementById('ac-ceo-name').value = d.ceo_name || '';
        } else {
            showToast(data.message || '사원 정보를 불러올 수 없습니다.', 'error');
        }
    } catch (e) {
        showToast('사원 정보 조회 중 오류가 발생했습니다.', 'error');
    }
}

function onAppointmentCertPurposeChange() {
    const sel = document.getElementById('ac-purpose-select');
    const customWrap = document.getElementById('ac-purpose-custom-wrap');
    if (sel.value === '__custom__') {
        customWrap.style.display = '';
        document.getElementById('ac-purpose-custom').focus();
    } else {
        customWrap.style.display = 'none';
    }
}

function getAppointmentCertPurpose() {
    const sel = document.getElementById('ac-purpose-select');
    if (sel.value === '__custom__') {
        return document.getElementById('ac-purpose-custom').value.trim();
    }
    return sel.value;
}

function openAppointmentCertPreview() {
    const name = document.getElementById('ac-name').value || '-';
    const resident = document.getElementById('ac-resident').value || '-';
    const department = document.getElementById('ac-department').value || '-';
    const phone = document.getElementById('ac-phone').value || '-';
    const hireDate = document.getElementById('ac-hire-date').value || '-';
    const resignDate = document.getElementById('ac-resign-date').value || '현재';
    const contractType = document.getElementById('ac-contract-type').value || '-';
    const purpose = getAppointmentCertPurpose() || '-';
    const issueDate = document.getElementById('ac-issue-date').value || '-';
    const issueDateFormatted = issueDate !== '-' ? issueDate.replace(/-/g, function(m, i) { return i === 4 ? '년 ' : '월 '; }) + '일' : '-';
    const company = document.getElementById('ac-company-name').value || '-';
    const ceoName = document.getElementById('ac-ceo-name').value || '-';

    const el = document.getElementById('appointment-cert-preview-content');
    el.innerHTML = buildAppointmentCertPreviewHtml({ name, resident, department, phone, hireDate, resignDate, contractType, purpose, issueDateFormatted, company, ceoName });

    document.getElementById('appointment-cert-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeAppointmentCertPreview() {
    document.getElementById('appointment-cert-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printAppointmentCertPreview() {
    const content = document.getElementById('appointment-cert-preview-content').innerHTML;
    const win = window.open('', '_blank', 'width=800,height=1000');
    win.document.write('<html><head><title>위촉증명서</title>');
    win.document.write('<style>@page{size:A4;margin:0;} body{font-family:"Pretendard","Malgun Gothic",sans-serif;margin:0;padding:0;} .cert-page{padding:100px 56px 60px;box-sizing:border-box;} table{border-collapse:collapse;width:100%;table-layout:fixed;} th,td{border:1px solid #333;padding:16px 14px;font-size:15px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;}</style>');
    win.document.write('</head><body><div class="cert-page">');
    win.document.write(content);
    win.document.write('</div></body></html>');
    win.document.close();
    win.onload = function() { win.print(); };
}

function buildAppointmentCertPreviewHtml(d) {
    const e = (s) => { const div = document.createElement('div'); div.textContent = s; return div.innerHTML; };
    const thStyle = 'border:1px solid #333; padding:16px 14px; background:#f8f9fa; font-weight:600; text-align:left; white-space:nowrap; font-size:15px;';
    const tdStyle = 'border:1px solid #333; padding:16px 14px; font-size:15px; white-space:nowrap;';

    return `
        <h1 style="text-align:center; font-size:30px; font-weight:700; letter-spacing:14px; margin-bottom:60px;">위 촉 증 명 서</h1>

        <table style="border-collapse:collapse; width:100%; margin-bottom:60px; table-layout:fixed;">
            <colgroup><col style="width:18%"><col style="width:32%"><col style="width:18%"><col style="width:32%"></colgroup>
            <tr>
                <th style="${thStyle}">성 명</th>
                <td style="${tdStyle}" colspan="3">${e(d.name)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">주민등록번호</th>
                <td style="${tdStyle}" colspan="3">${e(d.resident)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">소 속</th>
                <td style="${tdStyle}">${e(d.department)}</td>
                <th style="${thStyle}">연 락 처</th>
                <td style="${tdStyle}">${e(d.phone)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">위촉기간</th>
                <td style="${tdStyle}">${e(d.hireDate)} ~ ${e(d.resignDate)}</td>
                <th style="${thStyle}">계약자격</th>
                <td style="${tdStyle}">${e(d.contractType)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">용 도</th>
                <td style="${tdStyle}" colspan="3">${e(d.purpose)}</td>
            </tr>
        </table>

        <p style="text-align:center; font-size:16px; line-height:2; margin:80px 0;">
            위와 같이 위촉하였음을 증명합니다.
        </p>

        <p style="text-align:center; font-size:16px; font-weight:500; margin-bottom:80px;">
            ${e(d.issueDateFormatted)}
        </p>

        <div style="text-align:center; margin-top:60px;">
            <p style="font-size:18px; font-weight:600; margin-bottom:10px;">${e(d.company)}</p>
            <p style="font-size:15px; color:#555;">대표이사 &nbsp;&nbsp; ${e(d.ceoName)} &nbsp;&nbsp; (인)</p>
        </div>
    `;
}

// =========================================================================
// 사직서 관련 함수
// =========================================================================

async function loadResignationInfo(userId) {
    if (!userId) return;

    try {
        const resp = await fetch(`/api/admin/approvals/resignation-info/${userId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
        });
        const data = await resp.json();

        if (data.success) {
            const d = data.data;
            document.getElementById('rg-name').value = d.name || '';
            document.getElementById('rg-resident').value = d.resident_number || '';
            document.getElementById('rg-department').value = d.department || '';
            document.getElementById('rg-position').value = d.position || '';
            document.getElementById('rg-hire-date').value = d.hire_date || '';
            document.getElementById('rg-address').value = d.address || '';
            document.getElementById('rg-company-name').value = d.company_name || '';
            document.getElementById('rg-ceo-name').value = d.ceo_name || '';
        } else {
            showToast(data.message || '사원 정보를 불러올 수 없습니다.', 'error');
        }
    } catch (e) {
        showToast('사원 정보 조회 중 오류가 발생했습니다.', 'error');
    }
}

function onResignationReasonChange() {
    const sel = document.getElementById('rg-reason-select');
    const customWrap = document.getElementById('rg-reason-custom-wrap');
    if (sel.value === '__custom__') {
        customWrap.style.display = '';
        document.getElementById('rg-reason-custom').focus();
    } else {
        customWrap.style.display = 'none';
    }
}

function getResignationReason() {
    const sel = document.getElementById('rg-reason-select');
    if (sel.value === '__custom__') {
        return document.getElementById('rg-reason-custom').value.trim();
    }
    return sel.value;
}

function openResignationPreview() {
    const department = document.getElementById('rg-department').value || '-';
    const position = document.getElementById('rg-position').value || '-';
    const name = document.getElementById('rg-name').value || '-';
    const resident = document.getElementById('rg-resident').value || '-';
    const hireDate = document.getElementById('rg-hire-date').value || '-';
    const resignDate = document.getElementById('rg-resign-date').value || '-';
    const address = document.getElementById('rg-address').value || '-';
    const reason = getResignationReason() || '-';
    const issueDate = document.getElementById('rg-issue-date').value || '-';
    const issueDateFormatted = issueDate !== '-' ? issueDate.replace(/-/g, function(m, i) { return i === 4 ? '년 ' : '월 '; }) + '일' : '-';
    const company = document.getElementById('rg-company-name').value || '-';
    const ceoName = document.getElementById('rg-ceo-name').value || '-';

    const el = document.getElementById('resignation-preview-content');
    el.innerHTML = buildResignationPreviewHtml({ department, position, name, resident, hireDate, resignDate, address, reason, issueDateFormatted, company, ceoName });

    document.getElementById('resignation-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeResignationPreview() {
    document.getElementById('resignation-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printResignationPreview() {
    const content = document.getElementById('resignation-preview-content').innerHTML;
    const win = window.open('', '_blank', 'width=800,height=1000');
    win.document.write('<html><head><title>사직서</title>');
    win.document.write('<style>@page{size:A4;margin:0;} body{font-family:"Pretendard","Malgun Gothic",sans-serif;margin:0;padding:0;} .cert-page{padding:100px 56px 60px;box-sizing:border-box;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:16px 18px;font-size:16px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:140px;}</style>');
    win.document.write('</head><body><div class="cert-page">');
    win.document.write(content);
    win.document.write('</div></body></html>');
    win.document.close();
    win.onload = function() { win.print(); };
}

function buildResignationPreviewHtml(d) {
    const e = (s) => { const div = document.createElement('div'); div.textContent = s; return div.innerHTML; };
    const thStyle = 'border:1px solid #333; padding:16px 18px; background:#f8f9fa; font-weight:600; text-align:left; white-space:nowrap; width:140px; font-size:16px;';
    const tdStyle = 'border:1px solid #333; padding:16px 18px; font-size:16px;';

    return `
        <h1 style="text-align:center; font-size:30px; font-weight:700; letter-spacing:14px; margin-bottom:60px;">사 직 서</h1>

        <table style="border-collapse:collapse; width:100%; margin-bottom:60px;">
            <tr>
                <th style="${thStyle}">소 속</th>
                <td style="${tdStyle}">${e(d.department)}</td>
                <th style="${thStyle}">직 위</th>
                <td style="${tdStyle}">${e(d.position)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">성 명</th>
                <td style="${tdStyle}">${e(d.name)}</td>
                <th style="${thStyle}">주민등록번호</th>
                <td style="${tdStyle}">${e(d.resident)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">입사일</th>
                <td style="${tdStyle}">${e(d.hireDate)}</td>
                <th style="${thStyle}">퇴사(예정)일</th>
                <td style="${tdStyle}">${e(d.resignDate)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">주 소</th>
                <td style="${tdStyle}" colspan="3">${e(d.address)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">사 유</th>
                <td style="${tdStyle}" colspan="3">${e(d.reason)}</td>
            </tr>
        </table>

        <p style="text-align:center; font-size:16px; line-height:2; margin:80px 0;">
            상기 본인은 위 사유로 인하여 사직하고자<br>
            이에 사직서를 제출하오니 허가하여 주시기 바랍니다.
        </p>

        <p style="text-align:center; font-size:16px; font-weight:500; margin-bottom:40px;">
            ${e(d.issueDateFormatted)}
        </p>

        <p style="text-align:center; font-size:15px; margin-bottom:80px;">
            신청인 &nbsp;&nbsp; ${e(d.name)} &nbsp;&nbsp; (인)
        </p>

        <div style="text-align:center; margin-top:60px;">
            <p style="font-size:18px; font-weight:600;">${e(d.company)} &nbsp;&nbsp; 대표이사 귀하</p>
        </div>
    `;
}

function buildCertPreviewHtml(d) {
    const e = (s) => { const div = document.createElement('div'); div.textContent = s; return div.innerHTML; };
    const thStyle = 'border:1px solid #333; padding:14px 16px; background:#f8f9fa; font-weight:600; text-align:left; white-space:nowrap; width:130px; font-size:15px;';
    const tdStyle = 'border:1px solid #333; padding:14px 16px; font-size:15px;';

    return `
        <h1 style="text-align:center; font-size:30px; font-weight:700; letter-spacing:14px; margin-bottom:50px;">재 직 증 명 서</h1>

        <h3 style="font-size:16px; font-weight:600; margin:30px 0 12px; color:#333;">1. 인적사항</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:24px;">
            <tr>
                <th style="${thStyle}">성 명</th>
                <td style="${tdStyle}">${e(d.name)}</td>
                <th style="${thStyle}">주민등록번호</th>
                <td style="${tdStyle}">${e(d.resident)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">주 소</th>
                <td style="${tdStyle}" colspan="3">${e(d.address)}</td>
            </tr>
        </table>

        <h3 style="font-size:16px; font-weight:600; margin:30px 0 12px; color:#333;">2. 재직사항</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:24px;">
            <tr>
                <th style="${thStyle}">회 사 명</th>
                <td style="${tdStyle}" colspan="3">${e(d.company)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">사업자번호</th>
                <td style="${tdStyle}" colspan="3">${e(d.businessNum)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">근무부서</th>
                <td style="${tdStyle}">${e(d.department)}</td>
                <th style="${thStyle}">직 급</th>
                <td style="${tdStyle}">${e(d.position)}</td>
            </tr>
            <tr>
                <th style="${thStyle}">재직기간</th>
                <td style="${tdStyle}" colspan="3">${e(d.hireDate)}</td>
            </tr>
        </table>

        <h3 style="font-size:16px; font-weight:600; margin:30px 0 12px; color:#333;">3. 발급정보</h3>
        <table style="border-collapse:collapse; width:100%; margin-bottom:40px;">
            <tr>
                <th style="${thStyle}">사용용도</th>
                <td style="${tdStyle}" colspan="3">${e(d.purpose)}</td>
            </tr>
        </table>

        <p style="text-align:center; font-size:16px; line-height:2; margin:50px 0;">
            위 사항을 증명합니다.
        </p>

        <p style="text-align:center; font-size:16px; font-weight:500; margin-bottom:60px;">
            ${e(d.issueDateFormatted)}
        </p>

        <div style="text-align:center; margin-top:40px;">
            <p style="font-size:18px; font-weight:600; margin-bottom:8px;">${e(d.company)}</p>
            <p style="font-size:15px; color:#555;">대표이사 &nbsp;&nbsp; ${e(d.ceoName)} &nbsp;&nbsp; (인)</p>
        </div>
    `;
}

// =========================================================================
// 사용인감계 관련 함수
// =========================================================================

function buildSealUsagePreviewHtml(data) {
    const e = (s) => s ? String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') : '-';
    const dateObj = data.usage_date ? new Date(data.usage_date + 'T00:00:00') : new Date();
    const y = dateObj.getFullYear();
    const m = String(dateObj.getMonth() + 1).padStart(2, ' ');
    const d = String(dateObj.getDate()).padStart(2, ' ');

    return `
        <div style="text-align:center; margin-bottom:40px;">
            <h1 style="font-size:26px; font-weight:700; letter-spacing:14px; margin:0;">사 용 인 감 계</h1>
        </div>

        <!-- 인감 비교란 -->
        <table style="width:360px; margin:0 auto 32px; border-collapse:collapse;">
            <tr>
                <td style="border:1px solid #333; padding:8px; text-align:center; font-weight:600; font-size:13px; width:180px; background:#f8f8f8;">법인인감</td>
                <td style="border:1px solid #333; padding:8px; text-align:center; font-weight:600; font-size:13px; width:180px; background:#f8f8f8;">사용인감</td>
            </tr>
            <tr>
                <td style="border:1px solid #333; height:140px; text-align:center; vertical-align:middle;">
                    <span style="color:#bbb; font-size:11px;">(인감 날인)</span>
                </td>
                <td style="border:1px solid #333; height:140px; text-align:center; vertical-align:middle;">
                    <span style="color:#bbb; font-size:11px;">(인감 날인)</span>
                </td>
            </tr>
        </table>

        <!-- 용도 / 제출처 -->
        <div style="font-size:13px; line-height:2; margin-bottom:8px;">
            <p style="margin:0;"><span style="font-weight:600;">용도:</span> ${e(data.purpose)}</p>
            <p style="margin:0;"><span style="font-weight:600;">제출처:</span> ${e(data.submit_to)}</p>
        </div>

        <!-- 확약 문구 -->
        <div style="margin:28px 0; padding:16px 20px; border:1px solid #ccc; border-radius:4px; background:#fafafa;">
            <p style="font-size:12px; line-height:1.8; margin:0; color:#333;">
                위 사용인감은 당사에서 사용하는 인감입니다. 당사는 위 인감사용으로 인한 모든 책임을 질 것을 확약하고 사용인감계를 제출합니다.
            </p>
        </div>

        <!-- 첨부서류 -->
        ${data.attachment_desc ? `<p style="font-size:12px; margin:0 0 24px; color:#333;"><span style="font-weight:600;">첨부서류:</span> ${e(data.attachment_desc)}</p>` : ''}

        <!-- 일자 -->
        <p style="text-align:center; font-size:14px; margin:32px 0 28px; letter-spacing:2px;">${y}년 ${m}월 ${d}일</p>

        <!-- 회사 정보 -->
        <div style="margin-top:20px; font-size:12px; line-height:2;">
            <p style="margin:0;"><span style="display:inline-block; width:110px; font-weight:600; letter-spacing:6px;">상 호</span>: ${e(data.company_name)}</p>
            <p style="margin:0;"><span style="display:inline-block; width:110px; font-weight:600;">사업자등록번호</span>: ${e(data.business_num)}</p>
            <p style="margin:0;"><span style="display:inline-block; width:110px; font-weight:600; letter-spacing:6px;">주 소</span>: ${e(data.company_address)}</p>
            <p style="margin:0;"><span style="display:inline-block; width:110px; font-weight:600;">대표이사</span>: ${e(data.ceo_name)}</p>
        </div>
    `;
}

function openSealUsagePreview() {
    const data = {
        usage_date: document.getElementById('su-usage-date').value,
        purpose: document.getElementById('su-purpose').value,
        submit_to: document.getElementById('su-submit-to').value,
        attachment_desc: document.getElementById('su-attachment-desc').value,
        company_name: document.getElementById('su-company-name').value,
        business_num: document.getElementById('su-business-num').value,
        ceo_name: document.getElementById('su-ceo-name').value,
        company_address: document.getElementById('su-company-address').value,
    };
    document.getElementById('seal-usage-preview-content').innerHTML = buildSealUsagePreviewHtml(data);
    document.getElementById('seal-usage-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeSealUsagePreview() {
    document.getElementById('seal-usage-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printSealUsagePreview() {
    const content = document.getElementById('seal-usage-preview-content').innerHTML;
    const win = window.open('', '_blank');
    win.document.write('<html><head><title>사용인감계</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;}@media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.print();
}

// ── 위임장 미리보기 ──
function buildDelegationPreviewHtml(data) {
    return `
        <div style="text-align: center; margin-bottom: 36px;">
            <h1 style="font-size: 28px; font-weight: 800; letter-spacing: 8px;">위 임 장</h1>
        </div>
        <table style="width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 24px;">
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; width: 100px; text-align: center;" rowspan="4">위임인</td>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; width: 100px; text-align: center;">법인명</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.company_name || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">사업자등록번호</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.business_num || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">주소</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.company_address || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">대표자</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.ceo_name || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;" rowspan="5">수임인</td>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">성명</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.agent_name || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">생년월일</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.agent_birth || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">주소</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.agent_address || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">연락처</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.agent_phone || ''}</td>
            </tr>
            <tr>
                <td style="border: 1px solid #333; background: #f5f5f5; padding: 8px 12px; font-weight: 600; text-align: center;">소속</td>
                <td style="border: 1px solid #333; padding: 8px 12px;" colspan="3">${data.agent_department || ''}</td>
            </tr>
        </table>
        <div style="margin-bottom: 20px;">
            <div style="font-weight: 600; font-size: 14px; margin-bottom: 8px; border-bottom: 2px solid #333; padding-bottom: 4px;">위임사항</div>
            <div style="font-size: 13px; line-height: 1.8; white-space: pre-wrap; padding: 8px 4px;">${data.delegation_detail || ''}</div>
        </div>
        <div style="margin-bottom: 20px;">
            <div style="font-weight: 600; font-size: 14px; margin-bottom: 8px; border-bottom: 2px solid #333; padding-bottom: 4px;">위임기간</div>
            <div style="font-size: 13px; padding: 8px 4px;">${data.period_start || ''} ~ ${data.period_end || ''}</div>
        </div>
        ${data.attachments_desc ? `
        <div style="margin-bottom: 20px;">
            <div style="font-weight: 600; font-size: 14px; margin-bottom: 8px; border-bottom: 2px solid #333; padding-bottom: 4px;">첨부서류</div>
            <div style="font-size: 13px; line-height: 1.8; white-space: pre-wrap; padding: 8px 4px;">${data.attachments_desc}</div>
        </div>` : ''}
        <div style="text-align: center; margin-top: 40px; font-size: 13px;">
            <p>위와 같이 권한을 위임합니다.</p>
            <p style="margin-top: 24px; font-size: 14px; font-weight: 600;">${data.company_name || ''}</p>
            <p style="margin-top: 4px;">대표이사 ${data.ceo_name || ''} (인)</p>
        </div>
    `;
}

function openDelegationPreview() {
    const data = {
        company_name: document.getElementById('dl-company-name').value,
        business_num: document.getElementById('dl-business-num').value,
        ceo_name: document.getElementById('dl-ceo-name').value,
        company_address: document.getElementById('dl-company-address').value,
        agent_name: document.getElementById('dl-agent-name').value,
        agent_birth: document.getElementById('dl-agent-birth').value,
        agent_address: document.getElementById('dl-agent-address').value,
        agent_phone: document.getElementById('dl-agent-phone').value,
        agent_department: document.getElementById('dl-agent-department').value,
        delegation_detail: document.getElementById('dl-delegation-detail').value,
        period_start: document.getElementById('dl-period-start').value,
        period_end: document.getElementById('dl-period-end').value,
        attachments_desc: document.getElementById('dl-attachments-desc').value,
    };
    document.getElementById('delegation-preview-content').innerHTML = buildDelegationPreviewHtml(data);
    document.getElementById('delegation-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeDelegationPreview() {
    document.getElementById('delegation-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

// ── 이사회의사록 미리보기 ──
function buildBoardMinutesPreviewHtml(data) {
    const dt = data.meeting_datetime || '';
    let dateStr = '';
    if (dt) {
        const d = new Date(dt);
        const year = d.getFullYear();
        const month = d.getMonth() + 1;
        const day = d.getDate();
        const hour = d.getHours();
        const min = String(d.getMinutes()).padStart(2, '0');
        const ampm = hour < 12 ? '오전' : '오후';
        const h12 = hour % 12 || 12;
        dateStr = `${year}년 ${month}월 ${day}일 ${ampm} ${h12}시 ${min}분`;
    }

    const agendas = data.agendas || [];
    let agendasHtml = agendas.map(a =>
        `<div style="margin-bottom: 12px;">
            <div style="font-weight: 600; margin-bottom: 4px;">[제${a.no}호 의안: ${a.title}]</div>
            ${a.result ? `<div style="padding-left: 16px;">* ${a.result}</div>` : ''}
        </div>`
    ).join('');

    const signers = data.signers || [];
    let signersHtml = signers.map(s =>
        `<div style="display: flex; gap: 40px; margin-bottom: 8px; justify-content: center;">
            <span style="min-width: 120px; text-align: right;">${s.role}:</span>
            <span style="min-width: 100px;">${s.name}</span>
            <span>(인) &#12958;</span>
        </div>`
    ).join('');

    return `
        <div style="text-align: center; margin-bottom: 36px;">
            <h1 style="font-size: 26px; font-weight: 800; letter-spacing: 6px;">이 사 회 의 사 록</h1>
        </div>
        <div style="font-size: 13px; line-height: 2;">
            <p><strong>1. 일 시:</strong> ${dateStr}</p>
            <p><strong>2. 장 소:</strong> ${data.meeting_place || ''}</p>
            <p><strong>3. 출석이사 및 감사:</strong></p>
            <div style="padding-left: 24px;">
                <p>* 이사 총수: ${data.total_directors || 0}명 (출석이사: ${data.present_directors || 0}명)</p>
                <p>* 감사 총수: ${data.total_auditors || 0}명 (출석감사: ${data.present_auditors || 0}명)</p>
            </div>
            <p style="margin-top: 8px;"><strong>4. 의 안:</strong></p>
            <div style="padding-left: 24px; margin-bottom: 8px;">
                ${agendas.map(a => `<p>${a.title}</p>`).join('')}
            </div>
            <p><strong>5. 의사 경과 및 결과:</strong></p>
            <div style="padding-left: 24px; margin-bottom: 8px;">
                ${data.proceedings ? `<p>${data.proceedings}</p>` : `<p>의장(대표이사 ${data.chairman_name || ''})은 위와 같이 법정 수에 달하는 이사가 출석하였으므로 본 이사회가 적법하게 성립되었음을 선언하고, 다음의 의안을 상정하여 승인을 구하다.</p>`}
                ${agendasHtml}
            </div>
            <p><strong>6. 폐 회:</strong></p>
            <div style="padding-left: 24px;">
                <p>의장은 이상으로써 의안 전부의 심의를 종료하였으므로 폐회를 선언하다.</p>
                ${data.closing_time ? `<p>(폐회 시각: ${data.closing_time})</p>` : ''}
            </div>
        </div>
        <div style="margin-top: 32px; font-size: 13px; line-height: 1.8; text-align: center;">
            <p>위 의사의 경과와 결과를 명확히 하기 위하여 이 의사록을 작성하고,</p>
            <p>의장과 출석한 이사 및 감사가 아래와 같이 기명날인한다.</p>
            <p style="margin-top: 20px; font-size: 14px;">${data.meeting_date || ''}</p>
            <p style="margin-top: 8px; font-size: 15px; font-weight: 700;">${data.company_name || ''}</p>
        </div>
        <div style="margin-top: 32px; font-size: 13px;">
            ${signersHtml}
        </div>
    `;
}

function openBoardMinutesPreview() {
    const bmContainer = document.getElementById('board-minutes-form-container');
    const bmAlpine = bmContainer._x_dataStack?.[0];
    const data = {
        meeting_datetime: document.getElementById('bm-meeting-datetime').value,
        meeting_place: document.getElementById('bm-meeting-place').value,
        total_directors: parseInt(document.getElementById('bm-total-directors').value) || 0,
        present_directors: parseInt(document.getElementById('bm-present-directors').value) || 0,
        total_auditors: parseInt(document.getElementById('bm-total-auditors').value) || 0,
        present_auditors: parseInt(document.getElementById('bm-present-auditors').value) || 0,
        chairman_name: document.getElementById('bm-chairman-name').value,
        agendas: bmAlpine ? bmAlpine.agendas.filter(a => a.title.trim()) : [],
        proceedings: document.getElementById('bm-proceedings').value,
        closing_time: document.getElementById('bm-closing-time').value,
        signers: bmAlpine ? bmAlpine.signers.filter(s => s.name.trim()) : [],
        company_name: document.getElementById('bm-company-name').value,
        meeting_date: (document.getElementById('bm-meeting-datetime').value || '').split('T')[0],
    };
    document.getElementById('board-minutes-preview-content').innerHTML = buildBoardMinutesPreviewHtml(data);
    document.getElementById('board-minutes-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeBoardMinutesPreview() {
    document.getElementById('board-minutes-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printBoardMinutesPreview() {
    const content = document.getElementById('board-minutes-preview-content').innerHTML;
    const win = window.open('', '_blank');
    win.document.write('<html><head><title>이사회의사록</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;}@media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.print();
}

// ─── 견적서 미리보기 ───
function buildQuotationPreviewHtml(data) {
    const fmt = n => (n || 0).toLocaleString('ko-KR');
    let itemsHtml = '';
    (data.items || []).forEach((item, idx) => {
        itemsHtml += `<tr style="border-bottom:1px solid #ddd;">
            <td style="padding:6px 8px;text-align:center;font-size:12px;">${idx + 1}</td>
            <td style="padding:6px 8px;font-size:12px;">${item.name || ''}</td>
            <td style="padding:6px 8px;font-size:12px;color:#555;">${item.spec || ''}</td>
            <td style="padding:6px 8px;text-align:right;font-size:12px;">${item.qty || 0}</td>
            <td style="padding:6px 8px;text-align:right;font-size:12px;">${fmt(item.unit_price)}</td>
            <td style="padding:6px 8px;text-align:right;font-size:12px;font-weight:600;">${fmt(item.supply_amount)}</td>
            <td style="padding:6px 8px;text-align:right;font-size:12px;color:#555;">${fmt(item.tax)}</td>
            <td style="padding:6px 8px;font-size:12px;color:#555;">${item.note || ''}</td>
        </tr>`;
    });

    return `
    <div style="text-align:center;margin-bottom:32px;">
        <h1 style="font-size:28px;font-weight:800;letter-spacing:8px;margin:0;">견 적 서</h1>
    </div>
    <div style="display:flex;justify-content:space-between;margin-bottom:24px;">
        <div style="font-size:14px;">
            <p style="margin:0 0 4px;"><strong>${data.client_name || ''}</strong> 귀하</p>
            <p style="margin:0;font-size:12px;color:#555;">아래와 같이 견적합니다.</p>
        </div>
        <div style="font-size:12px;text-align:right;color:#555;">
            <p style="margin:0;">견적일자: ${data.quote_date || ''}</p>
        </div>
    </div>
    <div style="background:#EFF6FF;border:2px solid #3B82F6;border-radius:8px;padding:16px 24px;text-align:center;margin-bottom:24px;">
        <p style="margin:0 0 4px;font-size:13px;color:#555;">견적금액</p>
        <p style="margin:0;font-size:24px;font-weight:800;color:#1E40AF;">₩ ${fmt(data.total_amount)}</p>
        <p style="margin:4px 0 0;font-size:11px;color:#666;">(공급가액 ${fmt(data.total_supply)} + 부가세 ${fmt(data.total_tax)})</p>
    </div>
    <table style="width:100%;border-collapse:collapse;margin-bottom:16px;font-size:12px;">
        <caption style="text-align:left;font-weight:700;font-size:13px;margin-bottom:8px;">공급자</caption>
        <tbody>
            <tr style="border-bottom:1px solid #eee;">
                <td style="padding:6px 8px;background:#F9FAFB;width:100px;font-weight:600;font-size:11px;">사업자등록번호</td>
                <td style="padding:6px 8px;">${data.business_num || ''}</td>
                <td style="padding:6px 8px;background:#F9FAFB;width:60px;font-weight:600;font-size:11px;">상호</td>
                <td style="padding:6px 8px;">${data.company_name || ''}</td>
                <td style="padding:6px 8px;background:#F9FAFB;width:60px;font-weight:600;font-size:11px;">대표자</td>
                <td style="padding:6px 8px;">${data.ceo_name || ''}</td>
            </tr>
            <tr style="border-bottom:1px solid #eee;">
                <td style="padding:6px 8px;background:#F9FAFB;font-weight:600;font-size:11px;">소재지</td>
                <td colspan="5" style="padding:6px 8px;">${data.company_address || ''}</td>
            </tr>
            <tr style="border-bottom:1px solid #eee;">
                <td style="padding:6px 8px;background:#F9FAFB;font-weight:600;font-size:11px;">업태</td>
                <td style="padding:6px 8px;">${data.business_type || ''}</td>
                <td style="padding:6px 8px;background:#F9FAFB;font-weight:600;font-size:11px;">업종</td>
                <td colspan="3" style="padding:6px 8px;">${data.business_item || ''}</td>
            </tr>
            <tr>
                <td style="padding:6px 8px;background:#F9FAFB;font-weight:600;font-size:11px;">연락처</td>
                <td style="padding:6px 8px;">${data.phone || ''}</td>
                <td style="padding:6px 8px;background:#F9FAFB;font-weight:600;font-size:11px;">계좌</td>
                <td colspan="3" style="padding:6px 8px;">${data.bank_account || ''}</td>
            </tr>
        </tbody>
    </table>
    <table style="width:100%;border-collapse:collapse;margin-bottom:16px;">
        <thead>
            <tr style="background:#F9FAFB;border-bottom:2px solid #ccc;">
                <th style="padding:8px;text-align:center;font-size:11px;width:32px;">No</th>
                <th style="padding:8px;text-align:left;font-size:11px;">품명</th>
                <th style="padding:8px;text-align:left;font-size:11px;">규격</th>
                <th style="padding:8px;text-align:right;font-size:11px;">수량</th>
                <th style="padding:8px;text-align:right;font-size:11px;">단가</th>
                <th style="padding:8px;text-align:right;font-size:11px;">공급가액</th>
                <th style="padding:8px;text-align:right;font-size:11px;">세액</th>
                <th style="padding:8px;text-align:left;font-size:11px;">비고</th>
            </tr>
        </thead>
        <tbody>${itemsHtml}</tbody>
        <tfoot>
            <tr style="border-top:2px solid #999;background:#F9FAFB;">
                <td colspan="5" style="padding:8px;text-align:right;font-weight:700;font-size:12px;">합 계</td>
                <td style="padding:8px;text-align:right;font-weight:700;font-size:12px;color:#1E40AF;">${fmt(data.total_supply)}</td>
                <td style="padding:8px;text-align:right;font-weight:700;font-size:12px;color:#1E40AF;">${fmt(data.total_tax)}</td>
                <td></td>
            </tr>
        </tfoot>
    </table>
    ${data.remarks ? `<div style="margin-top:16px;padding:12px 16px;background:#FFFBEB;border:1px solid #FDE68A;border-radius:6px;font-size:12px;"><strong style="font-size:11px;color:#92400E;">특이사항</strong><p style="margin:4px 0 0;white-space:pre-wrap;">${data.remarks}</p></div>` : ''}
    `;
}

function openQuotationPreview() {
    const qtContainer = document.getElementById('quotation-form-container');
    const qtAlpine = qtContainer._x_dataStack?.[0];
    const qtItems = qtAlpine ? qtAlpine.items.filter(i => i.name.trim()).map(i => ({
        name: i.name.trim(), spec: (i.spec||'').trim(), qty: parseInt(i.qty)||0, unit_price: parseInt(i.unit_price)||0,
        supply_amount: (parseInt(i.qty)||0) * (parseInt(i.unit_price)||0), tax: qtAlpine.itemTax(i), note: (i.note||'').trim(),
    })) : [];
    const data = {
        client_name: document.getElementById('qt-client-name').value.trim(),
        quote_date: document.getElementById('qt-quote-date').value,
        company_name: document.getElementById('qt-company-name').value,
        business_num: document.getElementById('qt-business-num').value,
        ceo_name: document.getElementById('qt-ceo-name').value,
        company_address: document.getElementById('qt-company-address').value,
        business_type: document.getElementById('qt-business-type-input')?.value || '',
        business_item: document.getElementById('qt-business-item-input')?.value || '',
        phone: document.getElementById('qt-phone-input')?.value || '',
        bank_account: document.getElementById('qt-bank-input')?.value || '',
        items: qtItems,
        total_supply: qtAlpine ? qtAlpine.totalSupply() : 0,
        total_tax: qtAlpine ? qtAlpine.totalTax() : 0,
        total_amount: qtAlpine ? qtAlpine.totalAmount() : 0,
        remarks: document.getElementById('qt-remarks').value.trim(),
    };
    document.getElementById('quotation-preview-content').innerHTML = buildQuotationPreviewHtml(data);
    document.getElementById('quotation-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeQuotationPreview() {
    document.getElementById('quotation-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printQuotationPreview() {
    const content = document.getElementById('quotation-preview-content').innerHTML;
    const win = window.open('', '_blank');
    win.document.write('<html><head><title>견적서</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;}@media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.print();
}

// ─── 공문서 미리보기 ───
function buildOfficialLetterPreviewHtml(data) {
    const bodyHtml = (data.body || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g, '<br>');
    const attachHtml = (data.attachments_desc || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g, '<br>');
    return `
    <div style="text-align:center;margin-bottom:32px;">
        <h1 style="font-size:22px;font-weight:800;margin:0;">${data.company_name || ''}</h1>
    </div>
    <div style="border-bottom:2px solid #333;padding-bottom:16px;margin-bottom:24px;font-size:13px;line-height:2;">
        <div><span style="display:inline-block;width:80px;letter-spacing:12px;font-weight:600;">문서번호</span> : ${data.doc_number || ''}</div>
        <div><span style="display:inline-block;width:80px;letter-spacing:18px;font-weight:600;">일자</span> : ${data.doc_date || ''}</div>
        <div><span style="display:inline-block;width:80px;letter-spacing:18px;font-weight:600;">수신</span> : ${data.recipient || ''}</div>
        ${data.reference ? `<div><span style="display:inline-block;width:80px;letter-spacing:18px;font-weight:600;">참조</span> : ${data.reference}</div>` : ''}
        <div><span style="display:inline-block;width:80px;letter-spacing:18px;font-weight:600;">제목</span> : <strong>${data.subject || ''}</strong></div>
    </div>
    <div style="font-size:13px;line-height:1.8;margin-bottom:24px;min-height:200px;">${bodyHtml}</div>
    ${data.attachments_desc ? `<div style="font-size:13px;line-height:1.6;margin-bottom:24px;padding-top:12px;border-top:1px solid #ddd;"><strong>붙임 :</strong><br>${attachHtml}</div>` : ''}
    <div style="text-align:center;margin:40px 0 16px;font-size:14px;">
        <span>${data.company_name || ''}</span>&nbsp;&nbsp;&nbsp;&nbsp;
        <span>대표이사&nbsp;&nbsp;&nbsp;${data.ceo_name || ''}</span>&nbsp;&nbsp;
        <span style="color:#999;">[직인날인]</span>
    </div>
    <div style="border-top:1px solid #ccc;padding-top:8px;font-size:10px;color:#888;line-height:1.6;">
        ${data.company_address ? `<div>${data.company_address}</div>` : ''}
        <div>${data.phone ? '전화 ' + data.phone : ''}${data.fax ? ' / 팩스 ' + data.fax : ''}${data.email ? ' / 이메일 ' + data.email : ''}</div>
    </div>`;
}

function openOfficialLetterPreview() {
    const data = {
        doc_number: document.getElementById('ol-doc-number').value.trim(),
        doc_date: document.getElementById('ol-doc-date').value,
        recipient: document.getElementById('ol-recipient').value.trim(),
        reference: document.getElementById('ol-reference').value.trim(),
        subject: document.getElementById('ol-subject').value.trim(),
        body: document.getElementById('ol-body').value.trim(),
        attachments_desc: document.getElementById('ol-attachments-desc').value.trim(),
        company_name: document.getElementById('ol-company-name').value,
        ceo_name: document.getElementById('ol-ceo-name').value,
        company_address: document.getElementById('ol-company-address').value,
        phone: document.getElementById('ol-phone-input')?.value || '',
        fax: document.getElementById('ol-fax-input')?.value || '',
        email: document.getElementById('ol-email-input')?.value || '',
    };
    document.getElementById('official-letter-preview-content').innerHTML = buildOfficialLetterPreviewHtml(data);
    document.getElementById('official-letter-preview-modal').style.display = '';
    document.body.style.overflow = 'hidden';
}

function closeOfficialLetterPreview() {
    document.getElementById('official-letter-preview-modal').style.display = 'none';
    document.body.style.overflow = '';
}

function printOfficialLetterPreview() {
    const content = document.getElementById('official-letter-preview-content').innerHTML;
    const win = window.open('', '_blank');
    win.document.write('<html><head><title>공문서</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;}@media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.print();
}

function printDelegationPreview() {
    const content = document.getElementById('delegation-preview-content').innerHTML;
    const win = window.open('', '_blank');
    win.document.write('<html><head><title>위임장</title>');
    win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;}@media print{body{padding:40px 48px;}}</style>');
    win.document.write('</head><body>');
    win.document.write(content);
    win.document.write('</body></html>');
    win.document.close();
    win.print();
}
</script>
@endpush
