'use client';

/**
 * 악성채권 추심관리 상세 페이지
 * IntegratedDetailTemplate 마이그레이션 완료 (2026-01-20)
 */

import { useState, useCallback, useMemo } from 'react';
import { useDaumPostcode } from '@/hooks/useDaumPostcode';
import { useRouter } from 'next/navigation';
import { format } from 'date-fns';
import { Plus, X, FileText, Receipt, CreditCard, Upload, Download, Trash2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { PhoneInput } from '@/components/ui/phone-input';
import { BusinessNumberInput } from '@/components/ui/business-number-input';
import { Textarea } from '@/components/ui/textarea';
import { CurrencyInput } from '@/components/ui/currency-input';
import { NumberInput } from '@/components/ui/number-input';
import { Switch } from '@/components/ui/switch';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { DeleteConfirmDialog, SaveConfirmDialog } from '@/components/ui/confirm-dialog';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { badDebtConfig } from './badDebtConfig';
import { toast } from 'sonner';
import type {
  BadDebtRecord,
  BadDebtMemo,
  Manager,
  CollectionStatus,
} from './types';
import {
  STATUS_SELECT_OPTIONS,
  VENDOR_TYPE_LABELS,
} from './types';
import { createBadDebt, updateBadDebt, deleteBadDebt, addBadDebtMemo, deleteBadDebtMemo } from './actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { usePermission } from '@/hooks/usePermission';

interface BadDebtDetailProps {
  mode: 'view' | 'edit' | 'new';
  recordId?: string;
  initialData?: BadDebtRecord;
}

// 담당자 목록 (TODO: API에서 조회)
const MANAGER_OPTIONS: Manager[] = [
  { id: 'm1', departmentName: '경영지원팀', name: '홍길동', position: '과장', phone: '010-1234-1234' },
  { id: 'm2', departmentName: '재무팀', name: '김철수', position: '대리', phone: '010-2345-2345' },
  { id: 'm3', departmentName: '영업팀', name: '이영희', position: '차장', phone: '010-3456-3456' },
  { id: 'm4', departmentName: '관리팀', name: '박민수', position: '사원', phone: '010-4567-4567' },
];

// 빈 레코드 생성 (신규 등록용)
const getEmptyRecord = (): Omit<BadDebtRecord, 'id' | 'createdAt' | 'updatedAt'> => ({
  vendorId: '',
  vendorCode: '',
  vendorName: '',
  businessNumber: '',
  representativeName: '',
  vendorType: 'both',
  businessType: '',
  businessCategory: '',
  zipCode: '',
  address1: '',
  address2: '',
  phone: '',
  mobile: '',
  fax: '',
  email: '',
  contactName: '',
  contactPhone: '',
  systemManager: '',
  debtAmount: 0,
  status: 'collecting',
  overdueDays: 0,
  overdueToggle: false,
  occurrenceDate: format(new Date(), 'yyyy-MM-dd'),
  endDate: null,
  assignedManagerId: null,
  assignedManager: null,
  settingToggle: true,
  badDebtCount: 0,
  badDebts: [],
  files: [],
  memos: [],
});

export function BadDebtDetail({ mode, recordId, initialData }: BadDebtDetailProps) {
  const router = useRouter();
  const { canUpdate, canDelete } = usePermission();
  const isViewMode = mode === 'view';
  const isNewMode = mode === 'new';

  // 폼 데이터: initialData가 있으면 사용, 없으면 빈 레코드 (신규 등록)
  const [formData, setFormData] = useState(initialData || getEmptyRecord() as BadDebtRecord);

  // Daum 우편번호 서비스
  const { openPostcode } = useDaumPostcode({
    onComplete: (result) => {
      setFormData(prev => ({
        ...prev,
        zipCode: result.zonecode,
        address1: result.address,
      }));
    },
  });

  // 다이얼로그 상태
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const [showSaveDialog, setShowSaveDialog] = useState(false);
  const [isLoading, setIsLoading] = useState(false);

  // 새 메모 입력
  const [newMemo, setNewMemo] = useState('');

  // 파일 업로드 상태
  const [newBusinessRegistrationFile, setNewBusinessRegistrationFile] = useState<File | null>(null);
  const [newTaxInvoiceFile, setNewTaxInvoiceFile] = useState<File | null>(null);
  const [newAdditionalFiles, setNewAdditionalFiles] = useState<File[]>([]);

  // 필드 변경 핸들러
  const handleChange = useCallback((field: string, value: string | number | boolean | null) => {
    setFormData(prev => ({ ...prev, [field]: value }));
  }, []);

  // 네비게이션 핸들러
  const handleEdit = useCallback(() => {
    router.push(`/ko/accounting/bad-debt-collection/${recordId}?mode=edit`);
  }, [router, recordId]);

  const handleCancel = useCallback(() => {
    if (isNewMode) {
      router.push('/ko/accounting/bad-debt-collection');
    } else {
      router.push(`/ko/accounting/bad-debt-collection/${recordId}?mode=view`);
    }
  }, [router, recordId, isNewMode]);

  // 저장 핸들러
  const handleSave = useCallback(() => {
    setShowSaveDialog(true);
  }, []);

  const handleConfirmSave = useCallback(async () => {
    setIsLoading(true);
    setShowSaveDialog(false);

    try {
      if (isNewMode) {
        const result = await createBadDebt(formData);
        if (result.success) {
          toast.success('악성채권이 등록되었습니다.');
          router.push('/ko/accounting/bad-debt-collection');
        } else {
          toast.error(result.error || '등록에 실패했습니다.');
        }
      } else {
        const result = await updateBadDebt(recordId!, formData);
        if (result.success) {
          toast.success('악성채권이 수정되었습니다.');
          router.push(`/ko/accounting/bad-debt-collection/${recordId}?mode=view`);
        } else {
          toast.error(result.error || '수정에 실패했습니다.');
        }
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('저장 오류:', error);
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [formData, router, recordId, isNewMode]);

  // 삭제 핸들러
  const handleDelete = useCallback(() => {
    setShowDeleteDialog(true);
  }, []);

  const handleConfirmDelete = useCallback(async () => {
    if (!recordId) return;

    setIsLoading(true);
    setShowDeleteDialog(false);

    try {
      const result = await deleteBadDebt(recordId);
      if (result.success) {
        toast.success('악성채권이 삭제되었습니다.');
        router.push('/ko/accounting/bad-debt-collection');
      } else {
        toast.error(result.error || '삭제에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('삭제 오류:', error);
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [router, recordId]);

  // 메모 추가 핸들러
  const handleAddMemo = useCallback(async () => {
    if (!newMemo.trim()) return;

    // 신규 등록 모드에서는 로컬 상태만 변경
    if (isNewMode || !recordId) {
      const now = new Date();
      const memo: BadDebtMemo = {
        id: String(Date.now()),
        content: newMemo,
        createdAt: now.toISOString(),
        createdBy: '사용자',
      };
      setFormData(prev => ({
        ...prev,
        memos: [...prev.memos, memo],
      }));
      setNewMemo('');
      return;
    }

    // 기존 레코드 편집 시 API 호출
    setIsLoading(true);
    try {
      const result = await addBadDebtMemo(recordId, newMemo);
      if (result.success && result.data) {
        setFormData(prev => ({
          ...prev,
          memos: [...prev.memos, result.data!],
        }));
        setNewMemo('');
        toast.success('메모가 추가되었습니다.');
      } else {
        toast.error(result.error || '메모 추가에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('메모 추가 오류:', error);
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [newMemo, isNewMode, recordId]);

  // 메모 삭제 핸들러
  const handleDeleteMemo = useCallback(async (memoId: string) => {
    // 신규 등록 모드에서는 로컬 상태만 변경
    if (isNewMode || !recordId) {
      setFormData(prev => ({
        ...prev,
        memos: prev.memos.filter(m => m.id !== memoId),
      }));
      return;
    }

    // 기존 레코드 편집 시 API 호출
    setIsLoading(true);
    try {
      const result = await deleteBadDebtMemo(recordId, memoId);
      if (result.success) {
        setFormData(prev => ({
          ...prev,
          memos: prev.memos.filter(m => m.id !== memoId),
        }));
        toast.success('메모가 삭제되었습니다.');
      } else {
        toast.error(result.error || '메모 삭제에 실패했습니다.');
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('메모 삭제 오류:', error);
      toast.error('서버 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [isNewMode, recordId]);

  // 담당자 변경 핸들러
  const handleManagerChange = useCallback((managerId: string) => {
    const manager = MANAGER_OPTIONS.find(m => m.id === managerId) || null;
    setFormData(prev => ({
      ...prev,
      assignedManagerId: managerId,
      assignedManager: manager,
    }));
  }, []);

  // 수취 어음 현황 버튼
  const handleBillStatus = useCallback(() => {
    router.push(`/ko/accounting/bills?vendorId=${formData.vendorId}&type=received`);
  }, [router, formData.vendorId]);

  // 거래처 미수금 현황 버튼
  const handleReceivablesStatus = useCallback(() => {
    router.push(`/ko/accounting/receivables-status?highlight=${formData.vendorId}`);
  }, [router, formData.vendorId]);

  // 파일 다운로드 핸들러
  const handleFileDownload = useCallback((fileName: string) => {
    console.log('파일 다운로드:', fileName);
    // TODO: 실제 다운로드 로직
  }, []);

  // 기존 파일 삭제 핸들러
  const handleDeleteExistingFile = useCallback((fileId: string) => {
    setFormData(prev => ({
      ...prev,
      files: prev.files.filter(f => f.id !== fileId),
    }));
  }, []);

  // 추가 서류 추가 핸들러
  const handleAddAdditionalFile = useCallback((file: File) => {
    setNewAdditionalFiles(prev => [...prev, file]);
  }, []);

  // 추가 서류 (새 파일) 삭제 핸들러
  const handleRemoveNewAdditionalFile = useCallback((index: number) => {
    setNewAdditionalFiles(prev => prev.filter((_, i) => i !== index));
  }, []);

  // 동적 config (mode에 따라 title 변경)
  const dynamicConfig = useMemo(() => {
    const titleMap: Record<string, string> = {
      new: '악성채권 등록',
      edit: '악성채권 수정',
      view: '악성채권 추심관리 상세',
    };
    return {
      ...badDebtConfig,
      title: titleMap[mode] || badDebtConfig.title,
    };
  }, [mode]);

  // 커스텀 헤더 액션 (저장 확인 다이얼로그 패턴 유지)
  const customHeaderActions = useMemo(() => {
    if (isViewMode) {
      return (
        <>
          {canDelete && (
            <Button variant="outline" className="text-red-500 border-red-200 hover:bg-red-50" onClick={handleDelete} disabled={isLoading}>
              {isLoading ? '처리중...' : '삭제'}
            </Button>
          )}
          {canUpdate && (
            <Button onClick={handleEdit} className="bg-blue-500 hover:bg-blue-600" disabled={isLoading}>
              수정
            </Button>
          )}
        </>
      );
    }
    return (
      <>
        <Button variant="outline" onClick={handleCancel} disabled={isLoading}>
          취소
        </Button>
        <Button onClick={handleSave} className="bg-blue-500 hover:bg-blue-600" disabled={isLoading}>
          {isLoading ? '처리중...' : (isNewMode ? '등록' : '저장')}
        </Button>
      </>
    );
  }, [isViewMode, isNewMode, isLoading, handleDelete, handleEdit, handleCancel, handleSave, mode, canUpdate, canDelete]);

  // 입력 필드 렌더링 헬퍼
  const renderField = (
    label: string,
    field: string,
    value: string | number,
    options?: {
      required?: boolean;
      type?: 'text' | 'tel' | 'email' | 'number' | 'phone' | 'businessNumber';
      placeholder?: string;
      disabled?: boolean;
    }
  ) => {
    const { required, type = 'text', placeholder, disabled } = options || {};
    const isDisabled = isViewMode || disabled;
    const stringValue = value !== null && value !== undefined ? String(value) : '';

    const renderInput = () => {
      switch (type) {
        case 'phone':
          return (
            <PhoneInput
              value={stringValue}
              onChange={(v) => handleChange(field, v)}
              placeholder={placeholder}
              disabled={isDisabled}
              className="bg-white"
            />
          );
        case 'businessNumber':
          return (
            <BusinessNumberInput
              value={stringValue}
              onChange={(v) => handleChange(field, v)}
              placeholder={placeholder}
              disabled={isDisabled}
              showValidation
              className="bg-white"
            />
          );
        default:
          return (
            <Input
              type={type === 'tel' ? 'tel' : type}
              value={value}
              onChange={(e) => handleChange(field, type === 'number' ? Number(e.target.value) : e.target.value)}
              placeholder={placeholder}
              disabled={isDisabled}
              className="bg-white"
            />
          );
      }
    };

    return (
      <div className="space-y-2">
        <Label className="text-sm font-medium text-gray-700">
          {label} {required && <span className="text-red-500">*</span>}
        </Label>
        {renderInput()}
      </div>
    );
  };

  // 폼 콘텐츠 렌더링
  const renderFormContent = useCallback(() => (
    <div className="space-y-6">
        {/* 기본 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">기본 정보</CardTitle>
          </CardHeader>
          <CardContent className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {renderField('사업자등록번호', 'businessNumber', formData.businessNumber, { required: true, type: 'businessNumber', placeholder: '000-00-00000', disabled: true })}
            {renderField('거래처 코드', 'vendorCode', formData.vendorCode, { disabled: true })}
            {renderField('거래처명', 'vendorName', formData.vendorName, { required: true })}
            {renderField('대표자명', 'representativeName', formData.representativeName)}
            {/* 거래처 유형 - 읽기 전용 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">거래처 유형</Label>
              <Input
                value={VENDOR_TYPE_LABELS[formData.vendorType] || '매출매입'}
                disabled
                className="bg-gray-50"
              />
            </div>
            {/* 악성채권 등록 토글 + 업태/업종 */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <Label className="text-sm font-medium text-gray-700">악성채권 등록</Label>
                  <Switch
                    checked={formData.settingToggle}
                    onCheckedChange={(checked) => handleChange('settingToggle', checked)}
                    disabled={isViewMode}
                    className="data-[state=checked]:bg-orange-500"
                  />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-2">
                <Input
                  value={formData.businessType}
                  onChange={(e) => handleChange('businessType', e.target.value)}
                  placeholder="업태"
                  disabled={isViewMode}
                  className="bg-white"
                />
                <Input
                  value={formData.businessCategory}
                  onChange={(e) => handleChange('businessCategory', e.target.value)}
                  placeholder="업종"
                  disabled={isViewMode}
                  className="bg-white"
                />
              </div>
            </div>
          </CardContent>
        </Card>

        {/* 연락처 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">연락처 정보</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* 주소 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">주소</Label>
              <div className="flex gap-2">
                <Input
                  value={formData.zipCode}
                  onChange={(e) => handleChange('zipCode', e.target.value)}
                  placeholder="우편번호"
                  disabled={isViewMode}
                  className="w-[120px] bg-white"
                />
                <Button variant="outline" disabled={isViewMode} onClick={openPostcode} className="shrink-0">
                  우편번호 찾기
                </Button>
              </div>
              <Input
                value={formData.address1}
                onChange={(e) => handleChange('address1', e.target.value)}
                placeholder="기본주소"
                disabled={isViewMode}
                className="bg-white"
              />
              <Input
                value={formData.address2}
                onChange={(e) => handleChange('address2', e.target.value)}
                placeholder="상세주소"
                disabled={isViewMode}
                className="bg-white"
              />
            </div>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              {renderField('전화번호', 'phone', formData.phone, { type: 'phone', placeholder: '02-0000-0000' })}
              {renderField('모바일', 'mobile', formData.mobile, { type: 'phone', placeholder: '010-0000-0000' })}
              {renderField('팩스', 'fax', formData.fax, { type: 'phone', placeholder: '02-0000-0000' })}
              {renderField('이메일', 'email', formData.email, { type: 'email' })}
            </div>
          </CardContent>
        </Card>

        {/* 담당자 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">담당자 정보</CardTitle>
          </CardHeader>
          <CardContent className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {renderField('담당자명', 'contactName', formData.contactName)}
            {renderField('담당자 전화', 'contactPhone', formData.contactPhone, { type: 'phone' })}
            {renderField('시스템 관리자', 'systemManager', formData.systemManager, { disabled: true })}
          </CardContent>
        </Card>

        {/* 필요 서류 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">필요 서류</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* 사업자등록증 */}
            <div>
              <Label className="text-sm font-medium text-gray-700">사업자등록증</Label>
              <div className="mt-1.5">
                {/* 기존 파일 있는 경우 */}
                {formData.files.find(f => f.type === 'businessRegistration') && !newBusinessRegistrationFile ? (
                  <div className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-gray-50 rounded-md border text-sm">
                      <FileText className="h-4 w-4 text-blue-600 shrink-0" />
                      <span className="truncate">{formData.files.find(f => f.type === 'businessRegistration')?.name}</span>
                    </div>
                    <button
                      type="button"
                      onClick={() => handleFileDownload(formData.files.find(f => f.type === 'businessRegistration')?.name || '')}
                      className="inline-flex items-center justify-center h-9 w-9 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground text-blue-600"
                      title="다운로드"
                    >
                      <Download className="h-4 w-4" />
                    </button>
                    {!isViewMode && (
                      <>
                        <label
                          htmlFor="business_registration_file"
                          className="inline-flex items-center justify-center h-9 w-9 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground text-gray-600 cursor-pointer"
                          title="수정"
                        >
                          <Upload className="h-4 w-4" />
                          <input
                            id="business_registration_file"
                            type="file"
                            accept=".pdf,.jpg,.jpeg,.png"
                            onChange={(e) => setNewBusinessRegistrationFile(e.target.files?.[0] || null)}
                            className="hidden"
                          />
                        </label>
                        <Button
                          type="button"
                          variant="outline"
                          size="icon"
                          onClick={() => handleDeleteExistingFile(formData.files.find(f => f.type === 'businessRegistration')?.id || '')}
                          className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                          title="삭제"
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </>
                    )}
                  </div>
                ) : newBusinessRegistrationFile ? (
                  /* 새 파일 선택된 경우 */
                  <div className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-blue-50 rounded-md border border-blue-200 text-sm">
                      <FileText className="h-4 w-4 text-blue-600 shrink-0" />
                      <span className="truncate">{newBusinessRegistrationFile.name}</span>
                      <span className="text-xs text-blue-500">(새 파일)</span>
                    </div>
                    <Button
                      type="button"
                      variant="outline"
                      size="icon"
                      onClick={() => setNewBusinessRegistrationFile(null)}
                      className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                      title="취소"
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </div>
                ) : (
                  /* 파일 없는 경우 */
                  <div className="flex items-center gap-2">
                    <label
                      htmlFor="business_registration_file_new"
                      className={`flex items-center gap-2 flex-1 px-3 py-2 bg-gray-50 rounded-md border text-sm ${isViewMode ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:bg-gray-100'} transition-colors`}
                    >
                      <Upload className="h-4 w-4 text-gray-500 shrink-0" />
                      <span className="text-gray-500">파일을 선택하세요</span>
                    </label>
                    {!isViewMode && (
                      <input
                        id="business_registration_file_new"
                        type="file"
                        accept=".pdf,.jpg,.jpeg,.png"
                        onChange={(e) => setNewBusinessRegistrationFile(e.target.files?.[0] || null)}
                        className="hidden"
                      />
                    )}
                  </div>
                )}
              </div>
            </div>

            {/* 세금계산서 */}
            <div>
              <Label className="text-sm font-medium text-gray-700">세금계산서</Label>
              <div className="mt-1.5">
                {/* 기존 파일 있는 경우 */}
                {formData.files.find(f => f.type === 'taxInvoice') && !newTaxInvoiceFile ? (
                  <div className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-gray-50 rounded-md border text-sm">
                      <FileText className="h-4 w-4 text-green-600 shrink-0" />
                      <span className="truncate">{formData.files.find(f => f.type === 'taxInvoice')?.name}</span>
                    </div>
                    <button
                      type="button"
                      onClick={() => handleFileDownload(formData.files.find(f => f.type === 'taxInvoice')?.name || '')}
                      className="inline-flex items-center justify-center h-9 w-9 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground text-green-600"
                      title="다운로드"
                    >
                      <Download className="h-4 w-4" />
                    </button>
                    {!isViewMode && (
                      <>
                        <label
                          htmlFor="tax_invoice_file"
                          className="inline-flex items-center justify-center h-9 w-9 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground text-gray-600 cursor-pointer"
                          title="수정"
                        >
                          <Upload className="h-4 w-4" />
                          <input
                            id="tax_invoice_file"
                            type="file"
                            accept=".pdf,.jpg,.jpeg,.png"
                            onChange={(e) => setNewTaxInvoiceFile(e.target.files?.[0] || null)}
                            className="hidden"
                          />
                        </label>
                        <Button
                          type="button"
                          variant="outline"
                          size="icon"
                          onClick={() => handleDeleteExistingFile(formData.files.find(f => f.type === 'taxInvoice')?.id || '')}
                          className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                          title="삭제"
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </>
                    )}
                  </div>
                ) : newTaxInvoiceFile ? (
                  /* 새 파일 선택된 경우 */
                  <div className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-green-50 rounded-md border border-green-200 text-sm">
                      <FileText className="h-4 w-4 text-green-600 shrink-0" />
                      <span className="truncate">{newTaxInvoiceFile.name}</span>
                      <span className="text-xs text-green-500">(새 파일)</span>
                    </div>
                    <Button
                      type="button"
                      variant="outline"
                      size="icon"
                      onClick={() => setNewTaxInvoiceFile(null)}
                      className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                      title="취소"
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </div>
                ) : (
                  /* 파일 없는 경우 */
                  <div className="flex items-center gap-2">
                    <label
                      htmlFor="tax_invoice_file_new"
                      className={`flex items-center gap-2 flex-1 px-3 py-2 bg-gray-50 rounded-md border text-sm ${isViewMode ? 'cursor-not-allowed opacity-50' : 'cursor-pointer hover:bg-gray-100'} transition-colors`}
                    >
                      <Upload className="h-4 w-4 text-gray-500 shrink-0" />
                      <span className="text-gray-500">파일을 선택하세요</span>
                    </label>
                    {!isViewMode && (
                      <input
                        id="tax_invoice_file_new"
                        type="file"
                        accept=".pdf,.jpg,.jpeg,.png"
                        onChange={(e) => setNewTaxInvoiceFile(e.target.files?.[0] || null)}
                        className="hidden"
                      />
                    )}
                  </div>
                )}
              </div>
            </div>

            {/* 추가 서류 */}
            <div>
              <div className="flex items-center justify-between mb-1.5">
                <Label className="text-sm font-medium text-gray-700">추가 서류</Label>
                {!isViewMode && (
                  <label
                    htmlFor="additional_file"
                    className="inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium text-orange-600 border border-orange-200 rounded-md cursor-pointer hover:bg-orange-50 transition-colors"
                  >
                    <Plus className="h-4 w-4" />
                    추가
                    <input
                      id="additional_file"
                      type="file"
                      accept=".pdf,.jpg,.jpeg,.png"
                      onChange={(e) => {
                        const file = e.target.files?.[0];
                        if (file) {
                          handleAddAdditionalFile(file);
                          e.target.value = '';
                        }
                      }}
                      className="hidden"
                    />
                  </label>
                )}
              </div>
              <div className="space-y-2">
                {/* 기존 추가 서류 */}
                {formData.files.filter(f => f.type === 'additional').map((file) => (
                  <div key={file.id} className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-gray-50 rounded-md border text-sm">
                      <FileText className="h-4 w-4 text-gray-600 shrink-0" />
                      <span className="truncate">{file.name}</span>
                    </div>
                    <button
                      type="button"
                      onClick={() => handleFileDownload(file.name)}
                      className="inline-flex items-center justify-center h-9 w-9 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground text-gray-600"
                      title="다운로드"
                    >
                      <Download className="h-4 w-4" />
                    </button>
                    {!isViewMode && (
                      <Button
                        type="button"
                        variant="outline"
                        size="icon"
                        onClick={() => handleDeleteExistingFile(file.id)}
                        className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                        title="삭제"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                ))}
                {/* 새로 추가된 파일 */}
                {newAdditionalFiles.map((file, index) => (
                  <div key={`new-${index}`} className="flex items-center gap-2">
                    <div className="flex items-center gap-2 flex-1 px-3 py-2 bg-orange-50 rounded-md border border-orange-200 text-sm">
                      <FileText className="h-4 w-4 text-orange-600 shrink-0" />
                      <span className="truncate">{file.name}</span>
                      <span className="text-xs text-orange-500">(새 파일)</span>
                    </div>
                    <Button
                      type="button"
                      variant="outline"
                      size="icon"
                      onClick={() => handleRemoveNewAdditionalFile(index)}
                      className="h-9 w-9 text-red-500 hover:text-red-700 hover:bg-red-50"
                      title="취소"
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </div>
                ))}
                {/* 파일 없는 경우 안내 */}
                {formData.files.filter(f => f.type === 'additional').length === 0 && newAdditionalFiles.length === 0 && (
                  <div className="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-md border text-sm text-gray-400">
                    <FileText className="h-4 w-4 shrink-0" />
                    <span>추가 서류가 없습니다</span>
                  </div>
                )}
              </div>
            </div>
          </CardContent>
        </Card>

        {/* 악성 채권 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">악성 채권 정보</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              {/* 미수금 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">미수금</Label>
                <CurrencyInput
                  value={formData.debtAmount}
                  onChange={(value) => handleChange('debtAmount', value ?? 0)}
                  disabled={isViewMode}
                  className="bg-white"
                />
              </div>
              {/* 상태 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">상태</Label>
                <Select
                  value={formData.status}
                  onValueChange={(val) => handleChange('status', val as CollectionStatus)}
                  disabled={isViewMode}
                >
                  <SelectTrigger className="bg-white">
                    <SelectValue placeholder="선택" />
                  </SelectTrigger>
                  <SelectContent>
                    {STATUS_SELECT_OPTIONS.map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              {/* 연체일수 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">연체일수</Label>
                <div className="flex items-center gap-2">
                  <NumberInput
                    value={formData.overdueDays}
                    onChange={(value) => handleChange('overdueDays', value ?? 0)}
                    disabled={isViewMode}
                    className="bg-white w-[100px]"
                    min={0}
                  />
                  <span className="text-sm text-gray-500">일</span>
                </div>
              </div>
              {/* 본사 담당자 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">본사 담당자</Label>
                <Select
                  value={formData.assignedManagerId || ''}
                  onValueChange={handleManagerChange}
                  disabled={isViewMode}
                >
                  <SelectTrigger className="bg-white">
                    <SelectValue placeholder="담당자 선택">
                      {formData.assignedManager && (
                        <span>{formData.assignedManager.departmentName} {formData.assignedManager.name} {formData.assignedManager.position}님 {formData.assignedManager.phone}</span>
                      )}
                    </SelectValue>
                  </SelectTrigger>
                  <SelectContent>
                    {MANAGER_OPTIONS.map((manager) => (
                      <SelectItem key={manager.id} value={manager.id}>
                        {manager.departmentName} {manager.name} {manager.position}님 {manager.phone}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              {/* 악성채권 발생일 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">악성채권 발생일</Label>
                <Input
                  type="date"
                  value={formData.occurrenceDate}
                  onChange={(e) => handleChange('occurrenceDate', e.target.value)}
                  disabled={isViewMode}
                  className="bg-white"
                />
              </div>
              {/* 악성채권 종료일 */}
              <div className="space-y-2">
                <Label className="text-sm font-medium text-gray-700">악성채권 종료일</Label>
                <Input
                  type="date"
                  value={formData.endDate || ''}
                  onChange={(e) => handleChange('endDate', e.target.value || null)}
                  disabled={isViewMode}
                  className="bg-white"
                  placeholder="-"
                />
              </div>
            </div>
            {/* 연동 버튼 */}
            <div className="flex gap-2 pt-4">
              <Button
                variant="outline"
                onClick={handleBillStatus}
                className="border-red-200 text-red-600 hover:bg-red-50"
              >
                <Receipt className="h-4 w-4 mr-2" />
                수취 어음 현황
              </Button>
              <Button
                variant="outline"
                onClick={handleReceivablesStatus}
                className="border-red-200 text-red-600 hover:bg-red-50"
              >
                <CreditCard className="h-4 w-4 mr-2" />
                거래처 미수금 현황
              </Button>
            </div>
          </CardContent>
        </Card>

        {/* 메모 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">메모</CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* 메모 입력 */}
            {!isViewMode && (
              <div className="flex gap-2">
                <Textarea
                  value={newMemo}
                  onChange={(e) => setNewMemo(e.target.value)}
                  placeholder="메모를 입력하세요..."
                  className="flex-1 bg-white"
                  rows={2}
                />
                <Button onClick={handleAddMemo} className="bg-blue-500 hover:bg-blue-600 self-end">
                  <Plus className="h-4 w-4 mr-1" />
                  추가
                </Button>
              </div>
            )}
            {/* 메모 리스트 */}
            {formData.memos.length > 0 ? (
              <div className="space-y-2">
                {formData.memos.map((memo) => (
                  <div
                    key={memo.id}
                    className="flex items-start justify-between p-3 bg-gray-50 rounded-lg"
                  >
                    <p className="text-sm text-gray-700 flex-1">{memo.content}</p>
                    {!isViewMode && (
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-6 w-6 text-gray-400 hover:text-red-500"
                        onClick={() => handleDeleteMemo(memo.id)}
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                ))}
              </div>
            ) : (
              <p className="text-sm text-gray-500 text-center py-4">등록된 메모가 없습니다.</p>
            )}
          </CardContent>
        </Card>
      </div>
  ), [
    formData,
    isViewMode,
    isNewMode,
    newMemo,
    newBusinessRegistrationFile,
    newTaxInvoiceFile,
    newAdditionalFiles,
    handleChange,
    handleAddMemo,
    handleDeleteMemo,
    handleManagerChange,
    handleBillStatus,
    handleReceivablesStatus,
    handleFileDownload,
    handleDeleteExistingFile,
    handleAddAdditionalFile,
    handleRemoveNewAdditionalFile,
    openPostcode,
    renderField,
  ]);

  return (
    <>
      <IntegratedDetailTemplate
        config={dynamicConfig}
        mode={isNewMode ? 'create' : (isViewMode ? 'view' : 'edit')}
        initialData={formData as unknown as Record<string, unknown>}
        itemId={recordId}
        isLoading={isLoading}
        headerActions={customHeaderActions}
        renderView={() => renderFormContent()}
        renderForm={() => renderFormContent()}
      />

      {/* 삭제 확인 다이얼로그 */}
      <DeleteConfirmDialog
        open={showDeleteDialog}
        onOpenChange={setShowDeleteDialog}
        onConfirm={handleConfirmDelete}
        title="악성채권 삭제"
        description={
          <>
            &apos;{formData.vendorName}&apos;의 악성채권 기록을 삭제하시겠습니까?
            <br />
            확인 클릭 시 목록으로 이동합니다.
          </>
        }
      />

      {/* 저장 확인 다이얼로그 */}
      <SaveConfirmDialog
        open={showSaveDialog}
        onOpenChange={setShowSaveDialog}
        onConfirm={handleConfirmSave}
        description="입력한 내용을 저장하시겠습니까?"
      />
    </>
  );
}