@extends('layouts.app')

@section('title', '전자계약 문서')

@section('content')
<div id="esign-docs-root"></div>
@endsection

@push('scripts')
@include('partials.react-cdn')
<script src="https://unpkg.com/lucide@0.469.0"></script>
@verbatim
<script type="text/babel">
const { useState, useEffect } = React;

// ============================================================
// Tab Definitions
// ============================================================
const TABS = [
    { id: 'overview',    label: '개요',       icon: 'book-open' },
    { id: 'manual',      label: '사용자 매뉴얼', icon: 'help-circle' },
    { id: 'workflow',    label: '워크플로우',  icon: 'git-branch' },
    { id: 'architecture',label: '아키텍처',   icon: 'layers' },
    { id: 'api',         label: 'API 명세',   icon: 'code' },
    { id: 'security',    label: '보안',       icon: 'shield' },
    { id: 'screens',     label: '화면 설계',  icon: 'monitor' },
    { id: 'operations',  label: '운영 가이드', icon: 'settings' },
    { id: 'changelog',   label: '변경 이력',  icon: 'clock' },
];

// ============================================================
// Shared UI Components
// ============================================================
const Badge = ({ children, color = 'blue' }) => {
    const colors = {
        blue: 'bg-blue-100 text-blue-700',
        green: 'bg-green-100 text-green-700',
        yellow: 'bg-yellow-100 text-yellow-700',
        red: 'bg-red-100 text-red-700',
        gray: 'bg-gray-100 text-gray-600',
        purple: 'bg-purple-100 text-purple-700',
        indigo: 'bg-indigo-100 text-indigo-700',
    };
    return <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${colors[color] || colors.blue}`}>{children}</span>;
};

const SectionTitle = ({ children }) => (
    <h2 className="text-lg font-bold text-gray-900 mb-4 pb-2 border-b border-gray-200">{children}</h2>
);

const SubTitle = ({ children }) => (
    <h3 className="text-base font-semibold text-gray-800 mt-6 mb-3">{children}</h3>
);

const CodeBlock = ({ children, title }) => (
    <div className="my-3">
        {title && <p className="text-xs font-medium text-gray-500 mb-1">{title}</p>}
        <pre className="bg-gray-900 text-gray-100 rounded-lg p-4 text-sm overflow-x-auto leading-relaxed"><code>{children}</code></pre>
    </div>
);

const InfoCard = ({ title, children, color = 'blue' }) => {
    const colors = {
        blue: 'border-blue-200 bg-blue-50',
        green: 'border-green-200 bg-green-50',
        yellow: 'border-yellow-200 bg-yellow-50',
        red: 'border-red-200 bg-red-50',
        gray: 'border-gray-200 bg-gray-50',
    };
    return (
        <div className={`border rounded-lg p-4 ${colors[color] || colors.blue}`}>
            {title && <p className="font-semibold text-sm mb-2">{title}</p>}
            <div className="text-sm text-gray-700">{children}</div>
        </div>
    );
};

const Table = ({ headers, rows }) => (
    <div className="overflow-x-auto my-3">
        <table className="w-full text-sm border border-gray-200 rounded-lg overflow-hidden">
            <thead className="bg-gray-50">
                <tr>
                    {headers.map((h, i) => (
                        <th key={i} className="px-3 py-2 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider border-b">{h}</th>
                    ))}
                </tr>
            </thead>
            <tbody className="divide-y divide-gray-100">
                {rows.map((row, ri) => (
                    <tr key={ri} className="hover:bg-gray-50">
                        {row.map((cell, ci) => (
                            <td key={ci} className="px-3 py-2 text-gray-700 whitespace-nowrap">{cell}</td>
                        ))}
                    </tr>
                ))}
            </tbody>
        </table>
    </div>
);

// ============================================================
// Tab 1: Overview
// ============================================================
const OverviewTab = () => (
    <div>
        <SectionTitle>프로젝트 개요</SectionTitle>
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
            <InfoCard title="프로젝트" color="blue">
                <p>SAM E-Sign</p>
                <p className="text-xs text-gray-500 mt-1">v1.0 / 2026-02-12</p>
            </InfoCard>
            <InfoCard title="규모" color="green">
                <p>총 33개 파일 (신규 29 + 수정 4)</p>
                <p className="text-xs text-gray-500 mt-1">+3,273 라인</p>
            </InfoCard>
            <InfoCard title="기술 스택" color="gray">
                <p>Laravel 11 + React 18 + MySQL 8</p>
                <p className="text-xs text-gray-500 mt-1">PDF.js + SignaturePad + 카카오 알림톡</p>
            </InfoCard>
        </div>

        <SubTitle>파일 구성</SubTitle>
        <Table
            headers={['영역', '파일 수', '설명']}
            rows={[
                ['DB 마이그레이션', '4', 'esign_ 접두사 테이블'],
                ['Models', '4', 'Contract, Signer, SignField, AuditLog'],
                ['Services', '4', 'Contract, Sign, Pdf, Audit'],
                ['API Controllers', '2', '계약관리 10 + 서명 6 엔드포인트'],
                ['Form Requests', '4', 'Store, Configure, Submit, Reject'],
                ['Mail Templates', '1', 'EsignRequestMail'],
                ['알림톡 Templates', '3', '서명요청/OTP인증/완료 알림톡'],
                ['MNG Controllers', '2', '인증 5화면 + 공개 3화면'],
                ['MNG Views', '8', 'React 하이브리드'],
                ['API Routes', '16', '계약 + 서명 라우트'],
                ['MNG Routes', '8', '화면 + 공개 라우트'],
            ]}
        />

        <SubTitle>기술 스택 상세</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <InfoCard title="Backend" color="gray">
                <ul className="space-y-1">
                    <li>Laravel 11 (PHP 8.3)</li>
                    <li>MySQL 8.0 (Multi-tenant)</li>
                    <li>FPDI/FPDF (PDF 합성 - 예정)</li>
                    <li>Laravel Mail (이메일 발송)</li>
                    <li>카카오 알림톡 API (서명 요청/OTP/알림 발송)</li>
                </ul>
            </InfoCard>
            <InfoCard title="Frontend" color="gray">
                <ul className="space-y-1">
                    <li>React 18 + Babel (CDN, 브라우저 트랜스파일링)</li>
                    <li>HTMX (네비게이션)</li>
                    <li>Tailwind CSS (스타일링)</li>
                    <li>PDF.js (PDF 렌더링)</li>
                    <li>signature_pad.js (서명 캔버스)</li>
                    <li>Lucide (아이콘)</li>
                </ul>
            </InfoCard>
        </div>
    </div>
);

// ============================================================
// Tab: User Manual (사용자 매뉴얼)
// ============================================================
const StepCard = ({ step, title, children, color = 'blue' }) => {
    const bg = { blue: 'bg-blue-600', green: 'bg-green-600', yellow: 'bg-yellow-500', purple: 'bg-purple-600', indigo: 'bg-indigo-600', red: 'bg-red-600' };
    return (
        <div className="border border-gray-200 rounded-xl overflow-hidden">
            <div className={`flex items-center gap-3 px-4 py-3 ${bg[color] || bg.blue} text-white`}>
                <span className="flex-shrink-0 w-7 h-7 bg-white/20 rounded-full flex items-center justify-center text-sm font-bold">{step}</span>
                <span className="font-semibold">{title}</span>
            </div>
            <div className="p-4 text-sm text-gray-700 space-y-2">{children}</div>
        </div>
    );
};

const TipBox = ({ children, type = 'tip' }) => {
    const styles = {
        tip: { border: 'border-blue-300', bg: 'bg-blue-50', icon: 'bg-blue-500', emoji: 'i', text: 'text-blue-800' },
        warning: { border: 'border-yellow-300', bg: 'bg-yellow-50', icon: 'bg-yellow-500', emoji: '!', text: 'text-yellow-800' },
        success: { border: 'border-green-300', bg: 'bg-green-50', icon: 'bg-green-500', emoji: '\u2713', text: 'text-green-800' },
    };
    const s = styles[type] || styles.tip;
    return (
        <div className={`flex gap-3 ${s.bg} ${s.border} border rounded-lg p-3 my-3`}>
            <span className={`flex-shrink-0 w-5 h-5 ${s.icon} text-white rounded-full flex items-center justify-center text-xs font-bold`}>{s.emoji}</span>
            <div className={`text-sm ${s.text}`}>{children}</div>
        </div>
    );
};

const FaqItem = ({ q, children }) => {
    const [open, setOpen] = useState(false);
    return (
        <div className="border border-gray-200 rounded-lg overflow-hidden">
            <button onClick={() => setOpen(!open)} className="w-full flex items-center justify-between px-4 py-3 text-left hover:bg-gray-50 transition-colors">
                <span className="text-sm font-medium text-gray-900">Q. {q}</span>
                <span className="text-gray-400 text-lg flex-shrink-0 ml-2">{open ? '\u2212' : '+'}</span>
            </button>
            {open && <div className="px-4 pb-3 text-sm text-gray-600 border-t border-gray-100 pt-3">{children}</div>}
        </div>
    );
};

const UserManualTab = () => (
    <div>
        <SectionTitle>사용자 매뉴얼</SectionTitle>

        {/* 소개 */}
        <div className="bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-xl p-5 mb-6">
            <h3 className="text-base font-bold text-blue-900 mb-2">SAM E-Sign이란?</h3>
            <p className="text-sm text-blue-800 mb-3">
                PDF 계약서에 온라인으로 전자서명하는 솔루션입니다.<br/>
                종이 계약서를 인쇄하고 대면으로 서명받을 필요 없이, <strong>카카오 알림톡 또는 이메일 링크 하나로</strong> 간편하게 계약을 체결할 수 있습니다.
            </p>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-3 mt-4">
                {[
                    { icon: 'upload', label: 'PDF 업로드', desc: '계약서를 업로드' },
                    { icon: 'mouse-pointer', label: '서명란 배치', desc: '위치 지정' },
                    { icon: 'send', label: '알림톡/이메일', desc: '서명 요청 발송' },
                    { icon: 'check-circle', label: '서명 완료', desc: '양쪽 서명' },
                ].map((item, i) => (
                    <div key={i} className="bg-white rounded-lg p-3 text-center border border-blue-100">
                        <i data-lucide={item.icon} className="w-5 h-5 mx-auto text-blue-600 mb-1"></i>
                        <p className="text-xs font-semibold text-gray-800">{item.label}</p>
                        <p className="text-xs text-gray-500">{item.desc}</p>
                    </div>
                ))}
            </div>
        </div>

        {/* 사용자 역할 */}
        <SubTitle>누가 사용하나요?</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
            <InfoCard title="계약 생성자 (갑)" color="blue">
                <p className="mb-1">SAM MNG에 로그인하여 사용합니다.</p>
                <ul className="space-y-0.5 text-gray-600">
                    <li>- 계약서 PDF 업로드</li>
                    <li>- 서명란 위치 지정</li>
                    <li>- 서명 요청 알림톡/이메일 발송</li>
                    <li>- 계약 진행 상황 관리</li>
                </ul>
            </InfoCard>
            <InfoCard title="서명 상대방 (을)" color="green">
                <p className="mb-1">카카오 알림톡 또는 이메일 링크로 접속합니다. (로그인 불필요)</p>
                <ul className="space-y-0.5 text-gray-600">
                    <li>- 알림톡/이메일 OTP 본인인증</li>
                    <li>- 계약서 내용 확인</li>
                    <li>- 전자서명 또는 거절</li>
                </ul>
            </InfoCard>
        </div>

        {/* 사전 준비물 */}
        <SubTitle>시작하기 전에 준비하세요</SubTitle>
        <Table
            headers={['준비물', '형식', '비고']}
            rows={[
                ['계약서 PDF 파일', '.pdf 파일', '최대 20MB'],
                ['작성자(갑) 이름/이메일', '텍스트 / 이메일', 'OTP 인증에 사용'],
                ['상대방(을) 이름/이메일', '텍스트 / 이메일', '서명 링크 발송용'],
                ['상대방(을) 전화번호', '숫자 (010-xxxx-xxxx)', '카카오 알림톡 발송용 (선택)'],
            ]}
        />
        <TipBox type="tip">Word, 한글 등의 파일은 PDF로 변환한 후 업로드하세요. PDF 형식만 지원됩니다.</TipBox>

        {/* ===== 계약 생성자(갑) 가이드 ===== */}
        <div className="mt-8 mb-4">
            <h3 className="text-base font-bold text-blue-700 flex items-center gap-2">
                <span className="w-6 h-6 bg-blue-100 rounded-full flex items-center justify-center text-blue-700 text-xs font-bold">갑</span>
                계약 생성자 가이드 (갑)
            </h3>
            <p className="text-sm text-gray-500 mt-1">SAM MNG에 로그인 후 진행합니다.</p>
        </div>

        <div className="space-y-4">
            <StepCard step="1" title="새 계약 생성" color="blue">
                <p><strong>메뉴 이동:</strong> 사이드바 → SAM E-Sign → 새 계약 생성</p>
                <div className="bg-gray-50 rounded-lg p-3 mt-2 space-y-2">
                    <p className="font-medium text-gray-800">입력 항목:</p>
                    <ul className="space-y-1 ml-2">
                        <li><Badge color="red">필수</Badge> <strong>계약 제목</strong> - 계약서 이름 (최대 200자)</li>
                        <li><Badge color="gray">선택</Badge> <strong>계약 설명</strong> - 부가 설명 (최대 2,000자)</li>
                        <li><Badge color="red">필수</Badge> <strong>PDF 파일</strong> - 계약서 PDF 업로드 (최대 20MB)</li>
                        <li><Badge color="gray">선택</Badge> <strong>서명 기한</strong> - 기본 7일</li>
                        <li><Badge color="gray">선택</Badge> <strong>서명 순서</strong> - 상대방 먼저(기본) 또는 작성자 먼저</li>
                    </ul>
                    <div className="border-t border-gray-200 pt-2 mt-2">
                        <p className="font-medium text-gray-800">서명자 정보:</p>
                        <ul className="space-y-1 ml-2">
                            <li><Badge color="red">필수</Badge> 작성자(갑) 이름, 이메일</li>
                            <li><Badge color="red">필수</Badge> 상대방(을) 이름, 이메일</li>
                            <li><Badge color="gray">선택</Badge> 전화번호</li>
                        </ul>
                    </div>
                </div>
                <TipBox type="tip">계약 제목은 서명 요청 알림톡/이메일의 제목에 포함됩니다. 상대방이 알아보기 쉽게 작성하세요. 전화번호를 입력하면 카카오 알림톡으로도 서명 요청이 발송됩니다.</TipBox>
                <p className="text-gray-600">"계약 생성" 버튼을 누르면 계약 코드(예: <code className="bg-gray-100 px-1 rounded text-xs">ES-20260212-A1B2C3</code>)가 자동 생성되고, 서명 위치 지정 화면으로 이동합니다.</p>
            </StepCard>

            <StepCard step="2" title="서명 위치 지정" color="indigo">
                <p>업로드한 PDF가 화면에 표시됩니다. 서명이 필요한 위치에 필드를 배치합니다.</p>
                <div className="bg-gray-50 rounded-lg p-3 mt-2">
                    <p className="font-medium text-gray-800 mb-2">사용 방법:</p>
                    <ol className="list-decimal list-inside space-y-1.5 text-gray-700">
                        <li>오른쪽 패널에서 <strong>필드 타입</strong>을 선택합니다 (서명, 도장, 텍스트, 날짜, 체크박스)</li>
                        <li>PDF 문서 위의 원하는 위치를 <strong>클릭</strong>하여 필드를 배치합니다</li>
                        <li>필드를 <strong>드래그</strong>하여 위치를 조정하고, 모서리를 드래그하여 크기를 조정합니다</li>
                        <li>여러 페이지에 걸쳐 배치할 수 있습니다</li>
                    </ol>
                </div>
                <div className="flex gap-4 mt-3">
                    <div className="flex items-center gap-2 text-sm">
                        <span className="w-4 h-4 bg-blue-500 rounded"></span>
                        <span className="text-gray-600">파란색 = 작성자(갑) 서명란</span>
                    </div>
                    <div className="flex items-center gap-2 text-sm">
                        <span className="w-4 h-4 bg-red-500 rounded"></span>
                        <span className="text-gray-600">빨간색 = 상대방(을) 서명란</span>
                    </div>
                </div>
                <TipBox type="warning">서명 요청 발송 후에는 위치를 변경할 수 없습니다. 신중하게 배치하세요.</TipBox>
            </StepCard>

            <StepCard step="3" title="서명 요청 발송" color="purple">
                <p>서명 위치 지정을 완료하면 발송 확인 화면이 표시됩니다.</p>
                <div className="bg-gray-50 rounded-lg p-3 mt-2">
                    <p className="font-medium text-gray-800 mb-2">발송 전 체크리스트를 확인하세요:</p>
                    <ul className="space-y-1">
                        <li className="flex items-center gap-2"><span className="text-green-500 font-bold">&#10003;</span> PDF 문서 업로드 완료</li>
                        <li className="flex items-center gap-2"><span className="text-green-500 font-bold">&#10003;</span> 서명 필드 설정 완료</li>
                        <li className="flex items-center gap-2"><span className="text-green-500 font-bold">&#10003;</span> 문서 무결성 확인</li>
                        <li className="flex items-center gap-2"><span className="text-green-500 font-bold">&#10003;</span> 서명 순서 확인</li>
                    </ul>
                </div>
                <p className="mt-2 text-gray-600">"서명 요청 발송" 버튼을 누르면 첫 번째 서명자에게 <strong>카카오 알림톡과 이메일</strong>이 발송되고, 계약 상태가 <Badge color="blue">진행중</Badge>으로 변경됩니다.</p>
                <TipBox type="tip">전화번호가 등록된 서명자에게는 카카오 알림톡이 우선 발송됩니다. 알림톡 발송 실패 시 자동으로 이메일이 발송됩니다.</TipBox>
                <TipBox type="warning">발송 후에는 계약 내용, 서명 위치, 서명 순서를 변경할 수 없습니다. 수정이 필요하면 취소 후 새로 생성해야 합니다.</TipBox>
            </StepCard>

            <StepCard step="4" title="계약 관리" color="blue">
                <p>대시보드에서 진행 중인 계약을 관리합니다.</p>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-3 mt-2">
                    <div className="bg-gray-50 rounded-lg p-3">
                        <p className="font-medium text-sm text-gray-800 mb-1">리마인더 발송</p>
                        <p className="text-xs text-gray-600">상대방이 서명하지 않으면 리마인더 알림톡/이메일을 보낼 수 있습니다. 여러 번 발송 가능합니다.</p>
                    </div>
                    <div className="bg-gray-50 rounded-lg p-3">
                        <p className="font-medium text-sm text-gray-800 mb-1">계약 취소</p>
                        <p className="text-xs text-gray-600">초안 또는 진행중 상태에서만 취소 가능합니다. 완료된 계약은 취소할 수 없습니다.</p>
                    </div>
                    <div className="bg-gray-50 rounded-lg p-3">
                        <p className="font-medium text-sm text-gray-800 mb-1">PDF 다운로드</p>
                        <p className="text-xs text-gray-600">계약 완료 후 서명이 포함된 최종 PDF를 다운로드할 수 있습니다.</p>
                    </div>
                    <div className="bg-gray-50 rounded-lg p-3">
                        <p className="font-medium text-sm text-gray-800 mb-1">무결성 검증</p>
                        <p className="text-xs text-gray-600">원본 문서의 위변조 여부를 SHA-256 해시로 확인합니다.</p>
                    </div>
                </div>
            </StepCard>
        </div>

        {/* 상태 설명 */}
        <SubTitle>계약 상태별 의미</SubTitle>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
            {[
                { label: '초안', badge: 'gray', desc: '작성 중, 아직 발송 안 함' },
                { label: '진행중', badge: 'blue', desc: '서명 요청 발송됨' },
                { label: '부분 서명', badge: 'yellow', desc: '한쪽만 서명 완료' },
                { label: '완료', badge: 'green', desc: '양쪽 서명 완료!' },
                { label: '만료', badge: 'red', desc: '서명 기한 초과' },
                { label: '취소', badge: 'gray', desc: '생성자가 취소함' },
                { label: '거절', badge: 'red', desc: '서명자가 거절함' },
            ].map((s, i) => (
                <div key={i} className="border border-gray-200 rounded-lg p-3">
                    <Badge color={s.badge}>{s.label}</Badge>
                    <p className="text-xs text-gray-600 mt-1">{s.desc}</p>
                </div>
            ))}
        </div>

        {/* ===== 서명 상대방(을) 가이드 ===== */}
        <div className="mt-10 mb-4">
            <h3 className="text-base font-bold text-green-700 flex items-center gap-2">
                <span className="w-6 h-6 bg-green-100 rounded-full flex items-center justify-center text-green-700 text-xs font-bold">을</span>
                서명 상대방 가이드 (을)
            </h3>
            <p className="text-sm text-gray-500 mt-1">카카오 알림톡 또는 이메일로 서명 요청을 받은 분을 위한 안내입니다. SAM 계정이 없어도 됩니다.</p>
        </div>

        <div className="space-y-4">
            <StepCard step="1" title="서명 요청 알림 확인" color="green">
                <p>카카오 알림톡 또는 이메일로 서명 요청이 도착합니다.</p>

                {/* 카카오 알림톡 예시 */}
                <p className="text-xs font-semibold text-yellow-700 mt-3 mb-1">카카오 알림톡으로 받은 경우:</p>
                <div className="bg-yellow-50 border border-yellow-300 rounded-lg p-4 mt-1 text-gray-700">
                    <div className="flex items-center gap-2 mb-2">
                        <span className="text-lg">&#128172;</span>
                        <span className="text-xs font-bold text-yellow-800">카카오톡 알림톡</span>
                    </div>
                    <p className="text-sm font-medium mb-1">[SAM E-Sign] 서명 요청</p>
                    <p className="text-sm">안녕하세요, 박을동님.</p>
                    <p className="text-sm mb-1">김갑순님이 계약 서명을 요청했습니다.</p>
                    <p className="text-xs text-gray-500">계약: 소프트웨어 개발 용역 계약서</p>
                    <p className="text-xs text-gray-500 mb-2">서명 기한: 2026-02-19</p>
                    <div className="bg-yellow-500 text-white text-sm text-center py-2 px-4 rounded-lg inline-block">계약서 확인 및 서명하기</div>
                </div>

                {/* 이메일 예시 */}
                <p className="text-xs font-semibold text-blue-700 mt-4 mb-1">이메일로 받은 경우:</p>
                <div className="bg-white border border-gray-300 rounded-lg p-4 mt-1 text-gray-700">
                    <p className="text-xs text-gray-400 mb-1">제목</p>
                    <p className="font-medium text-sm mb-3">[SAM E-Sign] 서명 요청 - 소프트웨어 개발 용역 계약서</p>
                    <p className="text-sm">안녕하세요, 박을동님.</p>
                    <p className="text-sm mb-2">김갑순님이 계약 서명을 요청했습니다.</p>
                    <p className="text-xs text-gray-500">계약 제목: 소프트웨어 개발 용역 계약서</p>
                    <p className="text-xs text-gray-500 mb-3">서명 기한: 2026-02-19</p>
                    <div className="bg-blue-600 text-white text-sm text-center py-2 px-4 rounded-lg inline-block">계약서 확인 및 서명하기</div>
                </div>
                <p className="mt-2 text-gray-600">버튼을 클릭하면 서명 절차가 시작됩니다.</p>
                <TipBox type="tip">카카오 알림톡은 카카오톡 앱에서 바로 확인할 수 있어 이메일보다 빠르게 서명을 진행할 수 있습니다. 이메일이 보이지 않으면 <strong>스팸/정크 메일함</strong>을 확인해 보세요.</TipBox>
            </StepCard>

            <StepCard step="2" title="본인인증 (OTP)" color="green">
                {/* OTP 개념 설명 */}
                <div className="bg-green-50 border border-green-200 rounded-xl p-4 mb-4">
                    <p className="font-bold text-green-800 mb-2">OTP가 뭔가요?</p>
                    <p className="text-green-700 mb-3">
                        OTP는 <strong>"일회용 비밀번호"</strong> 입니다. (One-Time Password의 약자)<br/>
                        매번 새롭게 만들어지는 숫자 코드로, <strong>딱 한 번만</strong> 사용할 수 있습니다.<br/>
                        <strong>카카오 알림톡</strong> 또는 <strong>이메일</strong>로 받을 수 있습니다.
                    </p>
                    <div className="bg-white rounded-lg p-3 border border-green-100">
                        <p className="text-sm font-semibold text-gray-800 mb-2">쉽게 비유하면...</p>
                        <p className="text-sm text-gray-600 mb-2">
                            택배를 받을 때 무인 보관함에서 <strong>"인증번호 4자리"</strong>를 입력해야 열리죠?<br/>
                            그 번호는 내 택배에만 쓸 수 있고, 한 번 쓰면 다시 못 씁니다.
                        </p>
                        <p className="text-sm text-gray-600">
                            OTP도 마찬가지입니다. 이메일로 받은 <strong>6자리 숫자</strong>를 입력하면<br/>
                            "이 사람이 진짜 본인이 맞구나!" 하고 확인해 주는 거예요.
                        </p>
                    </div>
                </div>

                {/* 왜 필요한지 */}
                <div className="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-4">
                    <p className="font-bold text-blue-800 mb-2">왜 OTP가 필요한가요?</p>
                    <p className="text-sm text-blue-700">
                        계약서에 서명하는 건 아주 중요한 일이에요.<br/>
                        만약 누군가 내 서명 링크를 몰래 가져가서 대신 서명하면 큰일이겠죠?
                    </p>
                    <div className="flex items-start gap-3 mt-3 bg-white rounded-lg p-3 border border-blue-100">
                        <span className="text-2xl">&#128274;</span>
                        <div className="text-sm text-gray-700">
                            <p className="font-medium">OTP는 "내 카카오톡/이메일을 볼 수 있는 사람 = 진짜 본인"이라는 원리를 이용합니다.</p>
                            <p className="mt-1 text-gray-500">서명 링크를 누른 사람이 정말 계약 당사자인지 카카오 알림톡 또는 이메일로 한 번 더 확인하는 과정입니다.</p>
                        </div>
                    </div>
                </div>

                {/* 실제 진행 절차 */}
                <p className="font-semibold text-gray-800 mb-2">실제 진행 방법 (4단계)</p>
                <div className="space-y-3">
                    <div className="flex items-start gap-3 bg-gray-50 rounded-lg p-3">
                        <span className="flex-shrink-0 w-7 h-7 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold">1</span>
                        <div>
                            <p className="font-medium text-gray-800">"인증코드 발송" 버튼을 누릅니다</p>
                            <p className="text-xs text-gray-500 mt-0.5">전화번호가 등록된 경우 카카오 알림톡으로, 그렇지 않으면 이메일로 발송됩니다</p>
                        </div>
                    </div>
                    <div className="flex items-start gap-3 bg-gray-50 rounded-lg p-3">
                        <span className="flex-shrink-0 w-7 h-7 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold">2</span>
                        <div>
                            <p className="font-medium text-gray-800">카카오톡 또는 이메일함을 확인합니다</p>
                            <p className="text-xs text-gray-500 mt-0.5">몇 초 안에 인증코드가 도착합니다:</p>
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-2 mt-2">
                                <div className="bg-yellow-50 border border-yellow-200 rounded p-2 text-xs">
                                    <p className="text-yellow-700 font-semibold mb-1">&#128172; 카카오 알림톡</p>
                                    <p className="text-gray-600">[SAM E-Sign] 인증코드</p>
                                    <p className="text-gray-700 mt-1">인증코드: <strong className="text-lg text-blue-600 font-mono">4 8 2 9 1 7</strong></p>
                                </div>
                                <div className="bg-white border border-gray-200 rounded p-2 text-xs">
                                    <p className="text-blue-700 font-semibold mb-1">&#9993; 이메일</p>
                                    <p className="text-gray-400">제목: [SAM E-Sign] 인증코드 안내</p>
                                    <p className="text-gray-700 mt-1">인증코드: <strong className="text-lg text-blue-600 font-mono">4 8 2 9 1 7</strong></p>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="flex items-start gap-3 bg-gray-50 rounded-lg p-3">
                        <span className="flex-shrink-0 w-7 h-7 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold">3</span>
                        <div>
                            <p className="font-medium text-gray-800">받은 6자리 숫자를 입력합니다</p>
                            <p className="text-xs text-gray-500 mt-0.5">위 예시라면 4, 8, 2, 9, 1, 7 을 차례로 입력합니다</p>
                            <div className="flex gap-1 mt-1">
                                {['4','8','2','9','1','7'].map((n, i) => (
                                    <span key={i} className="w-8 h-8 bg-white border-2 border-blue-300 rounded flex items-center justify-center text-sm font-bold text-blue-700">{n}</span>
                                ))}
                            </div>
                        </div>
                    </div>
                    <div className="flex items-start gap-3 bg-gray-50 rounded-lg p-3">
                        <span className="flex-shrink-0 w-7 h-7 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold">4</span>
                        <div>
                            <p className="font-medium text-gray-800">"확인" 버튼을 누릅니다</p>
                            <p className="text-xs text-gray-500 mt-0.5">코드가 맞으면 자동으로 계약서 확인 화면으로 넘어갑니다</p>
                        </div>
                    </div>
                </div>

                {/* 주의사항 */}
                <div className="mt-4 bg-yellow-50 border border-yellow-200 rounded-xl p-4">
                    <p className="font-bold text-yellow-800 mb-2">주의하세요!</p>
                    <div className="space-y-2 text-sm text-yellow-700">
                        <div className="flex items-start gap-2">
                            <span className="font-bold text-yellow-600">&#9200;</span>
                            <p><strong>5분 안에 입력하세요</strong> - 코드는 발송 후 5분이 지나면 만료됩니다. 만료되면 "재발송"을 눌러 새 코드를 받으세요.</p>
                        </div>
                        <div className="flex items-start gap-2">
                            <span className="font-bold text-yellow-600">&#9888;</span>
                            <p><strong>5번까지만 입력할 수 있어요</strong> - 틀린 코드를 5번 넣으면 보안을 위해 차단됩니다. 이 경우 계약을 보낸 분에게 연락하세요.</p>
                        </div>
                        <div className="flex items-start gap-2">
                            <span className="font-bold text-yellow-600">&#128233;</span>
                            <p><strong>알림톡/이메일이 안 오나요?</strong> - 카카오톡 알림 설정을 확인하거나 이메일 스팸/정크 메일함을 확인해 보세요. 그래도 없으면 1분 후 "재발송" 버튼을 누르세요.</p>
                        </div>
                    </div>
                </div>

                <TipBox type="success">OTP 인증은 한 마디로 "내가 진짜 나"임을 증명하는 단계입니다. 카카오 알림톡 또는 이메일로 받은 숫자 6개만 입력하면 끝!</TipBox>
            </StepCard>

            <StepCard step="3" title="계약서 확인" color="green">
                <p>인증이 완료되면 계약서 PDF를 확인하는 화면으로 이동합니다.</p>
                <ul className="mt-2 space-y-1">
                    <li>- 계약서 전체 내용을 <strong>꼼꼼히 확인</strong>하세요</li>
                    <li>- 여러 페이지인 경우 <strong>모든 페이지</strong>를 확인하세요</li>
                    <li>- 서명이 필요한 위치에 <strong>빨간색 표시</strong>가 되어 있습니다</li>
                </ul>
                <p className="mt-2 text-gray-600">확인 후 <strong>"서명하기"</strong> 또는 <strong>"거절하기"</strong>를 선택합니다.</p>
            </StepCard>

            <StepCard step="4" title="서명 수행" color="green">
                <p>"서명하기"를 누르면 서명 입력 화면이 나타납니다.</p>
                <div className="bg-gray-50 rounded-lg p-3 mt-2">
                    <ol className="list-decimal list-inside space-y-2 text-gray-700">
                        <li>서명 캔버스에 <strong>마우스 드래그 또는 터치</strong>로 서명을 그립니다</li>
                        <li>마음에 들지 않으면 <strong>"다시 쓰기"</strong>를 눌러 초기화합니다</li>
                        <li>아래 <strong>2개의 동의 체크박스</strong>를 모두 체크합니다
                            <ul className="ml-4 mt-1 text-xs text-gray-500 space-y-0.5">
                                <li>&#9745; "본 계약서의 내용을 확인하였으며 서명에 동의합니다"</li>
                                <li>&#9745; "전자서명의 법적 효력에 동의합니다"</li>
                            </ul>
                        </li>
                        <li><strong>"최종 제출"</strong> 버튼을 클릭합니다</li>
                    </ol>
                </div>
                <div className="grid grid-cols-2 gap-3 mt-3">
                    <div className="bg-gray-50 rounded p-2 text-center">
                        <p className="text-xs font-medium text-gray-700">PC에서</p>
                        <p className="text-xs text-gray-500">마우스를 클릭+드래그</p>
                    </div>
                    <div className="bg-gray-50 rounded p-2 text-center">
                        <p className="text-xs font-medium text-gray-700">모바일/태블릿에서</p>
                        <p className="text-xs text-gray-500">손가락 또는 펜으로 터치</p>
                    </div>
                </div>
                <TipBox type="success">서명이 제출되면 완료 화면이 표시됩니다. 상대방 서명이 완료되면 계약이 최종 확정됩니다.</TipBox>
            </StepCard>
        </div>

        {/* 서명 거절 */}
        <SubTitle>서명을 거절하려면?</SubTitle>
        <InfoCard title="서명 거절 절차" color="red">
            <ol className="list-decimal list-inside space-y-1">
                <li>계약서 확인 화면에서 <strong>"거절하기"</strong> 버튼을 클릭합니다</li>
                <li>거절 사유를 입력합니다 (필수, 최대 1,000자)</li>
                <li><strong>"거절 확인"</strong>을 클릭합니다</li>
            </ol>
            <p className="mt-2 text-xs text-red-600">거절하면 계약이 "거절" 상태로 변경되며, 생성자에게 알림톡/이메일로 사유가 전달됩니다. 거절 후에는 취소할 수 없으니 신중하게 결정하세요.</p>
        </InfoCard>

        {/* FAQ */}
        <div className="mt-10">
            <SectionTitle>자주 묻는 질문 (FAQ)</SectionTitle>
        </div>

        <div className="space-y-2">
            <FaqItem q="PDF 외 다른 형식의 파일을 업로드할 수 있나요?">
                <p>현재 v1.0에서는 PDF 형식만 지원합니다. Word, 한글 등의 문서는 PDF로 변환한 후 업로드해 주세요.</p>
            </FaqItem>
            <FaqItem q="PDF 파일 크기 제한은 얼마인가요?">
                <p>최대 <strong>20MB</strong>까지 업로드할 수 있습니다.</p>
            </FaqItem>
            <FaqItem q="업로드한 PDF를 수정할 수 있나요?">
                <p>아니요. 문서 무결성 보장을 위해 업로드 후 PDF 내용은 변경할 수 없습니다. 수정이 필요하면 <strong>계약을 취소하고 수정된 PDF로 새 계약을 생성</strong>하세요.</p>
            </FaqItem>
            <FaqItem q="서명 기한을 연장할 수 있나요?">
                <p>현재 v1.0에서는 기한 연장 기능을 지원하지 않습니다. 기한이 만료되면 새 계약을 생성해야 합니다.</p>
            </FaqItem>
            <FaqItem q="상대방이 서명 요청을 받지 못했다고 합니다.">
                <ul className="list-disc list-inside space-y-1">
                    <li><strong>카카오 알림톡</strong>인 경우: 카카오톡 채널 차단 여부, 전화번호 정확성을 확인하세요</li>
                    <li><strong>이메일</strong>인 경우: <strong>스팸/정크 메일함</strong>을 확인하도록 안내하세요</li>
                    <li>이메일 주소/전화번호가 정확한지 확인하세요</li>
                    <li><strong>리마인더 발송</strong> 기능을 사용하여 알림톡/이메일을 재발송하세요</li>
                </ul>
            </FaqItem>
            <FaqItem q="인증코드(OTP)를 5회 이상 틀렸습니다. 어떻게 하나요?">
                <p className="mb-2">보안을 위해 5번 틀리면 더 이상 코드를 입력할 수 없게 됩니다.</p>
                <p><strong>해결 방법:</strong> 계약을 보낸 분에게 연락하여 "계약을 취소하고 다시 보내달라"고 요청하세요. 새 링크가 이메일로 오면 처음부터 다시 시도하면 됩니다.</p>
            </FaqItem>
            <FaqItem q="OTP 인증코드가 안 와요.">
                <p className="font-semibold text-gray-700 mb-2">카카오 알림톡으로 안 오는 경우:</p>
                <ul className="list-disc list-inside space-y-1 mb-3">
                    <li>카카오톡 앱에서 <strong>알림 설정</strong>이 켜져 있는지 확인하세요.</li>
                    <li>SAM E-Sign <strong>카카오 채널을 차단</strong>하지 않았는지 확인하세요.</li>
                    <li>전화번호가 정확하게 등록되었는지 계약 보낸 분에게 확인 요청하세요.</li>
                </ul>
                <p className="font-semibold text-gray-700 mb-2">이메일로 안 오는 경우:</p>
                <ul className="list-disc list-inside space-y-1">
                    <li><strong>스팸/정크 메일함</strong>을 먼저 확인해 보세요 (가장 흔한 원인!)</li>
                    <li>1~2분 정도 기다려 보세요. 서버 상황에 따라 약간 지연될 수 있습니다.</li>
                    <li>그래도 안 오면 화면의 <strong>"재발송"</strong> 버튼을 눌러 새 코드를 받으세요.</li>
                    <li>계속 안 된다면 계약을 보낸 분에게 내 이메일/전화번호가 맞는지 확인 요청하세요.</li>
                </ul>
            </FaqItem>
            <FaqItem q="모바일에서도 서명할 수 있나요?">
                <p>네! 모바일 브라우저(Chrome, Safari 등)에서 서명할 수 있습니다. 손가락으로 터치하여 서명하세요.</p>
            </FaqItem>
            <FaqItem q="서명을 잘못 했습니다. 다시 할 수 있나요?">
                <p>서명 <strong>제출 전</strong>에는 "다시 쓰기" 버튼으로 서명을 초기화할 수 있습니다. 이미 제출한 서명은 변경할 수 없습니다.</p>
            </FaqItem>
            <FaqItem q="서명을 거절하면 어떻게 되나요?">
                <p>계약이 "거절" 상태로 변경되며, 생성자에게 알림톡/이메일로 거절 알림과 사유가 전달됩니다. 거절된 계약은 복구할 수 없으므로, 협의 후 새 계약을 생성해야 합니다.</p>
            </FaqItem>
            <FaqItem q="완료된 계약서를 취소할 수 있나요?">
                <p>양쪽 서명이 완료된 계약은 취소할 수 없습니다. 법적으로 유효한 전자서명이 완료된 상태이므로, 필요한 경우 별도의 <strong>해지 계약</strong>을 체결해야 합니다.</p>
            </FaqItem>
            <FaqItem q="완료 PDF는 언제까지 다운로드할 수 있나요?">
                <p>완료된 PDF는 시스템에 보관되며, 로그인 후 언제든지 다운로드할 수 있습니다. 관련 법규에 따라 <strong>최소 5년간</strong> 보관됩니다.</p>
            </FaqItem>
            <FaqItem q="전자서명의 법적 효력은 어떻게 되나요?">
                <p className="mb-2">SAM E-Sign의 전자서명은 한국 전자서명법 제2조에 따른 전자서명 요건을 충족합니다:</p>
                <ul className="list-disc list-inside space-y-1">
                    <li><strong>서명자 확인</strong> → 이메일 OTP 본인인증</li>
                    <li><strong>서명 의사 확인</strong> → 동의 체크박스 2개</li>
                    <li><strong>문서 변경 감지</strong> → SHA-256 해시 비교</li>
                    <li><strong>서명 후 불변</strong> → 서명 완료 후 수정 차단</li>
                </ul>
            </FaqItem>
            <FaqItem q="다른 사람이 내 서명 링크를 사용할 수 있나요?">
                <p>서명 링크에 접속하더라도 <strong>등록된 카카오톡 또는 이메일로 OTP 인증</strong>을 통과해야만 서명할 수 있습니다. 카카오톡 및 이메일 계정을 안전하게 관리하고 있다면 걱정하지 않으셔도 됩니다.</p>
            </FaqItem>
        </div>

        {/* ===== 법률 안내 ===== */}
        <div className="mt-10">
            <SectionTitle>법률 안내</SectionTitle>
        </div>

        <div className="bg-gradient-to-r from-indigo-50 to-purple-50 border border-indigo-200 rounded-xl p-5 mb-6">
            <p className="font-bold text-indigo-900 mb-2">SAM E-Sign으로 체결한 계약은 법적으로 유효합니다</p>
            <p className="text-sm text-indigo-700">
                SAM E-Sign의 전자서명은 한국 <strong>전자서명법</strong>과 <strong>전자문서 및 전자거래 기본법</strong>에 근거하여
                종이 계약서의 서명/날인과 <strong>동일한 법적 효력</strong>을 가집니다.
            </p>
        </div>

        {/* 법적 근거 */}
        <SubTitle>1. 법적 근거</SubTitle>

        <div className="space-y-3 mb-4">
            <div className="border border-indigo-200 rounded-lg overflow-hidden">
                <div className="bg-indigo-50 px-4 py-2">
                    <p className="font-semibold text-sm text-indigo-900">전자서명법 제3조 제1항 - 효력 부인 금지</p>
                </div>
                <div className="px-4 py-3">
                    <blockquote className="border-l-4 border-indigo-300 pl-3 text-sm text-gray-700 italic">
                        "전자서명은 전자적 형태라는 이유만으로 서명, 서명날인 또는 기명날인으로서의 효력이 부인되지 아니한다."
                    </blockquote>
                    <p className="text-xs text-gray-500 mt-2">
                        즉, "컴퓨터로 서명했으니까 무효"라고 할 수 없습니다. 전자서명도 종이 서명과 같은 법적 효력이 있습니다.
                    </p>
                </div>
            </div>

            <div className="border border-indigo-200 rounded-lg overflow-hidden">
                <div className="bg-indigo-50 px-4 py-2">
                    <p className="font-semibold text-sm text-indigo-900">전자서명법 제3조 제3항 - 서명과 동일한 효력</p>
                </div>
                <div className="px-4 py-3">
                    <blockquote className="border-l-4 border-indigo-300 pl-3 text-sm text-gray-700 italic">
                        "법령의 규정이나 당사자 간의 약정에 따라 서명, 서명날인 또는 기명날인의 방식으로 전자서명을 선택한 경우
                        그 전자서명은 서명, 서명날인 또는 기명날인의 효력을 가진다."
                    </blockquote>
                    <p className="text-xs text-gray-500 mt-2">
                        양쪽이 전자서명으로 계약하기로 합의하면, 그 서명은 직접 손으로 쓴 서명과 동일한 효력을 가집니다.
                    </p>
                </div>
            </div>

            <div className="border border-indigo-200 rounded-lg overflow-hidden">
                <div className="bg-indigo-50 px-4 py-2">
                    <p className="font-semibold text-sm text-indigo-900">전자문서 및 전자거래 기본법 제4조 - 전자문서의 효력</p>
                </div>
                <div className="px-4 py-3">
                    <blockquote className="border-l-4 border-indigo-300 pl-3 text-sm text-gray-700 italic">
                        "전자문서는 전자적 형태로 되어 있다는 이유만으로 법적 효력이 부인되지 아니한다."
                    </blockquote>
                    <p className="text-xs text-gray-500 mt-2">
                        PDF로 작성된 계약서도 종이 계약서와 동일하게 법적으로 유효한 문서입니다.
                    </p>
                </div>
            </div>

            <div className="border border-indigo-200 rounded-lg overflow-hidden">
                <div className="bg-indigo-50 px-4 py-2">
                    <p className="font-semibold text-sm text-indigo-900">전자문서 및 전자거래 기본법 제5조 - 서면으로서의 효력</p>
                </div>
                <div className="px-4 py-3">
                    <p className="text-sm text-gray-700">전자문서가 다음 3가지 요건을 갖추면 <strong>법률상 "서면"</strong>으로 인정됩니다:</p>
                    <ol className="list-decimal list-inside mt-2 space-y-1 text-sm text-gray-600">
                        <li><strong>열람 가능</strong> - 내용을 화면에서 볼 수 있음</li>
                        <li><strong>재현 가능</strong> - 작성된 그대로의 형태를 다시 볼 수 있음</li>
                        <li><strong>보존 가능</strong> - 안전하게 저장/보관할 수 있음</li>
                    </ol>
                    <TipBox type="success">SAM E-Sign은 PDF 원본 보존, 언제든 열람/다운로드 가능, 해시 기반 무결성 검증으로 이 3가지를 모두 충족합니다.</TipBox>
                </div>
            </div>
        </div>

        {/* 공인전자서명 폐지 안내 */}
        <SubTitle>2. 2020년 전자서명법 개정과 SAM E-Sign</SubTitle>

        <InfoCard title="공인인증서 제도 폐지 (2020년 12월)" color="blue">
            <p className="mb-2">2020년 전자서명법 전면 개정으로 <strong>"공인전자서명"</strong> 제도가 폐지되었습니다.</p>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3 mt-3">
                <div className="bg-white rounded-lg p-3 border border-gray-200">
                    <p className="text-xs font-semibold text-red-600 mb-1">개정 전</p>
                    <ul className="text-xs text-gray-600 space-y-0.5">
                        <li>- 공인인증서 서명만 법적 추정력 인정</li>
                        <li>- 일반 전자서명은 효력 제한</li>
                    </ul>
                </div>
                <div className="bg-white rounded-lg p-3 border border-gray-200">
                    <p className="text-xs font-semibold text-green-600 mb-1">개정 후 (현행)</p>
                    <ul className="text-xs text-gray-600 space-y-0.5">
                        <li>- 모든 전자서명에 기본적 법적 효력 인정</li>
                        <li>- 기술 중립성 원칙 적용</li>
                        <li>- 당사자 약정으로 효력 확보</li>
                    </ul>
                </div>
            </div>
            <p className="text-xs text-gray-500 mt-3">
                SAM E-Sign은 개정된 전자서명법에 따라 OTP 본인인증, SHA-256 무결성 검증, 감사 추적 등
                기술적 신뢰성을 갖춘 전자서명 수단을 제공합니다.
            </p>
        </InfoCard>

        {/* SAM E-Sign이 법적 효력을 갖추는 방법 */}
        <SubTitle>3. SAM E-Sign이 법적 요건을 충족하는 방법</SubTitle>

        <p className="text-sm text-gray-600 mb-3">전자서명이 법적 효력을 인정받으려면 4가지 핵심 요건을 충족해야 합니다. SAM E-Sign은 모두 충족합니다.</p>

        <div className="space-y-3">
            <div className="border border-gray-200 rounded-xl overflow-hidden">
                <div className="bg-blue-600 px-4 py-2 flex items-center gap-2">
                    <span className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center text-xs font-bold text-white">1</span>
                    <span className="font-semibold text-white text-sm">서명자 본인 확인</span>
                </div>
                <div className="p-4">
                    <div className="flex items-start gap-3">
                        <div className="flex-1">
                            <p className="text-sm text-gray-700 mb-2"><strong>법적 요구:</strong> 서명한 사람이 정말 본인인지 확인해야 합니다.</p>
                            <p className="text-sm text-gray-700"><strong>SAM E-Sign 구현:</strong></p>
                            <ul className="text-sm text-gray-600 space-y-1 mt-1">
                                <li>- <strong>카카오 알림톡 / 이메일 OTP 인증</strong> (6자리 일회용 코드, 5분 유효, 5회 제한)</li>
                                <li>- 고유 액세스 토큰 (128자리 랜덤 문자열)</li>
                                <li>- 접속 IP 및 브라우저 정보 기록</li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>

            <div className="border border-gray-200 rounded-xl overflow-hidden">
                <div className="bg-green-600 px-4 py-2 flex items-center gap-2">
                    <span className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center text-xs font-bold text-white">2</span>
                    <span className="font-semibold text-white text-sm">서명 의사 확인</span>
                </div>
                <div className="p-4">
                    <p className="text-sm text-gray-700 mb-2"><strong>법적 요구:</strong> 서명자가 자발적으로, 내용을 이해하고 서명했음을 확인해야 합니다.</p>
                    <p className="text-sm text-gray-700"><strong>SAM E-Sign 구현:</strong></p>
                    <ul className="text-sm text-gray-600 space-y-1 mt-1">
                        <li>- 계약서 전문 열람 단계 (PDF 확인 필수)</li>
                        <li>- <strong>2개의 명시적 동의 체크박스</strong></li>
                        <li className="ml-4 text-xs text-gray-500">"본 계약서의 내용을 확인하였으며 서명에 동의합니다"</li>
                        <li className="ml-4 text-xs text-gray-500">"전자서명의 법적 효력에 동의합니다"</li>
                        <li>- 직접 서명 캔버스 입력 (터치/마우스)</li>
                        <li>- 거절 옵션 제공 (사유 기재 포함)</li>
                    </ul>
                </div>
            </div>

            <div className="border border-gray-200 rounded-xl overflow-hidden">
                <div className="bg-purple-600 px-4 py-2 flex items-center gap-2">
                    <span className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center text-xs font-bold text-white">3</span>
                    <span className="font-semibold text-white text-sm">문서 무결성 보장 (위변조 방지)</span>
                </div>
                <div className="p-4">
                    <p className="text-sm text-gray-700 mb-2"><strong>법적 요구:</strong> 서명 후 문서가 변경되지 않았음을 증명할 수 있어야 합니다.</p>
                    <p className="text-sm text-gray-700"><strong>SAM E-Sign 구현:</strong></p>
                    <ul className="text-sm text-gray-600 space-y-1 mt-1">
                        <li>- <strong>SHA-256 해시</strong>로 문서의 고유 지문 생성 및 DB 저장</li>
                        <li>- <code className="bg-gray-100 px-1 rounded text-xs">hash_equals()</code> 타이밍 공격 방지 검증</li>
                        <li>- 서명 완료 후 문서 수정 차단</li>
                        <li>- 언제든 "무결성 검증" 기능으로 원본 확인 가능</li>
                    </ul>
                    <TipBox type="tip">해시(Hash)란 파일의 "디지털 지문"입니다. 문서를 단 1글자만 바꿔도 해시값이 완전히 달라지므로, 해시값이 같으면 원본과 100% 동일함을 보장합니다.</TipBox>
                </div>
            </div>

            <div className="border border-gray-200 rounded-xl overflow-hidden">
                <div className="bg-red-600 px-4 py-2 flex items-center gap-2">
                    <span className="w-6 h-6 bg-white/20 rounded-full flex items-center justify-center text-xs font-bold text-white">4</span>
                    <span className="font-semibold text-white text-sm">감사 추적 (Audit Trail)</span>
                </div>
                <div className="p-4">
                    <p className="text-sm text-gray-700 mb-2"><strong>법적 요구:</strong> 계약 과정 전체를 시간순으로 기록하여 추후 분쟁 시 증거로 활용할 수 있어야 합니다.</p>
                    <p className="text-sm text-gray-700"><strong>SAM E-Sign 구현:</strong></p>
                    <ul className="text-sm text-gray-600 space-y-1 mt-1">
                        <li>- 모든 행위를 <strong>삭제 불가능한 로그</strong>로 영구 기록</li>
                        <li>- 각 기록에 <strong>정확한 시각, IP 주소, 브라우저 정보</strong> 포함</li>
                        <li>- 기록 항목: 계약 생성, 서명 요청 발송, 링크 접속, OTP 발송/인증, 문서 열람, 서명 수행, 완료, 다운로드 등</li>
                    </ul>
                    <div className="bg-gray-50 rounded-lg p-3 mt-3 text-xs text-gray-600">
                        <p className="font-medium text-gray-800 mb-1">감사 추적 기록 예시:</p>
                        <div className="font-mono space-y-0.5">
                            <p>2026-02-12 10:00:15 | 계약 생성 | IP: 192.168.1.100</p>
                            <p>2026-02-12 10:05:22 | 서명 요청 발송 | 수신: park@example.com</p>
                            <p>2026-02-12 14:30:08 | 서명 링크 접속 | IP: 211.xxx.xxx.xxx</p>
                            <p>2026-02-12 14:30:45 | OTP 인증 성공 | 시도: 1회</p>
                            <p>2026-02-12 14:32:10 | 전자서명 수행 | Chrome 120, Windows 11</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        {/* 체결 가능/불가능한 계약 */}
        <SubTitle>4. 전자서명으로 체결할 수 있는 계약</SubTitle>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
            <div className="border border-green-200 rounded-xl overflow-hidden">
                <div className="bg-green-50 px-4 py-2">
                    <p className="font-semibold text-sm text-green-800">&#10003; 전자서명 가능</p>
                </div>
                <div className="p-4">
                    <ul className="text-sm text-gray-700 space-y-1.5">
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 물품 공급/납품 계약</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 용역 계약 (개발, 컨설팅 등)</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 비밀유지계약 (NDA)</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 프랜차이즈/대리점 계약</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 근로 계약서</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 라이선스 계약</li>
                        <li className="flex items-start gap-2"><span className="text-green-500 mt-0.5">&#10003;</span> 부동산 매매/임대차 계약 *</li>
                    </ul>
                    <p className="text-xs text-gray-400 mt-2">* 부동산 계약 자체는 가능하나, 등기 시 별도 절차 필요</p>
                </div>
            </div>
            <div className="border border-red-200 rounded-xl overflow-hidden">
                <div className="bg-red-50 px-4 py-2">
                    <p className="font-semibold text-sm text-red-800">&#10007; 전자서명 제한/불가</p>
                </div>
                <div className="p-4">
                    <ul className="text-sm text-gray-700 space-y-1.5">
                        <li className="flex items-start gap-2"><span className="text-red-500 mt-0.5">&#10007;</span> 부동산 등기 신청 서류</li>
                        <li className="flex items-start gap-2"><span className="text-red-500 mt-0.5">&#10007;</span> 공증이 필요한 문서</li>
                        <li className="flex items-start gap-2"><span className="text-red-500 mt-0.5">&#10007;</span> 어음/수표 (유가증권)</li>
                        <li className="flex items-start gap-2"><span className="text-red-500 mt-0.5">&#10007;</span> 공정증서 (강제집행 목적)</li>
                        <li className="flex items-start gap-2"><span className="text-red-500 mt-0.5">&#10007;</span> 법원 제출 소송 서류</li>
                    </ul>
                    <p className="text-xs text-gray-400 mt-2">이러한 문서는 법령에서 별도의 형식/절차를 요구합니다.</p>
                </div>
            </div>
        </div>

        <TipBox type="tip">
            SAM E-Sign은 주로 <strong>물품 공급, 용역, NDA, 납품 계약</strong> 등 일반 상사 계약에 적합합니다.
            대부분의 비즈니스 계약은 전자서명으로 유효하게 체결할 수 있습니다.
        </TipBox>

        {/* 분쟁 발생 시 */}
        <SubTitle>5. 분쟁이 발생하면?</SubTitle>

        <InfoCard title="전자서명 계약서의 증거 능력" color="gray">
            <p className="mb-3">SAM E-Sign으로 체결한 계약서는 분쟁 시 <strong>법적 증거로 활용</strong>할 수 있습니다.</p>
            <div className="space-y-3">
                <div className="bg-white rounded-lg p-3 border border-gray-200">
                    <p className="text-xs font-semibold text-gray-800 mb-1">1. 문서 원본 제출</p>
                    <p className="text-xs text-gray-600">서명이 완료된 PDF 원본을 증거로 제출합니다. SHA-256 해시값으로 위변조 없음을 객관적으로 증명합니다.</p>
                </div>
                <div className="bg-white rounded-lg p-3 border border-gray-200">
                    <p className="text-xs font-semibold text-gray-800 mb-1">2. 감사 추적 기록 제출</p>
                    <p className="text-xs text-gray-600">누가, 언제, 어디서(IP), 어떤 기기로 서명했는지 상세 기록을 제출합니다. 서명 과정 전체를 재구성할 수 있어 <strong>부인 방지(Non-repudiation)</strong> 효과가 있습니다.</p>
                </div>
                <div className="bg-white rounded-lg p-3 border border-gray-200">
                    <p className="text-xs font-semibold text-gray-800 mb-1">3. 본인인증 기록 제출</p>
                    <p className="text-xs text-gray-600">OTP 인증 성공 기록, 접속 IP, 시각 등으로 서명자가 본인임을 입증합니다.</p>
                </div>
            </div>
        </InfoCard>

        <TipBox type="warning">
            <strong>참고:</strong> SAM E-Sign의 전자서명은 종이 계약서의 서명과 동일한 법적 효력을 가지지만,
            <strong>내용증명이나 공정증서</strong>와 동일한 강제집행력을 갖는 것은 아닙니다.
            강제집행이 필요한 경우 별도의 법적 절차를 진행해야 합니다.
        </TipBox>

        {/* 민법상 계약 성립 */}
        <SubTitle>6. 전자서명과 민법상 계약 성립</SubTitle>

        <InfoCard title="계약은 어떻게 성립되나요?" color="blue">
            <p className="mb-2">한국 민법에서 계약은 <strong>"낙성 불요식 계약"</strong> 원칙을 따릅니다.</p>
            <p className="text-xs text-gray-500 mb-3">즉, 별도의 형식을 요구하지 않고, 당사자간의 합의만으로 계약이 성립합니다.</p>
            <div className="bg-white rounded-lg p-3 border border-blue-100">
                <p className="text-sm text-gray-700">따라서 계약서의 형태가 <strong>종이든, PDF든, 전자문서든</strong> 상관없이,
                양쪽이 계약 내용에 합의했다는 사실을 증명할 수 있으면 법적으로 유효합니다.</p>
            </div>
            <div className="mt-3 space-y-2">
                <div className="flex items-center gap-2 text-sm">
                    <Badge color="blue">청약</Badge>
                    <span className="text-gray-600">계약 생성자가 계약서를 작성하고 서명 요청을 보냄</span>
                </div>
                <div className="flex items-center gap-2 text-sm">
                    <Badge color="green">승낙</Badge>
                    <span className="text-gray-600">상대방이 계약서 내용을 확인하고 전자서명을 수행</span>
                </div>
                <div className="flex items-center gap-2 text-sm">
                    <Badge color="purple">성립</Badge>
                    <span className="text-gray-600">양쪽 모두 서명 완료 → 계약 성립!</span>
                </div>
            </div>
        </InfoCard>

        {/* 관련 법령 요약 */}
        <SubTitle>7. 관련 법령 요약</SubTitle>

        <Table
            headers={['법령', '조문', '핵심 내용']}
            rows={[
                ['전자서명법', '제2조 제2호', '전자서명의 정의 (서명자 신원 + 서명 사실 표시)'],
                ['전자서명법', '제3조 제1항', '전자서명의 효력 부인 금지'],
                ['전자서명법', '제3조 제3항', '당사자 약정 시 서명/날인과 동일 효력'],
                ['전자문서법', '제4조 제1항', '전자문서의 법적 효력 인정'],
                ['전자문서법', '제5조', '전자문서의 서면 효력 (열람/재현/보존 요건)'],
                ['민법', '제527~532조', '계약의 성립 (청약과 승낙)'],
            ]}
        />

        <div className="bg-gray-50 border border-gray-200 rounded-lg p-4 mt-4 text-xs text-gray-500">
            <p className="font-semibold text-gray-700 mb-2">참고 자료</p>
            <ul className="space-y-0.5">
                <li>- 전자서명법 (법률 제17354호, 2020.6.9. 전부개정, 2020.12.10. 시행)</li>
                <li>- 전자문서 및 전자거래 기본법 (법률 제17799호)</li>
                <li>- 국가법령정보센터 (law.go.kr)</li>
            </ul>
            <p className="mt-2 text-gray-400">
                * 이 안내는 법률 자문을 대체하지 않습니다. 구체적인 법률 문제는 전문 변호사와 상담하세요.
            </p>
        </div>

        {/* 용어 사전 */}
        <SubTitle>용어 사전</SubTitle>
        <Table
            headers={['용어', '설명']}
            rows={[
                ['갑 (작성자)', '계약서를 작성하고 서명을 요청하는 사람'],
                ['을 (상대방)', '이메일 링크를 통해 서명하는 사람'],
                ['OTP', '일회용 인증 코드 (One-Time Password) - 카카오 알림톡 또는 이메일로 전송'],
                ['카카오 알림톡', '카카오톡 비즈니스 채널을 통한 알림 메시지 서비스'],
                ['전자서명', '종이 서명을 대체하는 디지털 서명'],
                ['감사 추적', '누가, 언제, 무엇을 했는지 기록하는 시스템'],
                ['무결성 검증', '문서가 위변조되지 않았는지 확인하는 절차'],
                ['전자서명법', '전자서명의 법적 효력과 인증 체계를 규정하는 법률 (2020년 전면 개정)'],
                ['전자문서법', '전자문서 및 전자거래 기본법 — 전자문서의 법적 효력을 규정'],
                ['부인 방지', '서명 후 "나는 서명한 적 없다"고 부인하지 못하게 하는 보안 기능'],
                ['본인확인', '카카오 알림톡/이메일 OTP 인증을 통해 서명자가 본인임을 확인하는 절차'],
                ['해시값', '문서 내용을 고유한 암호 코드로 변환한 값 (위변조 탐지용)'],
            ]}
        />
    </div>
);

// ============================================================
// Tab 2: Workflow
// ============================================================
const FlowStep = ({ number, title, desc, color = 'blue' }) => {
    const bg = { blue: 'bg-blue-600', green: 'bg-green-600', yellow: 'bg-yellow-500', red: 'bg-red-600', purple: 'bg-purple-600', indigo: 'bg-indigo-600' };
    return (
        <div className="flex items-start gap-3">
            <div className={`flex-shrink-0 w-8 h-8 ${bg[color] || bg.blue} text-white rounded-full flex items-center justify-center text-sm font-bold`}>{number}</div>
            <div>
                <p className="font-semibold text-gray-900">{title}</p>
                <p className="text-sm text-gray-600">{desc}</p>
            </div>
        </div>
    );
};

const WorkflowTab = () => (
    <div>
        <SectionTitle>계약 생성 ~ 서명 완료 플로우</SectionTitle>

        <SubTitle>전체 프로세스 (5단계)</SubTitle>
        <div className="space-y-4 mb-8">
            <FlowStep number="1" title="계약 생성 (Create)" desc="제목, PDF 업로드, 서명자 정보 입력 → status: draft" color="blue" />
            <div className="ml-4 border-l-2 border-gray-200 h-4"></div>
            <FlowStep number="2" title="서명 필드 배치 (Configure)" desc="PDF 위에 서명/날인/텍스트 필드 드래그&드롭 배치" color="indigo" />
            <div className="ml-4 border-l-2 border-gray-200 h-4"></div>
            <FlowStep number="3" title="서명 요청 발송 (Send)" desc="카카오 알림톡/이메일로 서명 링크 발송 → status: pending" color="purple" />
            <div className="ml-4 border-l-2 border-gray-200 h-4"></div>
            <FlowStep number="4" title="서명 수행 (Sign)" desc="알림톡/이메일 OTP 인증 → 문서 확인 → 서명 제출 → status: partially_signed / completed" color="yellow" />
            <div className="ml-4 border-l-2 border-gray-200 h-4"></div>
            <FlowStep number="5" title="완료 (Complete)" desc="모든 서명자 서명 완료 → status: completed, 완료 알림톡/이메일 발송" color="green" />
        </div>

        <SubTitle>계약 상태 전이</SubTitle>
        <div className="bg-gray-50 rounded-lg p-6 my-4">
            <div className="flex flex-wrap items-center gap-2 justify-center text-sm">
                <Badge color="gray">draft</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="blue">pending</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="yellow">partially_signed</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="green">completed</Badge>
            </div>
            <div className="flex flex-wrap gap-6 justify-center mt-4 text-xs text-gray-500">
                <span>draft → <Badge color="gray">cancelled</Badge></span>
                <span>pending → <Badge color="red">expired</Badge></span>
                <span>partially_signed → <Badge color="red">rejected</Badge></span>
            </div>
        </div>

        <SubTitle>서명자 상태 전이</SubTitle>
        <div className="bg-gray-50 rounded-lg p-6 my-4">
            <div className="flex flex-wrap items-center gap-2 justify-center text-sm">
                <Badge color="gray">waiting</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="blue">notified</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="yellow">authenticated</Badge>
                <span className="text-gray-400">→</span>
                <Badge color="green">signed</Badge>
            </div>
            <div className="flex flex-wrap gap-6 justify-center mt-4 text-xs text-gray-500">
                <span>notified → <Badge color="red">rejected</Badge></span>
                <span>authenticated → <Badge color="red">rejected</Badge></span>
            </div>
        </div>

        <SubTitle>서명 순서 옵션</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <InfoCard title="counterpart_first (기본)" color="blue">
                <p>상대방이 먼저 서명 → 작성자가 나중에 서명</p>
            </InfoCard>
            <InfoCard title="creator_first" color="green">
                <p>작성자가 먼저 서명 → 상대방이 나중에 서명</p>
            </InfoCard>
        </div>
    </div>
);

// ============================================================
// Tab 3: Architecture
// ============================================================
const ArchitectureTab = () => (
    <div>
        <SectionTitle>시스템 아키텍처</SectionTitle>

        <SubTitle>DB 스키마 (4개 테이블)</SubTitle>
        <Table
            headers={['테이블', '주요 필드', '용도']}
            rows={[
                ['esign_contracts', 'id, contract_code, status, title, original_file_path, original_file_hash, sign_order, expires_at', '계약 마스터'],
                ['esign_signers', 'id, contract_id, role, name, email, phone, access_token, otp_code, otp_expires_at, otp_attempts, signature_image_path, sign_session_token', '서명자 정보 & 인증'],
                ['esign_sign_fields', 'id, contract_id, signer_id, page_number, position_x, position_y, width, height, field_type', '서명 위치 좌표'],
                ['esign_audit_logs', 'id, contract_id, signer_id, action, ip_address, user_agent, metadata', '감사 추적 (삭제 불가)'],
            ]}
        />

        <SubTitle>서비스 레이어</SubTitle>
        <Table
            headers={['Service', '주요 메서드', '역할']}
            rows={[
                ['EsignContractService', 'list, stats, create, show, cancel, send, remind, configureFields', '계약 CRUD + 비즈니스 로직'],
                ['EsignSignService', 'getByToken, sendOtp, verifyOtp, submitSignature, reject', '서명 프로세스 처리'],
                ['EsignPdfService', 'generateHash, verifyIntegrity, composeSigned*, addAuditPage*', 'PDF 무결성 + 합성 (* stub)'],
                ['EsignAuditService', 'log, logPublic, getContractLogs', '감사 로그 기록/조회'],
                ['KakaoAlimtalkService', 'sendSignRequest, sendOtp, sendCompletion, sendReminder', '카카오 알림톡 발송 (예정)'],
            ]}
        />

        <SubTitle>멀티테넌트 구조</SubTitle>
        <InfoCard title="tenant_id 기반 데이터 격리" color="blue">
            <ul className="space-y-1">
                <li>모든 esign_ 테이블에 <code className="bg-blue-100 px-1 rounded">tenant_id</code> 컬럼 포함</li>
                <li><code className="bg-blue-100 px-1 rounded">BelongsToTenant</code> trait 으로 글로벌 스코프 적용</li>
                <li>공개 서명 API에서는 <code className="bg-blue-100 px-1 rounded">withoutGlobalScopes()</code> 사용</li>
            </ul>
        </InfoCard>

        <SubTitle>컨트롤러 구조</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <InfoCard title="API (sam-api)" color="gray">
                <ul className="space-y-1">
                    <li><strong>EsignContractController</strong> - 계약 관리 10 엔드포인트</li>
                    <li><strong>EsignSignController</strong> - 서명 프로세스 6 엔드포인트</li>
                </ul>
            </InfoCard>
            <InfoCard title="MNG (sam-mng)" color="gray">
                <ul className="space-y-1">
                    <li><strong>EsignController</strong> - 인증 필요 화면 5개</li>
                    <li><strong>EsignPublicController</strong> - 공개 서명 화면 3개</li>
                </ul>
            </InfoCard>
        </div>

        <SubTitle>파일 저장 구조</SubTitle>
        <CodeBlock>{`storage/app/esign/
├── contracts/
│   └── {contract_id}/
│       ├── original.pdf          # 원본 PDF
│       └── signed.pdf            # 서명 완료 PDF (v1.1)
└── signatures/
    └── {signer_id}/
        └── signature.png         # 서명 이미지`}</CodeBlock>
    </div>
);

// ============================================================
// Tab 4: API Specification
// ============================================================
const ApiTab = () => (
    <div>
        <SectionTitle>API 명세 (총 16 엔드포인트)</SectionTitle>

        <SubTitle>계약 관리 API (인증 필요 - 10개)</SubTitle>
        <Table
            headers={['Method', 'Path', '설명']}
            rows={[
                [<Badge color="green">GET</Badge>, '/esign/contracts', '계약 목록 (페이지네이션, 필터)'],
                [<Badge color="green">GET</Badge>, '/esign/contracts/stats', '상태별 통계'],
                [<Badge color="green">GET</Badge>, '/esign/contracts/{id}', '계약 상세'],
                [<Badge color="blue">POST</Badge>, '/esign/contracts', '계약 생성 (multipart/form-data)'],
                [<Badge color="blue">POST</Badge>, '/esign/contracts/{id}/fields', '서명 필드 설정'],
                [<Badge color="blue">POST</Badge>, '/esign/contracts/{id}/send', '서명 요청 발송'],
                [<Badge color="blue">POST</Badge>, '/esign/contracts/{id}/remind', '리마인드 발송'],
                [<Badge color="blue">POST</Badge>, '/esign/contracts/{id}/cancel', '계약 취소'],
                [<Badge color="green">GET</Badge>, '/esign/contracts/{id}/download', 'PDF 다운로드'],
                [<Badge color="green">GET</Badge>, '/esign/contracts/{id}/verify', '무결성 검증'],
            ]}
        />

        <SubTitle>서명 프로세스 API (토큰 기반 - 6개)</SubTitle>
        <Table
            headers={['Method', 'Path', '설명']}
            rows={[
                [<Badge color="green">GET</Badge>, '/api/esign/sign/{token}', '계약 정보 조회'],
                [<Badge color="blue">POST</Badge>, '/api/esign/sign/{token}/otp/send', 'OTP 발송'],
                [<Badge color="blue">POST</Badge>, '/api/esign/sign/{token}/otp/verify', 'OTP 검증'],
                [<Badge color="green">GET</Badge>, '/api/esign/sign/{token}/document', 'PDF 문서 조회'],
                [<Badge color="blue">POST</Badge>, '/api/esign/sign/{token}/submit', '서명 제출'],
                [<Badge color="blue">POST</Badge>, '/api/esign/sign/{token}/reject', '서명 거절'],
            ]}
        />

        <SubTitle>요청/응답 예시</SubTitle>

        <p className="text-sm font-medium text-gray-700 mb-2">계약 생성 (POST /esign/contracts)</p>
        <CodeBlock title="Response 201">{`{
  "success": true,
  "message": "계약이 생성되었습니다",
  "data": {
    "id": 1,
    "contract_code": "ES-20260212-A1B2C3",
    "status": "draft",
    "title": "2026년 블라인드 납품 계약서",
    "original_file_hash": "e3b0c44298fc1c14...",
    "signers": [
      { "id": 1, "role": "creator", "name": "김담당", "status": "waiting" },
      { "id": 2, "role": "counterpart", "name": "이대표", "status": "waiting" }
    ]
  }
}`}</CodeBlock>

        <p className="text-sm font-medium text-gray-700 mb-2 mt-4">OTP 검증 (POST /api/esign/sign/{'{token}'}/otp/verify)</p>
        <CodeBlock title="Response 200">{`{
  "success": true,
  "message": "OTP 인증이 완료되었습니다",
  "data": {
    "sign_session_token": "a3f8b2c1d4e5f6...",
    "signer": { "id": 2, "status": "authenticated" }
  }
}`}</CodeBlock>

        <SubTitle>Enum 값</SubTitle>
        <Table
            headers={['카테고리', '값']}
            rows={[
                ['계약 상태', 'draft, pending, partially_signed, completed, expired, cancelled, rejected'],
                ['서명 순서', 'counterpart_first, creator_first'],
                ['서명자 역할', 'creator, counterpart'],
                ['서명자 상태', 'waiting, notified, authenticated, signed, rejected'],
                ['필드 타입', 'signature, stamp, text, date, checkbox'],
            ]}
        />
    </div>
);

// ============================================================
// Tab 5: Security
// ============================================================
const SecurityTab = () => (
    <div>
        <SectionTitle>보안 아키텍처</SectionTitle>

        <SubTitle>OTP 인증</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
            <InfoCard title="OTP 스펙" color="yellow">
                <ul className="space-y-1">
                    <li>6자리 숫자 코드</li>
                    <li>유효 시간: <strong>5분</strong></li>
                    <li>최대 시도: <strong>5회</strong></li>
                    <li>저장: bcrypt 해시 (v1.1 예정, 현재 평문)</li>
                </ul>
            </InfoCard>
            <InfoCard title="인증 프로세스" color="blue">
                <ol className="space-y-1 list-decimal list-inside">
                    <li>서명자에게 카카오 알림톡(우선) 또는 이메일로 OTP 발송</li>
                    <li>서명자가 6자리 코드 입력</li>
                    <li>검증 성공 → sign_session_token 발급</li>
                    <li>이후 요청에 세션 토큰 사용</li>
                </ol>
            </InfoCard>
        </div>

        <SubTitle>토큰 보안</SubTitle>
        <Table
            headers={['토큰', '용도', '길이', '만료']}
            rows={[
                ['access_token', '서명 링크', '128자', '계약 만료일까지'],
                ['sign_session_token', 'OTP 인증 후 세션', '64자', '별도 만료 없음'],
            ]}
        />

        <SubTitle>문서 무결성</SubTitle>
        <InfoCard title="SHA-256 해시 검증" color="green">
            <ul className="space-y-1">
                <li>PDF 업로드 시 SHA-256 해시 생성 및 DB 저장</li>
                <li><code className="bg-green-100 px-1 rounded">hash_equals()</code> 사용 (타이밍 공격 방지)</li>
                <li>서명 완료 PDF 별도 해시 생성</li>
                <li>다운로드 시 무결성 검증 가능</li>
            </ul>
        </InfoCard>

        <SubTitle>감사 로그 (Audit Trail)</SubTitle>
        <InfoCard title="삭제 불가 - 법적 증적" color="red">
            <p className="mb-2">모든 주요 액션이 자동 기록됩니다:</p>
            <div className="flex flex-wrap gap-1">
                {['created','sent','viewed','otp_sent','authenticated','signed','rejected','completed','cancelled','reminded','downloaded'].map(a => (
                    <Badge key={a} color="gray">{a}</Badge>
                ))}
            </div>
            <p className="mt-2 text-xs text-gray-500">각 로그에 IP, User-Agent, 메타데이터 포함</p>
        </InfoCard>

        <SubTitle>법적 준거</SubTitle>
        <Table
            headers={['항목', '구현']}
            rows={[
                ['전자서명법 제2조', '전자 서명 + 본인 확인 (카카오 알림톡/이메일 OTP)'],
                ['본인 확인', '카카오 알림톡/이메일 OTP 6자리, 5분, 5회 제한'],
                ['동의 확인', '체크박스 2개 (문서 확인 + 서명 동의)'],
                ['위변조 방지', 'SHA-256 해시 + 무결성 검증 API'],
                ['서명 후 불변', '상태 변경 불가, 감사 로그 영구 보존'],
            ]}
        />
    </div>
);

// ============================================================
// Tab 6: Screens
// ============================================================
const ScreensTab = () => (
    <div>
        <SectionTitle>화면 설계 (8개 화면)</SectionTitle>

        <SubTitle>인증 필요 화면 (5개)</SubTitle>
        <div className="space-y-4 mb-6">
            <InfoCard title="1. 대시보드 (/esign)" color="blue">
                <ul className="space-y-1">
                    <li>상태별 통계 카드 (전체, 진행중, 완료, 만료)</li>
                    <li>계약 목록 테이블 (페이지네이션, 기본 20건)</li>
                    <li>필터: 상태, 검색어, 기간</li>
                </ul>
            </InfoCard>
            <InfoCard title="2. 계약 생성 (/esign/create)" color="blue">
                <ul className="space-y-1">
                    <li>제목 입력 (필수, 최대 200자)</li>
                    <li>PDF 업로드 (최대 20MB)</li>
                    <li>서명 순서 선택 (상대방 우선 / 작성자 우선)</li>
                    <li>작성자 & 상대방 정보 (이름, 이메일, 전화번호)</li>
                </ul>
            </InfoCard>
            <InfoCard title="3. 계약 상세 (/esign/{id})" color="blue">
                <ul className="space-y-1">
                    <li>기본 정보 표시 (제목, 코드, 상태, 날짜)</li>
                    <li>서명자별 상태 카드</li>
                    <li>감사 로그 타임라인</li>
                    <li>액션 버튼: 발송, 리마인드, 취소, 다운로드, 무결성 검증</li>
                </ul>
            </InfoCard>
            <InfoCard title="4. 서명 필드 배치 (/esign/{id}/fields)" color="blue">
                <ul className="space-y-1">
                    <li>PDF.js로 문서 렌더링</li>
                    <li>드래그 & 드롭으로 서명 필드 배치</li>
                    <li>색상 구분: 작성자(파란색), 상대방(빨간색)</li>
                    <li>필드 타입: signature, stamp, text, date, checkbox</li>
                    <li>좌표는 % 단위 (0-100)</li>
                </ul>
            </InfoCard>
            <InfoCard title="5. 서명 요청 발송 (/esign/{id}/send)" color="blue">
                <ul className="space-y-1">
                    <li>발송 전 체크리스트</li>
                    <li>서명 순서 최종 확인</li>
                    <li>발송 버튼</li>
                </ul>
            </InfoCard>
        </div>

        <SubTitle>공개 화면 - 서명자용 (3개)</SubTitle>
        <div className="space-y-4 mb-6">
            <InfoCard title="6. OTP 인증 (/esign/sign/{token})" color="green">
                <ul className="space-y-1">
                    <li>계약 정보 표시</li>
                    <li>OTP 발송 버튼 (카카오 알림톡 우선, 이메일 폴백)</li>
                    <li>6자리 입력 필드</li>
                    <li>카운트다운 타이머 (5분)</li>
                    <li>남은 시도 횟수 표시</li>
                </ul>
            </InfoCard>
            <InfoCard title="7. 서명 수행 (/esign/sign/{token}/sign)" color="green">
                <ul className="space-y-1">
                    <li>3단계 프로세스: 문서 확인 → 서명 → 확인</li>
                    <li>PDF 다운로드 링크</li>
                    <li>SignaturePad 캔버스 (터치/마우스)</li>
                    <li>동의 체크박스 2개</li>
                    <li>제출 / 거절 옵션</li>
                </ul>
            </InfoCard>
            <InfoCard title="8. 완료 (/esign/sign/{token}/done)" color="green">
                <ul className="space-y-1">
                    <li>서명 완료 메시지</li>
                    <li>계약 요약 정보</li>
                    <li>서명 일시 표시</li>
                </ul>
            </InfoCard>
        </div>

        <SubTitle>스토리보드</SubTitle>
        <InfoCard title="화면 설계 스토리보드 (PPTX)" color="gray">
            <p className="mb-2">8개 화면의 상세 UI 와이어프레임이 포함된 스토리보드입니다.</p>
            <a href="/docs/esign/esign-storyboard.pptx" download
               className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 text-sm font-medium">
                <svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                </svg>
                esign-storyboard.pptx 다운로드
            </a>
        </InfoCard>
    </div>
);

// ============================================================
// Tab 7: Operations Guide
// ============================================================
const OperationsTab = () => (
    <div>
        <SectionTitle>운영 가이드</SectionTitle>

        <SubTitle>초기 배포</SubTitle>
        <CodeBlock title="배포 절차">{`# 1. 마이그레이션
docker exec sam-api-1 php artisan migrate

# 2. 스토리지 설정
docker exec sam-api-1 mkdir -p storage/app/esign
chmod 775 storage/app/esign

# 3. 라우트 캐시
docker exec sam-api-1 php artisan route:cache
docker exec sam-mng-1 php artisan route:cache`}</CodeBlock>

        <SubTitle>환경 변수</SubTitle>
        <Table
            headers={['변수', '개발 환경', '운영 환경']}
            rows={[
                ['APP_ENV', 'local', 'production'],
                ['APP_DEBUG', 'true', 'false'],
                ['MAIL_MAILER', 'log', 'smtp'],
                ['QUEUE_CONNECTION', 'sync', 'database'],
                ['FILESYSTEM_DISK', 'local', 'local / s3'],
                ['KAKAO_ALIMTALK_SENDER_KEY', '-', '카카오 비즈니스 채널 발신 키'],
                ['KAKAO_ALIMTALK_TEMPLATE_*', '-', '알림톡 템플릿 코드 (서명요청/OTP/완료)'],
            ]}
        />

        <SubTitle>모니터링</SubTitle>
        <Table
            headers={['지표', '확인 방법', '임계치']}
            rows={[
                ['API 응답 시간', 'Nginx 로그', '> 3초 경고'],
                ['에러율', 'Laravel 로그', '> 10건/시간'],
                ['디스크 사용량', 'df -h', '> 80% 경고'],
                ['메일 큐', 'queue:failed', '> 0 알림'],
            ]}
        />

        <SubTitle>백업 전략</SubTitle>
        <Table
            headers={['대상', '방법', '주기']}
            rows={[
                ['DB (esign_ 테이블)', 'mysqldump', '매일'],
                ['PDF 파일', 'rsync', '매일'],
                ['감사 로그', '영구 보존', '삭제 불가'],
            ]}
        />

        <SubTitle>장애 대응</SubTitle>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <InfoCard title="카카오 알림톡 발송 실패" color="yellow">
                <ol className="list-decimal list-inside space-y-1">
                    <li>카카오 비즈니스 채널 상태 확인</li>
                    <li>발신 키(SENDER_KEY) 유효성 확인</li>
                    <li>템플릿 승인 상태 확인</li>
                    <li>수신자 전화번호 형식 확인</li>
                    <li>알림톡 실패 시 이메일 폴백 자동 발송 확인</li>
                </ol>
            </InfoCard>
            <InfoCard title="이메일 발송 실패" color="yellow">
                <ol className="list-decimal list-inside space-y-1">
                    <li>Laravel 로그 확인</li>
                    <li>SMTP 설정 확인</li>
                    <li>큐 실패 건 재시도: <code className="bg-yellow-100 px-1 rounded">queue:retry</code></li>
                </ol>
            </InfoCard>
            <InfoCard title="PDF 업로드 실패" color="yellow">
                <ol className="list-decimal list-inside space-y-1">
                    <li>파일 크기 제한 확인 (20MB)</li>
                    <li>디스크 공간 확인</li>
                    <li>storage 디렉토리 권한 확인</li>
                </ol>
            </InfoCard>
        </div>
    </div>
);

// ============================================================
// Tab 8: Changelog
// ============================================================
const ChangelogTab = () => (
    <div>
        <SectionTitle>변경 이력</SectionTitle>

        <SubTitle>v1.0.0 (2026-02-12) - 최초 릴리즈</SubTitle>
        <InfoCard title="SAM E-Sign 전체 구현" color="green">
            <Table
                headers={['저장소', '커밋', '파일', '라인']}
                rows={[
                    ['API', '2', '24', '+1,709'],
                    ['MNG', '1', '11', '+1,564'],
                    ['Docs', '8', '10', '-'],
                    ['합계', '11', '45', '+3,273'],
                ]}
            />
        </InfoCard>

        <div className="mt-4 space-y-2">
            <p className="text-sm text-gray-700"><Badge color="green">API</Badge> 마이그레이션 4개, 모델 4개, 서비스 4개, 컨트롤러 2개, FormRequest 4개, Mail 1개</p>
            <p className="text-sm text-gray-700"><Badge color="blue">MNG</Badge> 컨트롤러 2개, 뷰 8개, 라우트 설정</p>
            <p className="text-sm text-gray-700"><Badge color="gray">Docs</Badge> 기획서, 기술 설계서, API 명세서, 사용자 매뉴얼, 운영 가이드 등 8개 문서</p>
        </div>

        <SubTitle>향후 계획</SubTitle>

        <div className="space-y-4">
            <InfoCard title="v1.1 (계획)" color="blue">
                <ul className="space-y-1">
                    <li>PDF 서명 합성 (FPDI/FPDF)</li>
                    <li>감사 추적 페이지 PDF 포함</li>
                    <li><strong>카카오 알림톡 연동</strong> (서명 요청/OTP/리마인더/완료 알림)</li>
                    <li>자동 만료 스케줄러</li>
                    <li>큐 워커 설정</li>
                </ul>
            </InfoCard>

            <InfoCard title="v1.2 (계획)" color="blue">
                <ul className="space-y-1">
                    <li>대량 계약 발송</li>
                    <li>계약 템플릿 관리</li>
                    <li>알림톡 발송 통계 대시보드</li>
                </ul>
            </InfoCard>

            <InfoCard title="v2.0 (계획)" color="purple">
                <ul className="space-y-1">
                    <li>AWS S3 파일 저장소 전환</li>
                    <li>공인 인증서 연동</li>
                    <li>모바일 반응형 UI</li>
                    <li>다국어 지원</li>
                </ul>
            </InfoCard>
        </div>
    </div>
);

// ============================================================
// Tab Content Map
// ============================================================
const TAB_CONTENT = {
    overview: OverviewTab,
    manual: UserManualTab,
    workflow: WorkflowTab,
    architecture: ArchitectureTab,
    api: ApiTab,
    security: SecurityTab,
    screens: ScreensTab,
    operations: OperationsTab,
    changelog: ChangelogTab,
};

// ============================================================
// Main App
// ============================================================
const App = () => {
    const [activeTab, setActiveTab] = useState('overview');
    const TabContent = TAB_CONTENT[activeTab];

    useEffect(() => {
        if (window.lucide) lucide.createIcons();
    }, [activeTab]);

    return (
        <div className="p-4 sm:p-6">
            {/* Header */}
            <div className="flex items-center justify-between mb-6">
                <div>
                    <h1 className="text-2xl font-bold text-gray-900">SAM E-Sign 문서</h1>
                    <p className="text-sm text-gray-500 mt-1">SAM E-Sign 기술 문서</p>
                </div>
                <a href="/esign"
                   className="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 text-sm font-medium"
                   hx-boost="false">
                    ← 대시보드로 돌아가기
                </a>
            </div>

            <div className="flex flex-col lg:flex-row gap-6">
                {/* Desktop: Left sidebar tabs */}
                <nav className="hidden lg:block w-56 flex-shrink-0">
                    <div className="sticky top-6 space-y-1">
                        {TABS.map(tab => (
                            <button key={tab.id}
                                onClick={() => setActiveTab(tab.id)}
                                className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left transition-colors
                                    ${activeTab === tab.id
                                        ? 'bg-blue-50 text-blue-700 font-semibold'
                                        : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'}`}>
                                <i data-lucide={tab.icon} className="w-4 h-4"></i>
                                {tab.label}
                            </button>
                        ))}
                    </div>
                </nav>

                {/* Mobile: Horizontal scroll tabs */}
                <nav className="lg:hidden overflow-x-auto -mx-6 px-6">
                    <div className="flex gap-1 pb-2 min-w-max">
                        {TABS.map(tab => (
                            <button key={tab.id}
                                onClick={() => setActiveTab(tab.id)}
                                className={`flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm whitespace-nowrap transition-colors
                                    ${activeTab === tab.id
                                        ? 'bg-blue-50 text-blue-700 font-semibold'
                                        : 'text-gray-600 hover:bg-gray-100'}`}>
                                <i data-lucide={tab.icon} className="w-4 h-4"></i>
                                {tab.label}
                            </button>
                        ))}
                    </div>
                </nav>

                {/* Tab content */}
                <div className="flex-1 min-w-0 bg-white rounded-xl border border-gray-200 p-6">
                    <TabContent />
                </div>
            </div>
        </div>
    );
};

ReactDOM.createRoot(document.getElementById('esign-docs-root')).render(<App />);
</script>
@endverbatim
@endpush
