'use client';

import { useState, useCallback, useEffect, useRef } from 'react';
import { useDaumPostcode } from '@/hooks/useDaumPostcode';
import { useRouter } from 'next/navigation';
import { Plus, Trash2, Upload, FileText, X, CheckCircle2 } from 'lucide-react';
import { toast } from 'sonner';
import { getClientById, createClient, updateClient, deleteClient } from './actions';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { vendorConfig } from './vendorConfig';
import { CreditAnalysisModal, MOCK_CREDIT_DATA } from './CreditAnalysisModal';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
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 { PhoneInput } from '@/components/ui/phone-input';
import { BusinessNumberInput } from '@/components/ui/business-number-input';
import { CurrencyInput } from '@/components/ui/currency-input';
import { NumberInput } from '@/components/ui/number-input';
import type {
  Vendor,
  VendorMemo,
} from './types';
import {
  VENDOR_CATEGORY_SELECTOR_OPTIONS,
  VENDOR_STATUS_SELECTOR_OPTIONS,
  CREDIT_RATING_SELECTOR_OPTIONS,
  TRANSACTION_GRADE_SELECTOR_OPTIONS,
  BAD_DEBT_STATUS_SELECTOR_OPTIONS,
  PAYMENT_DAY_OPTIONS,
  BANK_OPTIONS,
} from './types';
import { getLocalDateString } from '@/lib/utils/date';

interface VendorDetailProps {
  mode: 'view' | 'edit' | 'new';
  vendorId?: string;
  /** URL 쿼리 파라미터로 전달된 모달 타입 (예: 'credit') */
  openModal?: string | null;
}

// 빈 Vendor 데이터 (신규 등록용)
const getEmptyVendor = (): Omit<Vendor, 'id' | 'createdAt' | 'updatedAt'> => ({
  vendorCode: '',
  businessNumber: '',
  vendorName: '',
  representativeName: '',
  category: 'both',
  businessType: '',
  businessCategory: '',
  zipCode: '',
  address1: '',
  address2: '',
  phone: '',
  mobile: '',
  fax: '',
  email: '',
  managerName: '',
  managerPhone: '',
  systemManager: '',
  logoUrl: '',
  purchasePaymentDay: 10,
  salesPaymentDay: 15,
  creditRating: 'AAA',
  transactionGrade: 'A',
  taxInvoiceEmail: '',
  bankName: 'none',
  accountNumber: '',
  accountHolder: '',
  outstandingAmount: 0,
  overdueAmount: 0,
  overdueDays: 0,
  unpaidAmount: 0,
  badDebtAmount: 0,
  badDebtStatus: 'none',
  overdueToggle: false,
  badDebtToggle: false,
  isActive: true,
  memos: [],
});

export function VendorDetail({ mode, vendorId, openModal }: VendorDetailProps) {
  const router = useRouter();
  const isViewMode = mode === 'view';
  const isNewMode = mode === 'new';

  // IntegratedDetailTemplate 모드 변환
  const templateMode = isNewMode ? 'create' : mode;

  // 폼 데이터
  const [formData, setFormData] = useState<Omit<Vendor, 'id' | 'createdAt' | 'updatedAt'> | Vendor>(getEmptyVendor());

  // 로딩 상태
  const [isLoading, setIsLoading] = useState(false);

  // API에서 데이터 로드 (view/edit 모드)
  useEffect(() => {
    const loadVendor = async () => {
      if (!vendorId || isNewMode) return;

      setIsLoading(true);
      try {
        const data = await getClientById(vendorId);
        if (data) {
          setFormData(data);
        } else {
          toast.error('거래처 정보를 불러오는데 실패했습니다.');
        }
      } catch {
        toast.error('서버 오류가 발생했습니다.');
      } finally {
        setIsLoading(false);
      }
    };

    loadVendor();
  }, [vendorId, isNewMode]);

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

  // Validation 에러 상태
  const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});

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

  // 사업자등록증 파일
  const MAX_FILES = 5;
  const MAX_FILE_SIZE_MB = 5;
  const ACCEPT_TYPES = '.pdf,.jpg,.jpeg,.png,.gif,.bmp,.tiff';
  const DANGEROUS_EXTENSIONS = ['.exe', '.bat', '.cmd', '.sh', '.js', '.jsx', '.ts', '.tsx', '.mjs', '.jar', '.app', '.scr', '.vbs', '.ps1', '.htm', '.html', '.svg', '.swf'];
  const [businessFiles, setBusinessFiles] = useState<File[]>([]);
  const [fileError, setFileError] = useState<string | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // 신용분석 모달
  const [isCreditModalOpen, setIsCreditModalOpen] = useState(false);

  // URL 쿼리 파라미터로 모달 자동 오픈 (알람에서 접근 시)
  useEffect(() => {
    if (openModal === 'credit' && !isLoading) {
      setIsCreditModalOpen(true);
    }
  }, [openModal, isLoading]);

  // Validation 함수
  const validateForm = useCallback(() => {
    const errors: Record<string, string> = {};

    if (!formData.businessNumber?.trim()) {
      errors.businessNumber = '사업자등록번호를 입력해주세요';
    }
    if (!formData.vendorName?.trim()) {
      errors.vendorName = '거래처명을 입력해주세요';
    }
    if (!formData.category) {
      errors.category = '거래처 유형을 선택해주세요';
    }

    setValidationErrors(errors);
    if (Object.keys(errors).length > 0) {
      const firstError = Object.values(errors)[0];
      toast.error(firstError);
    }
    return Object.keys(errors).length === 0;
  }, [formData.businessNumber, formData.vendorName, formData.category]);

  // 필드 변경 핸들러
  const handleChange = useCallback((field: string, value: string | number | boolean) => {
    setFormData(prev => ({ ...prev, [field]: value }));
    // 에러 클리어
    if (validationErrors[field]) {
      setValidationErrors(prev => {
        const next = { ...prev };
        delete next[field];
        return next;
      });
    }
  }, [validationErrors]);

  // 파일 검증 및 추가
  const validateAndAddFiles = useCallback((files: FileList | File[]) => {
    setFileError(null);
    const fileArray = Array.from(files);

    if (businessFiles.length + fileArray.length > MAX_FILES) {
      setFileError(`최대 ${MAX_FILES}건까지 업로드 가능합니다.`);
      return;
    }

    for (const file of fileArray) {
      const ext = '.' + (file.name.split('.').pop()?.toLowerCase() || '');
      if (DANGEROUS_EXTENSIONS.includes(ext)) {
        setFileError('보안상 허용되지 않는 파일 형식입니다.');
        return;
      }
      const allowedExts = ACCEPT_TYPES.split(',').map(e => e.trim().toLowerCase());
      if (!allowedExts.some(allowed => ext === allowed)) {
        setFileError(`허용되지 않은 파일 형식입니다. (${ACCEPT_TYPES})`);
        return;
      }
      if (file.size / (1024 * 1024) > MAX_FILE_SIZE_MB) {
        setFileError(`파일 크기는 ${MAX_FILE_SIZE_MB}MB 이하여야 합니다.`);
        return;
      }
    }

    setBusinessFiles(prev => [...prev, ...fileArray]);
  }, [businessFiles.length]);

  const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      validateAndAddFiles(e.target.files);
      e.target.value = '';
    }
  }, [validateAndAddFiles]);

  const handleRemoveFile = useCallback((index: number) => {
    setBusinessFiles(prev => prev.filter((_, i) => i !== index));
    setFileError(null);
  }, []);

  // 메모 추가 핸들러
  const handleAddMemo = useCallback(() => {
    if (!newMemo.trim()) return;
    const now = new Date();
    const dateStr = getLocalDateString(now);
    const timeStr = now.toTimeString().slice(0, 5);
    const memo: VendorMemo = {
      id: String(Date.now()),
      content: `${dateStr} ${timeStr} [사용자] ${newMemo}`,
      createdAt: now.toISOString(),
    };
    setFormData(prev => ({
      ...prev,
      memos: [...prev.memos, memo],
    }));
    setNewMemo('');
  }, [newMemo]);

  // 메모 삭제 핸들러
  const handleDeleteMemo = useCallback((memoId: string) => {
    setFormData(prev => ({
      ...prev,
      memos: prev.memos.filter(m => m.id !== memoId),
    }));
  }, []);

  // 저장 핸들러 (IntegratedDetailTemplate용)
  const handleSubmit = useCallback(async () => {
    if (!validateForm()) {
      return { success: false, error: '입력 내용을 확인해주세요.' };
    }

    try {
      const result = isNewMode
        ? await createClient(formData)
        : await updateClient(vendorId!, formData);

      if (result.success) {
        router.refresh();
        return { success: true };
      } else {
        return { success: false, error: result.error || '저장에 실패했습니다.' };
      }
    } catch {
      return { success: false, error: '서버 오류가 발생했습니다.' };
    }
  }, [formData, validateForm, isNewMode, vendorId, router]);

  // 삭제 핸들러 (IntegratedDetailTemplate용)
  const handleDelete = useCallback(async () => {
    if (!vendorId) return { success: false, error: 'ID가 없습니다.' };

    try {
      const result = await deleteClient(vendorId);
      if (result.success) {
        router.refresh();
        return { success: true };
      } else {
        return { success: false, error: result.error || '삭제에 실패했습니다.' };
      }
    } catch {
      return { success: false, error: '서버 오류가 발생했습니다.' };
    }
  }, [vendorId, router]);

  // 입력 필드 렌더링 헬퍼
  const renderField = (
    label: string,
    field: string,
    value: string | number,
    options?: {
      required?: boolean;
      type?: 'text' | 'tel' | 'email' | 'number';
      placeholder?: string;
      disabled?: boolean;
    }
  ) => {
    const { required, type = 'text', placeholder, disabled } = options || {};
    return (
      <div className="space-y-2">
        <Label className="text-sm font-medium text-gray-700">
          {label} {required && <span className="text-red-500">*</span>}
        </Label>
        <Input
          type={type}
          value={value}
          onChange={(e) => handleChange(field, type === 'number' ? Number(e.target.value) : e.target.value)}
          placeholder={placeholder}
          disabled={isViewMode || disabled}
          className={`bg-white ${validationErrors[field] ? 'border-red-500' : ''}`}
        />
        {validationErrors[field] && <p className="text-sm text-red-500">{validationErrors[field]}</p>}
      </div>
    );
  };

  // 셀렉트 필드 렌더링 헬퍼
  const renderSelectField = (
    label: string,
    field: string,
    value: string,
    options: { value: string; label: string }[],
    required?: boolean
  ) => {
    return (
      <div className="space-y-2">
        <Label className="text-sm font-medium text-gray-700">
          {label} {required && <span className="text-red-500">*</span>}
        </Label>
        <Select
          value={value}
          onValueChange={(val) => handleChange(field, val)}
          disabled={isViewMode}
        >
          <SelectTrigger className={`bg-white ${validationErrors[field] ? 'border-red-500' : ''}`}>
            <SelectValue placeholder="선택" />
          </SelectTrigger>
          <SelectContent>
            {options.map((option) => (
              <SelectItem key={option.value} value={option.value}>
                {option.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        {validationErrors[field] && <p className="text-sm text-red-500">{validationErrors[field]}</p>}
      </div>
    );
  };

  // 폼 콘텐츠 렌더링 (View/Edit 공통)
  const renderFormContent = () => (
    <div className="space-y-6">
      {/* 기본 정보 */}
      <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>
            <input
              ref={fileInputRef}
              type="file"
              accept={ACCEPT_TYPES}
              multiple
              onChange={handleFileInputChange}
              className="hidden"
            />

            {/* 업로드된 파일 목록 */}
            {businessFiles.length > 0 && (
              <div className="space-y-2">
                {businessFiles.map((file, idx) => (
                  <div
                    key={`${file.name}-${idx}`}
                    className="flex items-center justify-between p-2.5 bg-gray-50 rounded-lg border"
                  >
                    <div className="flex items-center gap-2 min-w-0">
                      <FileText className="h-5 w-5 text-primary shrink-0" />
                      <div className="min-w-0">
                        <p className="text-sm font-medium truncate">{file.name}</p>
                        <p className="text-xs text-muted-foreground">
                          {(file.size / 1024).toFixed(1)} KB
                        </p>
                      </div>
                      <CheckCircle2 className="h-4 w-4 text-green-500 shrink-0" />
                    </div>
                    {!isViewMode && (
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-7 w-7 shrink-0 text-gray-400 hover:text-red-500"
                        onClick={() => handleRemoveFile(idx)}
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                ))}
              </div>
            )}

            {/* 드래그앤드롭 / 클릭 업로드 영역 */}
            {!isViewMode && businessFiles.length < MAX_FILES && (
              <div
                onDragEnter={(e) => { e.preventDefault(); e.stopPropagation(); setIsDragging(true); }}
                onDragLeave={(e) => { e.preventDefault(); e.stopPropagation(); setIsDragging(false); }}
                onDragOver={(e) => { e.preventDefault(); e.stopPropagation(); }}
                onDrop={(e) => {
                  e.preventDefault(); e.stopPropagation(); setIsDragging(false);
                  if (e.dataTransfer.files) validateAndAddFiles(e.dataTransfer.files);
                }}
                onClick={() => fileInputRef.current?.click()}
                className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
                  isDragging ? 'border-primary bg-primary/5' : 'border-gray-300 hover:border-primary/50'
                }`}
              >
                <Upload className="h-8 w-8 mx-auto text-gray-400 mb-2" />
                <p className="text-sm text-gray-500">클릭하여 파일을 올리거나, 드래그로 파일을 올립니다</p>
                <p className="text-xs text-gray-400 mt-1">
                  PDF, 이미지 파일 / 최대 {MAX_FILES}건, 1건당 {MAX_FILE_SIZE_MB}MB 이하
                  {businessFiles.length > 0 && ` (${businessFiles.length}/${MAX_FILES})`}
                </p>
              </div>
            )}

            {/* view 모드에서 파일 없을 때 */}
            {isViewMode && businessFiles.length === 0 && (
              <p className="text-sm text-muted-foreground py-3">등록된 파일이 없습니다.</p>
            )}

            {/* 에러 메시지 */}
            {fileError && (
              <p className="text-sm text-red-500">{fileError}</p>
            )}
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {/* 사업자등록번호 - BusinessNumberInput 사용 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">
                사업자등록번호 <span className="text-red-500">*</span>
              </Label>
              <BusinessNumberInput
                value={formData.businessNumber}
                onChange={(value) => handleChange('businessNumber', value)}
                placeholder="000-00-00000"
                disabled={isViewMode}
                showValidation={!isViewMode}
                error={!!validationErrors.businessNumber}
              />
              {validationErrors.businessNumber && <p className="text-sm text-red-500">{validationErrors.businessNumber}</p>}
            </div>
            {renderField('거래처코드', 'vendorCode', formData.vendorCode, { placeholder: '자동생성', disabled: true })}
            {renderField('거래처명', 'vendorName', formData.vendorName, { required: true })}
            {renderField('대표자명', 'representativeName', formData.representativeName)}
            {renderSelectField('거래처 유형', 'category', formData.category, VENDOR_CATEGORY_SELECTOR_OPTIONS, true)}
            {renderField('업태', 'businessType', formData.businessType)}
            {renderField('업종', 'businessCategory', formData.businessCategory)}
            {/* 사용 상태 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">사용</Label>
              <Select
                value={formData.isActive ? 'active' : 'inactive'}
                onValueChange={(val) => handleChange('isActive', val === 'active')}
                disabled={isViewMode}
              >
                <SelectTrigger className="bg-white">
                  <SelectValue placeholder="선택" />
                </SelectTrigger>
                <SelectContent>
                  {VENDOR_STATUS_SELECTOR_OPTIONS.map((option) => (
                    <SelectItem key={option.value} value={option.value}>
                      {option.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </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">
            {/* 전화번호 - PhoneInput 사용 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">전화번호</Label>
              <PhoneInput
                value={formData.phone}
                onChange={(value) => handleChange('phone', value)}
                placeholder="02-0000-0000"
                disabled={isViewMode}
              />
            </div>
            {/* 모바일 - PhoneInput 사용 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">모바일</Label>
              <PhoneInput
                value={formData.mobile}
                onChange={(value) => handleChange('mobile', value)}
                placeholder="010-0000-0000"
                disabled={isViewMode}
              />
            </div>
            {/* 팩스 - PhoneInput 사용 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">팩스</Label>
              <PhoneInput
                value={formData.fax}
                onChange={(value) => handleChange('fax', value)}
                placeholder="02-0000-0000"
                disabled={isViewMode}
              />
            </div>
            {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('담당자명', 'managerName', formData.managerName)}
          {/* 담당자 전화 - PhoneInput 사용 */}
          <div className="space-y-2">
            <Label className="text-sm font-medium text-gray-700">담당자 전화</Label>
            <PhoneInput
              value={formData.managerPhone}
              onChange={(value) => handleChange('managerPhone', value)}
              placeholder="010-0000-0000"
              disabled={isViewMode}
            />
          </div>
        </CardContent>
      </Card>

      {/* 신용/거래 정보 */}
      <Card>
        <CardHeader className="flex flex-row items-center justify-between">
          <CardTitle className="text-lg">신용/거래 정보</CardTitle>
          {isViewMode && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => setIsCreditModalOpen(true)}
            >
              신용정보 보기
            </Button>
          )}
        </CardHeader>
        <CardContent className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {/* 매입 결제일: 매입 또는 매입매출일 때만 표시 */}
          {(formData.category === 'purchase' || formData.category === 'both') &&
            renderSelectField('매입 결제일', 'purchasePaymentDay', String(formData.purchasePaymentDay), PAYMENT_DAY_OPTIONS)
          }
          {/* 매출 결제일: 매출 또는 매입매출일 때만 표시 */}
          {(formData.category === 'sales' || formData.category === 'both') &&
            renderSelectField('매출 결제일', 'salesPaymentDay', String(formData.salesPaymentDay), PAYMENT_DAY_OPTIONS)
          }
          {renderSelectField('신용등급', 'creditRating', formData.creditRating, CREDIT_RATING_SELECTOR_OPTIONS)}
          {renderSelectField('거래등급', 'transactionGrade', formData.transactionGrade, TRANSACTION_GRADE_SELECTOR_OPTIONS)}
          {renderField('세금계산서 이메일', 'taxInvoiceEmail', formData.taxInvoiceEmail, { type: 'email' })}
          {renderSelectField('입금계좌 은행', 'bankName', formData.bankName, BANK_OPTIONS)}
          {renderField('계좌', 'accountNumber', formData.accountNumber, { placeholder: '계좌번호' })}
          {renderField('예금주', 'accountHolder', formData.accountHolder)}
        </CardContent>
      </Card>

      {/* 추가 정보 */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">추가 정보</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            {/* 미수금 */}
            <div className="space-y-2">
              <Label className="text-sm font-medium text-gray-700">미수금</Label>
              <CurrencyInput
                value={formData.outstandingAmount}
                onChange={(value) => handleChange('outstandingAmount', value ?? 0)}
                disabled={isViewMode}
                className="bg-white"
              />
            </div>
            {/* 연체 */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label className="text-sm font-medium text-gray-700">연체</Label>
                <Switch
                  checked={formData.overdueToggle}
                  onCheckedChange={(checked) => handleChange('overdueToggle', checked)}
                  disabled={isViewMode}
                  className="data-[state=checked]:bg-orange-500"
                />
              </div>
              <NumberInput
                value={formData.overdueDays}
                onChange={(value) => handleChange('overdueDays', value ?? 0)}
                disabled={isViewMode}
                className="bg-white"
                placeholder="일"
                suffix="일"
                min={0}
              />
            </div>
            {/* 악성채권 */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label className="text-sm font-medium text-gray-700">악성채권</Label>
                <Switch
                  checked={formData.badDebtToggle}
                  onCheckedChange={(checked) => handleChange('badDebtToggle', checked)}
                  disabled={isViewMode}
                  className="data-[state=checked]:bg-orange-500"
                />
              </div>
              <Select
                value={formData.badDebtStatus}
                onValueChange={(val) => handleChange('badDebtStatus', val)}
                disabled={isViewMode}
              >
                <SelectTrigger className="bg-white">
                  <SelectValue placeholder="-" />
                </SelectTrigger>
                <SelectContent>
                  {BAD_DEBT_STATUS_SELECTOR_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>
              <CurrencyInput
                value={formData.unpaidAmount}
                onChange={(value) => handleChange('unpaidAmount', value ?? 0)}
                disabled={isViewMode}
                className="bg-white"
              />
            </div>
          </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)}
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  )}
                </div>
              ))}
            </div>
          ) : (
            <p className="text-sm text-gray-500 text-center py-4">등록된 메모가 없습니다.</p>
          )}
        </CardContent>
      </Card>
    </div>
  );

  // config 동적 수정 (등록 모드일 때 타이틀 변경)
  // IntegratedDetailTemplate: create → "{title} 등록", view → "{title}", edit → "{title} 수정"
  // view 모드에서 "거래처 상세"로 표시하려면 직접 설정 필요
  const dynamicConfig = {
    ...vendorConfig,
    title: isViewMode ? '거래처 상세' : '거래처',
    description: isNewMode ? '새로운 거래처를 등록합니다' : '거래처 상세 정보 및 신용등급을 관리합니다',
    actions: {
      ...vendorConfig.actions,
      submitLabel: isNewMode ? '등록' : '저장',
    },
  };

  return (
    <>
      <IntegratedDetailTemplate
        config={dynamicConfig}
        mode={templateMode}
        initialData={formData as unknown as Record<string, unknown>}
        itemId={vendorId}
        isLoading={isLoading}
        onSubmit={handleSubmit}
        onDelete={vendorId ? handleDelete : undefined}
        renderView={() => renderFormContent()}
        renderForm={() => renderFormContent()}
      />

      {/* 신용분석 모달 */}
      <CreditAnalysisModal
        open={isCreditModalOpen}
        onOpenChange={setIsCreditModalOpen}
        data={MOCK_CREDIT_DATA}
      />
    </>
  );
}
