'use client';

import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
import { invalidateDashboard } from '@/lib/dashboard-invalidation';
import { useRouter, useSearchParams } from 'next/navigation';
import { usePermission } from '@/hooks/usePermission';
import { format } from 'date-fns';
import { Trash2, Send, Save, Eye } from 'lucide-react';
import { toast } from 'sonner';
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
import { IntegratedDetailTemplate, type ActionItem } from '@/components/templates/IntegratedDetailTemplate';
import {
  documentCreateConfig,
  documentEditConfig,
  documentCopyConfig,
} from './documentCreateConfig';
import {
  getExpenseEstimateItems,
  createApproval,
  createAndSubmitApproval,
  getApprovalById,
  updateApproval,
  updateAndSubmitApproval,
  deleteApproval,
  getEmployees,
} from './actions';
import { useAuthStore } from '@/stores/authStore';
import { BasicInfoSection } from './BasicInfoSection';
import { ApprovalLineSection } from './ApprovalLineSection';
import { ReferenceSection } from './ReferenceSection';
import { ProposalForm } from './ProposalForm';
import { ExpenseReportForm } from './ExpenseReportForm';
import { ExpenseEstimateForm } from './ExpenseEstimateForm';
import { OfficialDocumentForm } from './OfficialDocumentForm';
import { ResignationForm } from './ResignationForm';
import { LeaveNotice1stForm } from './LeaveNotice1stForm';
import { LeaveNotice2ndForm } from './LeaveNotice2ndForm';
import { PowerOfAttorneyForm } from './PowerOfAttorneyForm';
import { BoardMinutesForm } from './BoardMinutesForm';
import { EmploymentCertForm } from './EmploymentCertForm';
import { CareerCertForm } from './CareerCertForm';
import { AppointmentCertForm } from './AppointmentCertForm';
import { SealUsageForm } from './SealUsageForm';
import { QuotationForm } from './QuotationForm';
import { DynamicFormRenderer } from './DynamicFormRenderer';
import type { ApprovalFormField } from './form-actions';
import { DEDICATED_FORM_CODES } from './types';

function isDedicatedForm(docType: string): boolean {
  return (DEDICATED_FORM_CODES as readonly string[]).includes(docType);
}
// V2: DynamicDocument 렌더링 지원 (14개 전용 양식 미리보기)
import { DocumentDetailModalV2 as DocumentDetailModal } from '@/components/approval/DocumentDetail';
import { getFieldLabels, filterVisibleFields } from '@/components/approval/DocumentDetail/field-labels';
import type {
  DocumentType as ModalDocumentType,
  ProposalDocumentData,
  ExpenseReportDocumentData,
  ExpenseEstimateDocumentData,
  DynamicDocumentData,
} from '@/components/approval/DocumentDetail/types';
import type {
  BasicInfo,
  ApprovalPerson,
  ProposalData,
  ExpenseReportData,
  ExpenseEstimateData,
  OfficialDocumentData,
  ResignationData,
  EmploymentCertData,
  CareerCertData,
  AppointmentCertData,
  SealUsageData,
  LeaveNotice1stData,
  LeaveNotice2ndData,
  PowerOfAttorneyData,
  BoardMinutesData,
  QuotationData,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { useDevFill, generatePurchaseApprovalData } from '@/components/dev';
import { getClients } from '@/components/accounting/VendorManagement/actions';

// 초기 데이터 - SSR에서는 빈 문자열, 클라이언트에서 날짜 설정
const getInitialBasicInfo = (): BasicInfo => ({
  drafter: '', // 클라이언트에서 currentUser로 설정
  draftDate: '', // 클라이언트에서 설정
  documentNo: '',
  documentType: 'proposal',
});

const getInitialProposalData = (): ProposalData => ({
  vendorId: '',
  vendor: '',
  vendorPaymentDate: '', // 클라이언트에서 설정
  title: '',
  description: '',
  reason: '',
  estimatedCost: 0,
  attachments: [],
});

const getInitialExpenseReportData = (): ExpenseReportData => ({
  requestDate: '', // 클라이언트에서 설정
  paymentDate: '', // 클라이언트에서 설정
  items: [],
  cardId: '',
  totalAmount: 0,
  attachments: [],
});

const getInitialExpenseEstimateData = (): ExpenseEstimateData => ({
  title: '',
  body: '',
  items: [],
  totalExpense: 0,
  accountBalance: 10000000,
  finalDifference: 10000000,
});

export function DocumentCreate() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const currentUser = useAuthStore((state) => state.currentUser);
  const { canCreate, canDelete } = usePermission();

  // 수정 모드 / 복제 모드 상태
  const urlDocumentId = searchParams.get('id');
  const mode = searchParams.get('mode');
  const copyFromId = searchParams.get('copyFrom');
  const isCopyMode = !!copyFromId;
  const [isLoadingDocument, setIsLoadingDocument] = useState(false);

  // BUG #11 fix: 임시저장 후 edit 모드 전환을 위한 상태
  const [savedDocId, setSavedDocId] = useState<string | null>(null);
  const documentId = urlDocumentId || savedDocId;
  const isEditMode = (mode === 'edit' && !!urlDocumentId) || !!savedDocId;

  // 상태 관리
  const [basicInfo, setBasicInfo] = useState<BasicInfo>(getInitialBasicInfo);
  const [approvalLine, setApprovalLine] = useState<ApprovalPerson[]>([]);
  const [references, setReferences] = useState<ApprovalPerson[]>([]);
  const [proposalData, setProposalData] = useState<ProposalData>(getInitialProposalData);
  const [expenseReportData, setExpenseReportData] = useState<ExpenseReportData>(getInitialExpenseReportData);
  const [expenseEstimateData, setExpenseEstimateData] = useState<ExpenseEstimateData>(getInitialExpenseEstimateData);
  const [dynamicFormData, setDynamicFormData] = useState<Record<string, unknown>>({});
  const [dynamicFormFields, setDynamicFormFields] = useState<ApprovalFormField[]>([]);
  const [officialDocumentData, setOfficialDocumentData] = useState<OfficialDocumentData>({ documentNumber: '', documentDate: '', recipient: '', reference: '', title: '', body: '', attachment: '', companyName: '', representativeName: '', address: '', phone: '', fax: '', email: '' });
  const [resignationData, setResignationData] = useState<ResignationData>({ employeeId: '', department: '', position: '', employeeName: '', residentNumber: '', joinDate: '', resignDate: '', employeeAddress: '', reasonType: '', reasonDetail: '', submitDate: '' });
  const [employmentCertData, setEmploymentCertData] = useState<EmploymentCertData>({ employeeId: '', employeeName: '', residentNumber: '', employeeAddress: '', companyName: '', businessNumber: '', department: '', position: '', employmentPeriodStart: '', employmentPeriodEnd: '', purpose: '', issueDate: '' });
  const [careerCertData, setCareerCertData] = useState<CareerCertData>({ employeeId: '', employeeName: '', residentNumber: '', birthDate: '', employeeAddress: '', companyName: '', businessNumber: '', representativeName: '', companyPhone: '', companyAddress: '', department: '', positionTitle: '', workPeriodStart: '', workPeriodEnd: '', duties: '', purpose: '', issueDate: '' });
  const [appointmentCertData, setAppointmentCertData] = useState<AppointmentCertData>({ employeeId: '', employeeName: '', residentNumber: '', department: '', phone: '', appointmentPeriodStart: '', appointmentPeriodEnd: '', contractQualification: '', purpose: '', issueDate: '' });
  const [sealUsageData, setSealUsageData] = useState<SealUsageData>({ sealImprint: '', purpose: '', submitTo: '', attachedDocuments: '', usageDate: '', companyName: '', businessNumber: '', address: '', representativeName: '' });
  const [leaveNotice1stData, setLeaveNotice1stData] = useState<LeaveNotice1stData>({ employeeId: '', department: '', position: '', totalDays: 0, usedDays: 0, remainingDays: 0, deadline: '', legalNotice: '' });
  const [leaveNotice2ndData, setLeaveNotice2ndData] = useState<LeaveNotice2ndData>({ employeeId: '', department: '', position: '', remainingDays: 0, designatedDates: [''], legalNotice: '' });
  const [powerOfAttorneyData, setPowerOfAttorneyData] = useState<PowerOfAttorneyData>({ principalCompanyName: '', principalBusinessNumber: '', principalAddress: '', principalRepresentative: '', agentName: '', agentBirthDate: '', agentAddress: '', agentPhone: '', agentDepartment: '', delegationDetails: '', delegationPeriodStart: '', delegationPeriodEnd: '', attachedDocuments: '' });
  const [boardMinutesData, setBoardMinutesData] = useState<BoardMinutesData>({ meetingDate: '', meetingPlace: '', totalDirectors: 0, attendingDirectors: 0, totalAuditors: 0, attendingAuditors: 0, agendaTitle: '', agendaResult: '', chairperson: '', proceedings: '', adjournmentTime: '', signatories: '' });
  const [quotationData, setQuotationData] = useState<QuotationData>({ recipientName: '', quotationDate: '', businessNumber: '', companyName: '', representativeName: '', companyAddress: '', businessType: '', businessCategory: '', companyPhone: '', accountNumber: '', autoTax: true, items: [], specialNotes: '' });
  const [isLoadingEstimate, setIsLoadingEstimate] = useState(false);
  const prevFormIdRef = useRef<number | undefined>(undefined);

  // 양식 변경 시 동적 폼 데이터 초기화
  useEffect(() => {
    if (prevFormIdRef.current !== undefined && basicInfo.formId !== prevFormIdRef.current) {
      setDynamicFormData({});
    }
    prevFormIdRef.current = basicInfo.formId;
  }, [basicInfo.formId]);

  // 복제 모드 toast 중복 호출 방지
  const copyToastShownRef = useRef(false);

  // 삭제 확인 다이얼로그
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);

  // Hydration 불일치 방지: 클라이언트에서만 날짜 초기화
  useEffect(() => {
    const today = format(new Date(), 'yyyy-MM-dd');
    const now = format(new Date(), 'yyyy-MM-dd HH:mm');

    // localStorage 'user' 키에서 사용자 이름 가져오기 (로그인 시 저장됨)
    const userDataStr = typeof window !== 'undefined' ? localStorage.getItem('user') : null;
    const userName = userDataStr ? JSON.parse(userDataStr).name : currentUser?.name || '';

    setBasicInfo(prev => ({
      ...prev,
      drafter: prev.drafter || userName,
      draftDate: prev.draftDate || now,
    }));
    setProposalData(prev => ({ ...prev, vendorPaymentDate: prev.vendorPaymentDate || today }));
    setExpenseReportData(prev => ({
      ...prev,
      requestDate: prev.requestDate || today,
      paymentDate: prev.paymentDate || today,
    }));
  }, [currentUser?.name]);

  // 미리보기 모달 상태
  const [isPreviewOpen, setIsPreviewOpen] = useState(false);

  // ===== DevFill: 자동 입력 기능 =====
  useDevFill('purchaseApproval', useCallback(async () => {
    if (!isEditMode && !isCopyMode) {
      const mockData = generatePurchaseApprovalData();

      // 직원 목록 가져오기
      const employees = await getEmployees();

      // 거래처 목록 가져오기 (매입 거래처만)
      const clientsResult = await getClients({ size: 1000, only_active: true });
      const purchaseClients = clientsResult.success
        ? clientsResult.data
            .filter((v) => v.category === 'purchase' || v.category === 'both')
            .map((v) => ({ id: v.id, name: v.vendorName }))
        : [];

      // 랜덤 거래처 선택
      const randomClient = purchaseClients.length > 0
        ? purchaseClients[Math.floor(Math.random() * purchaseClients.length)]
        : null;

      // localStorage에서 실제 로그인 사용자 이름 가져오기 (우측 상단 표시와 동일한 소스)
      const userDataStr = localStorage.getItem("user");
      const currentUserName = userDataStr ? JSON.parse(userDataStr).name : currentUser?.name;

      // 현재 사용자 이름으로 결재선에 추가할 직원 찾기
      const approver = currentUserName
        ? employees.find(e => e.name === currentUserName)
        : null;

      // 경리/회계/재무 부서 직원 중 랜덤 1명 참조 추가
      const accountingDepts = ['경리', '회계', '재무'];
      const accountingStaff = employees.filter(e =>
        accountingDepts.some(dept => e.department?.includes(dept))
      );
      const randomReference = accountingStaff.length > 0
        ? accountingStaff[Math.floor(Math.random() * accountingStaff.length)]
        : null;

      setBasicInfo(prev => ({
        ...prev,
        ...mockData.basicInfo,
        drafter: currentUserName || prev.drafter,
        draftDate: prev.draftDate || mockData.basicInfo.draftDate,
        documentType: (mockData.basicInfo.documentType || prev.documentType) as BasicInfo['documentType'],
      }));

      // 결재선: 현재 사용자가 직원 목록에 있으면 설정, 없으면 랜덤 1명
      if (approver) {
        setApprovalLine([approver]);
      } else if (employees.length > 0) {
        const randomApprover = employees[Math.floor(Math.random() * employees.length)];
        setApprovalLine([randomApprover]);
      }

      // 참조: 경리/회계/재무 직원이 있으면 설정
      if (randomReference) {
        setReferences([randomReference]);
      }

      setProposalData(prev => ({
        ...prev,
        ...mockData.proposalData,
        // 실제 API 거래처로 덮어쓰기
        vendorId: randomClient?.id || '',
        vendor: randomClient?.name || '',
      }));
      toast.success('지출결의서 데이터가 자동 입력되었습니다.');
    }
  }, [isEditMode, isCopyMode, currentUser?.name]));

  // 수정 모드: 문서 로드 (URL 기반으로만 — savedDocId로 전환 시에는 재로딩하지 않음)
  useEffect(() => {
    if (!(mode === 'edit' && urlDocumentId)) return;

    const loadDocument = async () => {
      setIsLoadingDocument(true);
      try {
        const result = await getApprovalById(parseInt(urlDocumentId));
        if (result.success && result.data) {
          const loaded = result.data;

          setBasicInfo(loaded.basicInfo);
          setApprovalLine(loaded.approvalLine);
          setReferences(loaded.references);
          if (loaded.proposalData) setProposalData(loaded.proposalData);
          if (loaded.expenseReportData) setExpenseReportData(loaded.expenseReportData);
          if (loaded.expenseEstimateData) setExpenseEstimateData(loaded.expenseEstimateData);
          if (loaded.dynamicFormData) setDynamicFormData(loaded.dynamicFormData);

          // 12개 전용 양식 데이터 복원
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          const d = loaded as any;
          if (d.officialDocumentData) setOfficialDocumentData(d.officialDocumentData);
          if (d.resignationData) setResignationData(d.resignationData);
          if (d.employmentCertData) setEmploymentCertData(d.employmentCertData);
          if (d.careerCertData) setCareerCertData(d.careerCertData);
          if (d.appointmentCertData) setAppointmentCertData(d.appointmentCertData);
          if (d.sealUsageData) setSealUsageData(d.sealUsageData);
          if (d.leaveNotice1stData) setLeaveNotice1stData(d.leaveNotice1stData);
          if (d.leaveNotice2ndData) setLeaveNotice2ndData(d.leaveNotice2ndData);
          if (d.powerOfAttorneyData) setPowerOfAttorneyData(d.powerOfAttorneyData);
          if (d.boardMinutesData) setBoardMinutesData(d.boardMinutesData);
          if (d.quotationData) setQuotationData(d.quotationData);
        } else {
          toast.error(result.error || '문서를 불러오는데 실패했습니다.');
          router.back();
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Failed to load document:', error);
        toast.error('문서를 불러오는데 실패했습니다.');
        router.back();
      } finally {
        setIsLoadingDocument(false);
      }
    };

    loadDocument();
  }, [mode, urlDocumentId, router]);

  // 복제 모드: 원본 문서 로드 후 새 문서로 설정
  useEffect(() => {
    if (!isCopyMode || !copyFromId) return;

    const loadDocumentForCopy = async () => {
      setIsLoadingDocument(true);
      try {
        const result = await getApprovalById(parseInt(copyFromId));
        if (result.success && result.data) {
          const loaded = result.data;

          // 복제: 문서번호 초기화, 기안일 현재 시간으로
          const now = format(new Date(), 'yyyy-MM-dd HH:mm');
          setBasicInfo({
            ...loaded.basicInfo,
            documentNo: '', // 새 문서이므로 문서번호 초기화
            draftDate: now,
          });

          // 결재선/참조는 그대로 유지
          setApprovalLine(loaded.approvalLine);
          setReferences(loaded.references);

          // 문서 내용 복제
          if (loaded.proposalData) setProposalData(loaded.proposalData);
          if (loaded.expenseReportData) setExpenseReportData(loaded.expenseReportData);
          if (loaded.expenseEstimateData) setExpenseEstimateData(loaded.expenseEstimateData);
          if (loaded.dynamicFormData) setDynamicFormData(loaded.dynamicFormData);

          // 12개 전용 양식 데이터 복원
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          const d = loaded as any;
          if (d.officialDocumentData) setOfficialDocumentData(d.officialDocumentData);
          if (d.resignationData) setResignationData(d.resignationData);
          if (d.employmentCertData) setEmploymentCertData(d.employmentCertData);
          if (d.careerCertData) setCareerCertData(d.careerCertData);
          if (d.appointmentCertData) setAppointmentCertData(d.appointmentCertData);
          if (d.sealUsageData) setSealUsageData(d.sealUsageData);
          if (d.leaveNotice1stData) setLeaveNotice1stData(d.leaveNotice1stData);
          if (d.leaveNotice2ndData) setLeaveNotice2ndData(d.leaveNotice2ndData);
          if (d.powerOfAttorneyData) setPowerOfAttorneyData(d.powerOfAttorneyData);
          if (d.boardMinutesData) setBoardMinutesData(d.boardMinutesData);
          if (d.quotationData) setQuotationData(d.quotationData);

          // React.StrictMode에서 useEffect 두 번 실행으로 인한 toast 중복 방지
          if (!copyToastShownRef.current) {
            copyToastShownRef.current = true;
            toast.info('문서가 복제되었습니다. 수정 후 상신해주세요.');
          }
        } else {
          toast.error(result.error || '원본 문서를 불러오는데 실패했습니다.');
          router.back();
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Failed to load document for copy:', error);
        toast.error('원본 문서를 불러오는데 실패했습니다.');
        router.back();
      } finally {
        setIsLoadingDocument(false);
      }
    };

    loadDocumentForCopy();
  }, [isCopyMode, copyFromId, router]);

  // 비용견적서 항목 로드
  const loadExpenseEstimateItems = useCallback(async () => {
    setIsLoadingEstimate(true);
    try {
      const result = await getExpenseEstimateItems();
      if (result) {
        setExpenseEstimateData(prev => ({
          ...prev,
          items: result.items,
          totalExpense: result.totalExpense,
          accountBalance: result.accountBalance,
          finalDifference: result.finalDifference,
        }));
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load expense estimate items:', error);
      toast.error('비용견적서 항목을 불러오는데 실패했습니다.');
    } finally {
      setIsLoadingEstimate(false);
    }
  }, []);

  // 문서 유형이 비용견적서로 변경되면 항목 로드
  useEffect(() => {
    if (basicInfo.documentType === 'expenseEstimate' && expenseEstimateData.items.length === 0) {
      loadExpenseEstimateItems();
    }
  }, [basicInfo.documentType, expenseEstimateData.items.length, loadExpenseEstimateItems]);

  // 폼 데이터 수집
  const getFormData = useCallback(() => {
    const dt = basicInfo.documentType;
    return {
      basicInfo,
      approvalLine,
      references,
      proposalData: dt === 'proposal' ? proposalData : undefined,
      expenseReportData: dt === 'expenseReport' ? expenseReportData : undefined,
      expenseEstimateData: dt === 'expenseEstimate' ? expenseEstimateData : undefined,
      officialDocumentData: dt === 'officialDocument' ? officialDocumentData : undefined,
      resignationData: dt === 'resignation' ? resignationData : undefined,
      employmentCertData: dt === 'employmentCert' ? employmentCertData : undefined,
      careerCertData: dt === 'careerCert' ? careerCertData : undefined,
      appointmentCertData: dt === 'appointmentCert' ? appointmentCertData : undefined,
      sealUsageData: dt === 'sealUsage' ? sealUsageData : undefined,
      leaveNotice1stData: dt === 'leaveNotice1st' ? leaveNotice1stData : undefined,
      leaveNotice2ndData: dt === 'leaveNotice2nd' ? leaveNotice2ndData : undefined,
      powerOfAttorneyData: dt === 'powerOfAttorney' ? powerOfAttorneyData : undefined,
      boardMinutesData: dt === 'boardMinutes' ? boardMinutesData : undefined,
      quotationData: dt === 'quotation' ? quotationData : undefined,
      dynamicFormData: isDedicatedForm(dt) ? undefined : dynamicFormData,
    };
  }, [basicInfo, approvalLine, references, proposalData, expenseReportData, expenseEstimateData, officialDocumentData, resignationData, employmentCertData, careerCertData, appointmentCertData, sealUsageData, leaveNotice1stData, leaveNotice2ndData, powerOfAttorneyData, boardMinutesData, quotationData, dynamicFormData]);

  // 핸들러
  const handleBack = useCallback(() => {
    router.back();
  }, [router]);

  const handleDelete = useCallback(() => {
    setIsDeleteDialogOpen(true);
  }, []);

  const handleDeleteConfirm = useCallback(async () => {
    setIsDeleteDialogOpen(false);

    // 수정 모드: 실제 문서 삭제
    if (isEditMode && documentId) {
      setIsSubmitting(true);
      try {
        const result = await deleteApproval(parseInt(documentId));
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('문서가 삭제되었습니다.');
          router.back();
        } else {
          toast.error(result.error || '문서 삭제에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Delete error:', error);
        toast.error('문서 삭제 중 오류가 발생했습니다.');
      } finally {
        setIsSubmitting(false);
      }
    } else {
      // 새 문서: 그냥 뒤로가기
      router.back();
    }
  }, [router, isEditMode, documentId]);

  const handleSubmit = useCallback(async () => {
    // 유효성 검사
    if (!basicInfo.formId) {
      toast.error('양식을 선택해주세요.');
      return;
    }
    if (approvalLine.length === 0) {
      toast.error('결재선을 지정해주세요.');
      return;
    }
    // BUG #14 fix: 동적 폼 필수 필드 프론트엔드 검증
    if (dynamicFormFields.length > 0) {
      const requiredFields = dynamicFormFields.filter(f => f.required);
      const missingFields = requiredFields.filter(f => {
        const val = dynamicFormData[f.name];
        return val === '' || val === null || val === undefined;
      });
      if (missingFields.length > 0) {
        toast.error(`필수 항목을 입력해주세요: ${missingFields.map(f => f.label).join(', ')}`);
        return;
      }
    }

    setIsSubmitting(true);
    try {
      const formData = getFormData();

      // 수정 모드: 수정 후 상신
      if (isEditMode && documentId) {
        const result = await updateAndSubmitApproval(parseInt(documentId), formData);
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('수정 및 상신 완료', {
            description: `문서번호: ${result.data?.documentNo}`,
          });
          // BUG #1 fix: router.push로 기안함 이동하여 데이터 확실히 로드
          router.push('/approval/draft');
        } else {
          toast.error(result.error || '문서 상신에 실패했습니다.');
        }
      } else {
        // 새 문서: 생성 후 상신
        const result = await createAndSubmitApproval(formData);
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('상신 완료', {
            description: `문서번호: ${result.data?.documentNo}`,
          });
          // BUG #1 fix: router.push로 기안함 이동하여 데이터 확실히 로드
          router.push('/approval/draft');
        } else {
          toast.error(result.error || '문서 상신에 실패했습니다.');
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Submit error:', error);
      toast.error('문서 상신 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  }, [approvalLine, getFormData, router, isEditMode, documentId]);

  const handleSaveDraft = useCallback(async () => {
    if (!basicInfo.formId) {
      toast.error('양식을 선택해주세요.');
      return;
    }
    // BUG #13 fix: 빈 폼 사전 검증 — 최소 1개 필드 입력 필요
    if (!isEditMode) {
      const formData = getFormData();
      const dt = formData.basicInfo.documentType;
      const hasDedicatedContent =
        (dt === 'proposal' && formData.proposalData?.title) ||
        (dt === 'expenseReport' && (formData.expenseReportData?.items?.length ?? 0) > 0) ||
        (dt === 'expenseEstimate' && (formData.expenseEstimateData?.items?.length ?? 0) > 0);
      const hasDynamicContent = formData.dynamicFormData && Object.values(formData.dynamicFormData).some(v => v !== '' && v !== null && v !== undefined && v !== 0);
      const hasDedicatedFormContent = !isDedicatedForm(dt) ? false :
        [formData.officialDocumentData, formData.resignationData, formData.employmentCertData,
         formData.careerCertData, formData.appointmentCertData, formData.sealUsageData,
         formData.leaveNotice1stData, formData.leaveNotice2ndData, formData.powerOfAttorneyData,
         formData.boardMinutesData, formData.quotationData].some(d =>
          d && Object.values(d as unknown as Record<string, unknown>).some(v => v !== '' && v !== null && v !== undefined && v !== 0)
        );
      if (!hasDedicatedContent && !hasDynamicContent && !hasDedicatedFormContent) {
        toast.error('문서 내용을 최소 1개 이상 입력해주세요.');
        return;
      }
    }
    setIsSubmitting(true);
    try {
      const formData = getFormData();

      // 수정 모드: 기존 문서 업데이트
      if (isEditMode && documentId) {
        const result = await updateApproval(parseInt(documentId), formData);
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('저장 완료', {
            description: `문서번호: ${result.data?.documentNo}`,
          });
        } else {
          toast.error(result.error || '저장에 실패했습니다.');
        }
      } else {
        // 새 문서: 임시저장
        const result = await createApproval(formData);
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('임시저장 완료', {
            description: `문서번호: ${result.data?.documentNo}`,
          });
          // 문서번호 업데이트
          if (result.data?.documentNo) {
            setBasicInfo(prev => ({ ...prev, documentNo: result.data!.documentNo }));
          }
          // BUG #11 fix: edit 모드로 전환하여 이후 저장이 updateApproval을 호출하도록
          if (result.data?.id) {
            setSavedDocId(String(result.data.id));
          }
        } else {
          toast.error(result.error || '임시저장에 실패했습니다.');
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Save draft error:', error);
      toast.error('저장 중 오류가 발생했습니다.');
    } finally {
      setIsSubmitting(false);
    }
  }, [getFormData, isEditMode, documentId]);

  // 미리보기 핸들러
  const handlePreview = useCallback(() => {
    setIsPreviewOpen(true);
  }, []);

  // 미리보기용 데이터 변환
  const getPreviewData = useCallback((): ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData | DynamicDocumentData => {
    const drafter = {
      id: 'drafter-1',
      name: basicInfo.drafter,
      position: '사원',
      department: '개발팀',
      status: 'approved' as const,
    };
    const approvers = approvalLine.map((a, index) => ({
      id: a.id,
      name: a.name,
      position: a.position,
      department: a.department,
      status: (index === 0 ? 'pending' : 'none') as 'pending' | 'approved' | 'rejected' | 'none',
    }));

    switch (basicInfo.documentType) {
      case 'expenseEstimate':
        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          items: expenseEstimateData.items.map(item => ({
            id: item.id,
            expectedPaymentDate: item.expectedPaymentDate,
            category: item.category,
            amount: item.amount,
            vendor: item.vendor,
            account: item.memo || '',
          })),
          totalExpense: expenseEstimateData.totalExpense,
          accountBalance: expenseEstimateData.accountBalance,
          finalDifference: expenseEstimateData.finalDifference,
          approvers,
          drafter,
        };
      case 'expenseReport':
        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          requestDate: expenseReportData.requestDate,
          paymentDate: expenseReportData.paymentDate,
          items: expenseReportData.items.map((item, index) => ({
            id: item.id,
            no: index + 1,
            description: item.description,
            amount: item.amount,
            note: item.note,
          })),
          cardInfo: expenseReportData.cardId || '-',
          totalAmount: expenseReportData.totalAmount,
          attachments: [
            ...(expenseReportData.uploadedFiles || []).map(f => `/api/proxy/files/${f.id}/download`),
            ...expenseReportData.attachments.map(f => URL.createObjectURL(f)),
          ],
          approvers,
          drafter,
        };
      default: {
        // 신규 전용 폼들: DynamicDocumentData 형태로 미리보기
        const dedicatedFormDataMap: Record<string, { formName: string; fields: Record<string, unknown> }> = {
          officialDocument: { formName: '공문서', fields: officialDocumentData as unknown as Record<string, unknown> },
          resignation: { formName: '사직서', fields: resignationData as unknown as Record<string, unknown> },
          employmentCert: { formName: '재직증명서', fields: employmentCertData as unknown as Record<string, unknown> },
          careerCert: { formName: '경력증명서', fields: careerCertData as unknown as Record<string, unknown> },
          appointmentCert: { formName: '위촉증명서', fields: appointmentCertData as unknown as Record<string, unknown> },
          sealUsage: { formName: '사용인감계', fields: sealUsageData as unknown as Record<string, unknown> },
          leaveNotice1st: { formName: '연차촉진 1차', fields: leaveNotice1stData as unknown as Record<string, unknown> },
          leaveNotice2nd: { formName: '연차촉진 2차', fields: leaveNotice2ndData as unknown as Record<string, unknown> },
          powerOfAttorney: { formName: '위임장', fields: powerOfAttorneyData as unknown as Record<string, unknown> },
          boardMinutes: { formName: '이사회의사록', fields: boardMinutesData as unknown as Record<string, unknown> },
          quotation: { formName: '견적서', fields: quotationData as unknown as Record<string, unknown> },
        };

        const dedicatedPreview = dedicatedFormDataMap[basicInfo.documentType];
        if (dedicatedPreview) {
          return {
            documentNo: basicInfo.documentNo || '미발급',
            createdAt: basicInfo.draftDate,
            formName: dedicatedPreview.formName,
            formCategory: basicInfo.formCategory,
            fields: filterVisibleFields(dedicatedPreview.fields),
            fieldLabels: getFieldLabels(basicInfo.documentType),
            approvers,
            drafter,
          };
        }

        // 동적 폼이면 DynamicDocumentData 반환
        if (basicInfo.formId && !isDedicatedForm(basicInfo.documentType)) {
          // 동적 폼 필드의 name → label 매핑 생성
          const fieldLabels: Record<string, string> = {};
          dynamicFormFields.forEach(f => {
            fieldLabels[f.name] = f.label;
            // array 타입의 columns도 매핑
            if (f.columns) {
              f.columns.forEach(col => {
                fieldLabels[col.name] = col.label;
              });
            }
          });

          return {
            documentNo: basicInfo.documentNo || '미발급',
            createdAt: basicInfo.draftDate,
            formName: basicInfo.formName || '문서',
            formCategory: basicInfo.formCategory,
            fields: dynamicFormData,
            fieldLabels,
            approvers,
            drafter,
          };
        }

        // 기본 품의서 폴백
        const uploadedFileUrls = (proposalData.uploadedFiles || []).map(f =>
          `/api/proxy/files/${f.id}/download`
        );
        const newFileUrls = proposalData.attachments.map(f => URL.createObjectURL(f));

        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          vendor: proposalData.vendor || '-',
          vendorPaymentDate: proposalData.vendorPaymentDate,
          title: proposalData.title || '(제목 없음)',
          description: proposalData.description || '-',
          reason: proposalData.reason || '-',
          estimatedCost: proposalData.estimatedCost,
          attachments: [...uploadedFileUrls, ...newFileUrls],
          approvers,
          drafter,
        };
      }
    }
  }, [basicInfo, approvalLine, proposalData, expenseReportData, expenseEstimateData, officialDocumentData, resignationData, employmentCertData, careerCertData, appointmentCertData, sealUsageData, leaveNotice1stData, leaveNotice2ndData, powerOfAttorneyData, boardMinutesData, quotationData, dynamicFormData, dynamicFormFields]);

  // 문서 유형별 폼 렌더링
  const renderDocumentTypeForm = () => {
    switch (basicInfo.documentType) {
      case 'proposal':
        return <ProposalForm data={proposalData} onChange={setProposalData} />;
      case 'expenseReport':
        return <ExpenseReportForm data={expenseReportData} onChange={setExpenseReportData} />;
      case 'expenseEstimate':
        return <ExpenseEstimateForm data={expenseEstimateData} onChange={setExpenseEstimateData} isLoading={isLoadingEstimate} />;
      // 신규 12종 전용 폼
      case 'officialDocument':
        return <OfficialDocumentForm data={officialDocumentData} onChange={setOfficialDocumentData} />;
      case 'resignation':
        return <ResignationForm data={resignationData} onChange={setResignationData} />;
      case 'leaveNotice1st':
        return <LeaveNotice1stForm data={leaveNotice1stData} onChange={setLeaveNotice1stData} />;
      case 'leaveNotice2nd':
        return <LeaveNotice2ndForm data={leaveNotice2ndData} onChange={setLeaveNotice2ndData} />;
      case 'powerOfAttorney':
        return <PowerOfAttorneyForm data={powerOfAttorneyData} onChange={setPowerOfAttorneyData} />;
      case 'boardMinutes':
        return <BoardMinutesForm data={boardMinutesData} onChange={setBoardMinutesData} />;
      case 'employmentCert':
        return <EmploymentCertForm data={employmentCertData} onChange={setEmploymentCertData} />;
      case 'careerCert':
        return <CareerCertForm data={careerCertData} onChange={setCareerCertData} />;
      case 'appointmentCert':
        return <AppointmentCertForm data={appointmentCertData} onChange={setAppointmentCertData} />;
      case 'sealUsage':
        return <SealUsageForm data={sealUsageData} onChange={setSealUsageData} />;
      case 'quotation':
        return <QuotationForm data={quotationData} onChange={setQuotationData} />;
      default:
        // 동적 폼: API template 기반 렌더링
        if (basicInfo.formId) {
          return (
            <DynamicFormRenderer
              formId={basicInfo.formId}
              data={dynamicFormData}
              onChange={setDynamicFormData}
              onFieldsLoaded={setDynamicFormFields}
            />
          );
        }
        return null;
    }
  };

  // 양식이 선택되었는지 여부 (결재선/참조/폼 섹션 표시 조건)
  const isFormSelected = !!basicInfo.formId;

  // 현재 모드에 맞는 config 선택
  const currentConfig = isEditMode
    ? documentEditConfig
    : isCopyMode
    ? documentCopyConfig
    : documentCreateConfig;

  // 헤더 액션 버튼 (config 배열 → 모바일 아이콘 패턴 자동 적용)
  const headerActionItems = useMemo<ActionItem[]>(() => [
    { icon: Eye, label: '미리보기', onClick: handlePreview, variant: 'outline', disabled: !isFormSelected },
    { icon: Trash2, label: '삭제', onClick: handleDelete, variant: 'outline', hidden: !canDelete, disabled: isSubmitting },
    { icon: Send, label: '상신', onClick: handleSubmit, variant: 'outline', disabled: isSubmitting || !canCreate || !isFormSelected, loading: isSubmitting },
    { icon: Save, label: isEditMode ? '저장' : '임시저장', onClick: handleSaveDraft, variant: 'outline', disabled: isSubmitting || !isFormSelected, loading: isSubmitting },
  ], [handlePreview, handleDelete, handleSubmit, handleSaveDraft, isSubmitting, isEditMode, canCreate, canDelete, isFormSelected]);

  // 폼 컨텐츠 렌더링
  const renderFormContent = useCallback(() => {
    return (
      <div className="space-y-6">
        {/* 기본 정보 */}
        <BasicInfoSection data={basicInfo} onChange={setBasicInfo} />

        {/* 양식 선택 후에만 결재선/참조/폼 표시 */}
        {isFormSelected && (
          <>
            {/* 결재선 */}
            <ApprovalLineSection data={approvalLine} onChange={setApprovalLine} />

            {/* 참조 */}
            <ReferenceSection data={references} onChange={setReferences} />

            {/* 문서 유형별 폼 */}
            {renderDocumentTypeForm()}
          </>
        )}
      </div>
    );
  }, [basicInfo, approvalLine, references, renderDocumentTypeForm, isFormSelected]);

  return (
    <>
      <IntegratedDetailTemplate
        config={currentConfig}
        mode={isEditMode ? 'edit' : 'create'}
        isLoading={isLoadingDocument}
        onBack={handleBack}
        renderForm={renderFormContent}
        headerActionItems={headerActionItems}
      />

      {/* 미리보기 모달 */}
      <DocumentDetailModal
        open={isPreviewOpen}
        onOpenChange={setIsPreviewOpen}
        documentType={['proposal', 'expenseReport', 'expenseEstimate'].includes(basicInfo.documentType) ? basicInfo.documentType as ModalDocumentType : 'dynamic'}
        data={getPreviewData()}
        mode="draft"
        documentStatus="draft"
        onCopy={() => {
          // 복제: 현재 데이터를 기반으로 새 문서 등록 화면으로 이동
          if (documentId) {
            router.push(`/ko/approval/draft/new?copyFrom=${documentId}`);
            setIsPreviewOpen(false);
          }
        }}
        onSubmit={() => {
          setIsPreviewOpen(false);
          handleSubmit();
        }}
      />

      <DeleteConfirmDialog
        open={isDeleteDialogOpen}
        onOpenChange={setIsDeleteDialogOpen}
        onConfirm={handleDeleteConfirm}
        title="문서 삭제"
        description="작성 중인 문서를 삭제하시겠습니까?"
      />
    </>
  );
}
