"use client"

import * as React from "react"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { CalendarIcon, Loader, X, Download, AlertTriangle } from "lucide-react"
import { format } from "date-fns"
import { toast } from "sonner"
import { updateVendorInvestigationResultAction } from "../service"
import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet"
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Calendar } from "@/components/ui/calendar"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
import {
  Dropzone,
  DropzoneZone,
  DropzoneUploadIcon,
  DropzoneTitle,
  DropzoneDescription,
  DropzoneInput
} from "@/components/ui/dropzone"
import {
  FileList,
  FileListAction,
  FileListHeader,
  FileListIcon,
  FileListInfo,
  FileListItem,
  FileListName,
  FileListSize,
} from "@/components/ui/file-list"

import {
  updateVendorInvestigationResultSchema,
  type UpdateVendorInvestigationResultSchema,
} from "../validations"
import { updateVendorInvestigationAction, getInvestigationAttachments, deleteInvestigationAttachment, createVendorInvestigationAttachmentAction } from "../service"
import { VendorInvestigationsViewWithContacts } from "@/config/vendorInvestigationsColumnsConfig"
import prettyBytes from "pretty-bytes"
import { downloadFile } from "@/lib/file-download"
import { Dialog as SystemDialog, DialogContent as SystemDialogContent, DialogHeader as SystemDialogHeader, DialogTitle as SystemDialogTitle, DialogFooter as SystemDialogFooter } from "@/components/ui/dialog"

interface InvestigationResultSheetProps extends React.ComponentPropsWithoutRef<typeof Sheet> {
  investigation: VendorInvestigationsViewWithContacts | null
}

// 첨부파일 정책 정의
const getFileUploadConfig = (status: string) => {
  // 취소된 상태에서만 파일 업로드 비활성화
  if (status === "CANCELED") {
    return {
      enabled: false,
      label: "",
      description: "",
      accept: undefined,
      maxSize: 0,
      maxSizeText: ""
    }
  }

  // 모든 활성 상태에서 동일한 정책 적용
  return {
    enabled: true,
    label: "실사 관련 첨부파일",
    description: "실사와 관련된 모든 문서와 이미지를 첨부할 수 있습니다.",
    accept: {
      'application/pdf': ['.pdf'],
      'application/msword': ['.doc'],
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
      'application/vnd.ms-excel': ['.xls'],
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
      'image/*': ['.png', '.jpg', '.jpeg', '.gif'],
    },
    maxSize: 10 * 1024 * 1024, // 10MB
    maxSizeText: "10MB"
  }
}

/**
 * 실사 결과 입력 시트
 */
export function InvestigationResultSheet({
  investigation,
  ...props
}: InvestigationResultSheetProps) {
  const [isPending, startTransition] = React.useTransition()
  const [existingAttachments, setExistingAttachments] = React.useState<any[]>([])
  const [loadingAttachments, setLoadingAttachments] = React.useState(false)
  const [uploadingFiles, setUploadingFiles] = React.useState(false)

  // 불합격 안내 팝업 상태
  const [showRejectedDialog, setShowRejectedDialog] = React.useState(false)
  // 보완 세부 항목 (재실사/자료제출)
  const [supplementType, setSupplementType] = React.useState<string>("")

  // RHF + Zod
  const form = useForm<UpdateVendorInvestigationResultSchema>({
    resolver: zodResolver(updateVendorInvestigationResultSchema),
    defaultValues: {
      investigationId: investigation?.investigationId ?? 0,
      completedAt: investigation?.completedAt ?? undefined,
      requestedAt: investigation?.requestedAt ?? undefined, // 날짜 검증을 위해 추가
      evaluationScore: investigation?.evaluationScore ?? undefined,
      evaluationResult: investigation?.evaluationResult ?? undefined,
      investigationNotes: investigation?.investigationNotes ?? "",
      attachments: [],
    },
  })

  // 평가점수 변화 → 자동 평가 & 보완 타입 초기화
  React.useEffect(() => {
    const score = form.watch("evaluationScore")
    let nextResult: string | undefined = undefined
    if (typeof score === "number") {
      if (score >= 80) nextResult = "APPROVED"
      else if (score >= 70) {
        // 70~79점일 때는 보완방법 선택을 기다리므로 바로 설정하지 않음
        nextResult = undefined
        setSupplementType("")
      }
      else if (score < 70) nextResult = "REJECTED"
    }
    if (nextResult) {
      form.setValue("evaluationResult", nextResult as any)
    } else if (score >= 70 && score < 80) {
      // 70~79점 범위에서는 보완방법 선택이 필요하다는 표시
      form.setValue("evaluationResult", "SUPPLEMENT" as any)
    }
  }, [form.watch("evaluationScore")])

  // 보완방법 선택 변화 → 평가결과 변경
  React.useEffect(() => {
    // 70~79점 범위에서만 보완방법 선택에 따라 결과 변경
    const score = form.watch("evaluationScore")
    if (typeof score === "number" && score >= 70 && score < 80) {
      if (supplementType === "REINSPECT")
        form.setValue("evaluationResult", "SUPPLEMENT_REINSPECT" as any)
      else if (supplementType === "DOCUMENT")
        form.setValue("evaluationResult", "SUPPLEMENT_DOCUMENT" as any)
    }
  }, [supplementType, form.watch("evaluationScore")])

  // investigation이 변경될 때마다 폼 리셋
  React.useEffect(() => {
    if (investigation) {
      form.reset({
        investigationId: investigation.investigationId,
        completedAt: investigation.completedAt ?? undefined,
        requestedAt: investigation.requestedAt ?? undefined, // 날짜 검증을 위해 추가
        evaluationScore: investigation.evaluationScore ?? undefined,
        evaluationResult: investigation.evaluationResult ?? undefined,
        investigationNotes: investigation.investigationNotes ?? "",
        attachments: [],
      })

      // 기존 첨부파일 로드
      loadExistingAttachments(investigation.investigationId)
    }
  }, [investigation, form])

  // 기존 첨부파일 로드 함수
  const loadExistingAttachments = async (investigationId: number) => {
    setLoadingAttachments(true)
    try {
      const result = await getInvestigationAttachments(investigationId)
      if (result.success) {
        setExistingAttachments(result.attachments || [])
      } else {
        toast.error("첨부파일 목록을 불러오는데 실패했습니다.")
      }
    } catch (error) {
      console.error("첨부파일 로드 실패:", error)
      toast.error("첨부파일 목록을 불러오는 중 오류가 발생했습니다.")
    } finally {
      setLoadingAttachments(false)
    }
  }

  // 첨부파일 삭제 함수
  const handleDeleteAttachment = async (attachmentId: number) => {
    if (!investigation) return

    try {
      await deleteInvestigationAttachment(attachmentId)
      toast.success("첨부파일이 삭제되었습니다.")
      // 목록 새로고침
      loadExistingAttachments(investigation.investigationId)

    } catch (error) {
      console.error("첨부파일 삭제 오류:", error)
      toast.error(error instanceof Error ? error.message : "첨부파일 삭제 중 오류가 발생했습니다.")
    }
  }

  // 첨부파일 다운로드 함수
  const handleDownloadAttachment = async (attachment: any) => {
    if (!attachment.filePath || !attachment.fileName) {
      toast.error("첨부파일 정보가 올바르지 않습니다.")
      return
    }

    try {
      await downloadFile(attachment.filePath, attachment.fileName, {
        showToast: true,
        action: 'download'
      })
    } catch (error) {
      console.error("첨부파일 다운로드 오류:", error)
      toast.error("첨부파일 다운로드 중 오류가 발생했습니다.")
    }
  }

  // 선택된 파일에서 특정 파일 제거
  const handleRemoveSelectedFile = (indexToRemove: number) => {
    const currentFiles = (form.getValues("attachments") as File[]) || []
    const updatedFiles = currentFiles.filter((_: File, index: number) => index !== indexToRemove)
    form.setValue("attachments", updatedFiles as any)

    if (updatedFiles.length === 0) {
      toast.success("모든 선택된 파일이 제거되었습니다.")
    } else {
      toast.success("파일이 제거되었습니다.")
    }
  }

  // 파일 업로드 섹션 렌더링
  const renderFileUploadSection = () => {
    const currentStatus = form.watch("evaluationResult") as string | undefined
    const selectedFiles = form.watch("attachments") as File[] | undefined
    const config = getFileUploadConfig(currentStatus ?? "")

    if (!config.enabled) return null

    return (
      <>
        {/* 기존 첨부파일 목록 */}
        {(existingAttachments.length > 0 || loadingAttachments) && (
          <div className="space-y-2">
            <FormLabel>기존 첨부파일</FormLabel>
            <div className="border rounded-md p-3 space-y-2 max-h-32 overflow-y-auto">
              {loadingAttachments ? (
                <div className="flex items-center justify-center py-4">
                  <Loader className="h-4 w-4 animate-spin" />
                  <span className="ml-2 text-sm text-muted-foreground">
                    첨부파일 로딩 중...
                  </span>
                </div>
              ) : existingAttachments.length > 0 ? (
                existingAttachments.map((attachment) => (
                  <div key={attachment.id} className="flex items-center justify-between text-sm">
                    <div className="flex items-center space-x-2 flex-1 min-w-0">
                      <span className="text-xs px-2 py-1 bg-muted rounded">
                        {attachment.attachmentType}
                      </span>
                      <span className="truncate">{attachment.fileName}</span>
                      <span className="text-muted-foreground">
                        ({Math.round(attachment.fileSize / 1024)}KB)
                      </span>
                    </div>
                    <div className="flex items-center gap-1">
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        onClick={() => handleDownloadAttachment(attachment)}
                        className="text-blue-600 hover:text-blue-700"
                        disabled={isPending}
                        title="파일 다운로드"
                      >
                        <Download className="h-4 w-4" />
                      </Button>
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        onClick={() => handleDeleteAttachment(attachment.id)}
                        className="text-destructive hover:text-destructive"
                        disabled={isPending}
                        title="파일 삭제"
                      >
                        <X className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                ))
              ) : (
                <div className="text-sm text-muted-foreground text-center py-2">
                  첨부된 파일이 없습니다.
                </div>
              )}
            </div>
          </div>
        )}

        {/* 새 파일 업로드 */}
        <FormField
          control={form.control}
          name="attachments"
          render={({ field: { onChange, ...field } }) => (
            <FormItem>
              <FormControl>
                <Dropzone
                  onDrop={(acceptedFiles, rejectedFiles) => {
                    // 거부된 파일에 대한 상세 에러 메시지
                    if (rejectedFiles.length > 0) {
                      rejectedFiles.forEach((file) => {
                        const error = file.errors[0]
                        if (error.code === 'file-too-large') {
                          toast.error(`${file.file.name}: 파일 크기가 ${config.maxSizeText}를 초과합니다.`)
                        } else if (error.code === 'file-invalid-type') {
                          toast.error(`${file.file.name}: 지원하지 않는 파일 형식입니다.`)
                        } else {
                          toast.error(`${file.file.name}: 파일 업로드에 실패했습니다.`)
                        }
                      })
                    }

                    if (acceptedFiles.length > 0) {
                      // 기존 파일들과 새로 선택된 파일들을 합치기
                      const currentFiles = (form.getValues("attachments") as File[]) || []
                      const newFiles = [...currentFiles, ...acceptedFiles]
                      onChange(newFiles)
                      toast.success(`${acceptedFiles.length}개 파일이 추가되었습니다.`)
                    }
                  }}
                  accept={config.accept}
                  multiple
                  maxSize={config.maxSize}
                  disabled={isPending || uploadingFiles}
                >
                  <DropzoneZone>
                    <DropzoneUploadIcon />
                    <DropzoneTitle>
                      {isPending || uploadingFiles
                        ? "파일 업로드 중..."
                        : "파일을 드래그하거나 클릭하여 업로드"
                      }
                    </DropzoneTitle>
                    <DropzoneDescription>
                      {config.description} (최대 {config.maxSizeText})
                    </DropzoneDescription>
                    <DropzoneInput />
                  </DropzoneZone>
                </Dropzone>
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        {/* 선택된 파일 목록 */}
        {selectedFiles && selectedFiles.length > 0 && (
          <div className="space-y-2">
            {/* <FormLabel>선택된 파일 ({selectedFiles.length}개)</FormLabel> */}
            <FileList>
              <FileListHeader>
                <span className="text-sm font-medium">업로드 예정 파일 ({selectedFiles.length}개)</span>
              </FileListHeader>
              {selectedFiles.map((file, index) => (
                <FileListItem
                  key={`${file.name}-${index}`}
                  className="flex items-center justify-between gap-2 px-2 py-2"
                >
                  {/* 왼쪽 아이콘 */}
                  <FileListIcon className="shrink-0 h-4 w-4 text-muted-foreground" />

                  {/* 가운데 이름 + 사이즈 */}
                  <FileListInfo className="flex-1 min-w-0">
                    <FileListName className="truncate">{file.name}</FileListName>
                    <FileListSize className="text-xs text-muted-foreground shrink-0">
                      {file.size}
                    </FileListSize>
                  </FileListInfo>

                  {/* 오른쪽 삭제 버튼 */}
                  <FileListAction className="shrink-0">
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      onClick={() => handleRemoveSelectedFile(index)}
                      disabled={isPending || uploadingFiles}
                      className="h-5 w-5 text-destructive hover:text-destructive"
                    >
                      <X className="h-4 w-4" />
                    </Button>
                  </FileListAction>
                </FileListItem>

              ))}
            </FileList>
          </div>
        )}
      </>
    )
  }

  // 파일 업로드 함수
  const uploadFiles = async (files: File[], investigationId: number) => {
    const uploadPromises = files.map(async (file) => {
      try {
        // 서버 액션을 호출하여 파일 저장 및 DB 레코드 생성
        const result = await createVendorInvestigationAttachmentAction({
          investigationId,
          file,
          userId: undefined // 필요시 사용자 ID 추가
        });

        if (!result.success) {
          throw new Error(result.error || "파일 업로드 실패");
        }

        return result.attachment;
      } catch (error) {
        console.error(`파일 업로드 실패: ${file.name}`, error);
        throw error;
      }
    });

    return await Promise.all(uploadPromises);
  }

  // Submit handler
  async function onSubmit(values: UpdateVendorInvestigationResultSchema) {
    console.log("실사 결과 입력 onSubmit 호출됨:", values)

    if (!values.investigationId) {
      console.log("investigationId가 없음:", values.investigationId)
      return
    }

    startTransition(async () => {
      try {
        console.log("실사 결과 입력 startTransition 시작")

        // 1) 먼저 텍스트 데이터 업데이트
        const formData = new FormData()

        // 필수 필드
        formData.append("investigationId", String(values.investigationId))

        // 선택적 필드들
        if (values.completedAt) {
          formData.append("completedAt", values.completedAt.toISOString())
        }

        if (values.evaluationScore !== undefined) {
          formData.append("evaluationScore", String(values.evaluationScore))
        }

        if (values.evaluationResult) {
          formData.append("evaluationResult", values.evaluationResult)
        }

        if (values.investigationNotes) {
          formData.append("investigationNotes", values.investigationNotes)
        }

        // 텍스트 데이터 업데이트 (IN_PROGRESS -> COMPLETED/CANCELED/SUPPLEMENT_REQUIRED)
        const { error } = await updateVendorInvestigationResultAction(formData)

        if (error) {
          toast.error(error)
          return
        }

        // 보완-서류제출 선택 시 메일 발송
        if (values.evaluationResult === "SUPPLEMENT_DOCUMENT") {
          try {
            const { requestInvestigationSupplementAction } = await import('../service')
            const mailResult = await requestInvestigationSupplementAction({
              investigationId: values.investigationId,
              vendorId: investigation?.vendorId || 0,
              comment: values.investigationNotes || "실사 보완이 필요합니다. 첨부된 내용을 확인하시고 필요한 자료를 제출해 주시기 바랍니다."
            })

            if (!mailResult.success) {
              console.warn("보완 메일 발송 실패:", mailResult.error)
              toast.warning("실사 결과는 저장되었지만 보완 메일 발송에 실패했습니다.")
            }
          } catch (mailError) {
            console.warn("보완 메일 발송 중 오류:", mailError)
            toast.warning("실사 결과는 저장되었지만 보완 메일 발송에 실패했습니다.")
          }
        }

        // 2) 첨부파일 검증 (필수: 기존 첨부파일 + 새 파일 합계 최소 1개)
        const newFilesCount = values.attachments?.length || 0
        const existingFilesCount = existingAttachments.length
        const totalFilesCount = newFilesCount + existingFilesCount

        if (totalFilesCount === 0) {
          toast.error("최소 1개의 첨부파일이 필요합니다.")
          return
        }

        // 새 파일이 있는 경우에만 업로드 진행
        if (newFilesCount > 0) {
          setUploadingFiles(true)

          try {
            await uploadFiles(values.attachments, values.investigationId)
            toast.success(`실사 결과와 ${newFilesCount}개 파일이 업데이트되었습니다!`)

            // 첨부파일 목록 새로고침
            loadExistingAttachments(values.investigationId)
          } catch (fileError) {
            console.error("파일 업로드 에러:", fileError)
            toast.error(`데이터는 저장되었지만 파일 업로드 중 오류가 발생했습니다: ${fileError}`)
          } finally {
            setUploadingFiles(false)
          }
        } else {
          // 기존 첨부파일만 있는 경우
          toast.success("실사 결과가 업데이트되었습니다!")
        }

        form.reset()
        props.onOpenChange?.(false)

      } catch (error) {
        console.error("실사 결과 업데이트 오류:", error)
        toast.error("실사 결과 업데이트 중 오류가 발생했습니다.")
      }
    })
  }

  // 저장버튼 커스텀(불합격시: 팝업 → 확인하면 제출 / 아니면 중단)
  const handleSaveClick = async () => {
    const score = form.getValues("evaluationScore")
    const result = form.getValues("evaluationResult")
    if (result === "REJECTED" && !showRejectedDialog) {
      setShowRejectedDialog(true)
      return
    }
    const isValid = await form.trigger()
    if (isValid) form.handleSubmit(onSubmit)()
  }
  // 불합격 안내(확정) 처리
  const handleRejectedConfirm = () => {
    setShowRejectedDialog(false)
    form.handleSubmit(onSubmit)()
  }

  return (
    <>
      <Sheet {...props}>
        <SheetContent className="flex flex-col h-full sm:max-w-xl" >
          <SheetHeader className="text-left flex-shrink-0">
            <SheetTitle>실사 결과 입력</SheetTitle>
            <SheetDescription>
              {investigation?.vendorName && (
                <span className="font-medium">{investigation.vendorName}</span>
              )}의 실사 결과를 입력합니다.
            </SheetDescription>
          </SheetHeader>

          <div className="flex-1 overflow-y-auto py-4">
            <Form {...form}>
              <form
                onSubmit={form.handleSubmit(onSubmit)}
                className="flex flex-col gap-4"
                id="update-investigation-form"
              >
                {/* 실제 실사일 */}
                <FormField
                  control={form.control}
                  name="completedAt"
                  render={({ field }) => (
                    <FormItem className="flex flex-col">
                      <FormLabel>실제 실사일<span className="text-red-500 ml-1">*</span></FormLabel>
                      <Popover>
                        <PopoverTrigger asChild>
                          <FormControl>
                            <Button
                              variant="outline"
                              className={`w-full pl-3 text-left font-normal ${!field.value && "text-muted-foreground"}`}
                            >
                              {field.value ? (
                                format(field.value, "yyyy년 MM월 dd일")
                              ) : (
                                <span>날짜를 선택하세요</span>
                              )}
                              <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
                            </Button>
                          </FormControl>
                        </PopoverTrigger>
                        <PopoverContent className="w-auto p-0" align="start">
                          <Calendar mode="single" selected={field.value} onSelect={field.onChange} initialFocus />
                        </PopoverContent>
                      </Popover>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {/* 평가 점수 */}
                <FormField
                  control={form.control}
                  name="evaluationScore"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>평가 점수<span className="text-red-500 ml-1">*</span></FormLabel>
                      <FormControl>
                        <Input
                          type="number"
                          min={0}
                          max={100}
                          placeholder="0-100점"
                          maxLength={3}
                          {...field}
                          value={field.value || ""}
                          onChange={e => {
                            const inputValue = e.target.value

                            // 빈 값이거나 숫자가 아닌 경우
                            if (inputValue === "") {
                              field.onChange(undefined)
                              return
                            }

                            // 3자리 초과 입력 방지
                            if (inputValue.length > 3) {
                              return
                            }

                            const numericValue = parseInt(inputValue, 10)

                            // 100 이상 입력 시 alert
                            if (numericValue > 100) {
                              toast.error("평가 점수는 100점을 초과할 수 없습니다.")
                              return
                            }

                            field.onChange(numericValue)
                          }}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {/* 평가 결과 VIEW (자동) */}
                <div>
                  <FormLabel>평가 결과</FormLabel>
                  <div className="min-h-10 flex items-center gap-2 mt-1 font-bold">
                    {(() => {
                      const result = form.watch("evaluationResult")
                      if (result === "APPROVED") return <span className="text-green-600">합격 (승인)</span>
                      if (result === "SUPPLEMENT") return <span className="text-yellow-600">보완 필요 (방법 선택)</span>
                      if (result === "SUPPLEMENT_REINSPECT") return <span className="text-yellow-600">보완 필요 - 재실사</span>
                      if (result === "SUPPLEMENT_DOCUMENT") return (
                        <div className="flex flex-col gap-1">
                          <span className="text-yellow-600">보완 필요 - 자료제출</span>
                          <span className="text-xs text-muted-foreground font-normal">
                            💡 저장 시 협력업체에 자동으로 보완 요청 메일이 발송됩니다.
                          </span>
                        </div>
                      )
                      if (result === "REJECTED") return <span className="text-destructive">불합격</span>
                      return <span className="text-muted-foreground">-</span>
                    })()}
                  </div>
                </div>

                {/* 보완 세부항목(70~79점) */}
                {(() => {
                  const score = form.watch("evaluationScore")
                  return typeof score === "number" && score >= 70 && score < 80
                })() && (
                  <div>
                    <FormLabel>보완 방법<span className="text-red-500 ml-1">*</span></FormLabel>
                    <Select value={supplementType} onValueChange={setSupplementType}>
                      <SelectTrigger>
                        <SelectValue placeholder="선택" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectGroup>
                          <SelectItem value="REINSPECT">재실사</SelectItem>
                          <SelectItem value="DOCUMENT">자료제출</SelectItem>
                        </SelectGroup>
                      </SelectContent>
                    </Select>
                  </div>
                )}

                {/* QM 의견 */}
                <FormField
                  control={form.control}
                  name="investigationNotes"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>QM 의견</FormLabel>
                      <FormControl>
                        <Textarea placeholder="실사에 대한 QM 의견을 입력하세요..." {...field} className="min-h-[80px]" />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                        {/* 파일 첨부 섹션 */}
                <div className="space-y-2">
                  <FormLabel>실사 관련 첨부파일<span className="text-red-500 ml-1">*</span></FormLabel>
                  <div className="text-sm text-muted-foreground">
                    실사 결과 입력 시 최소 1개의 첨부파일이 필요합니다.
                  </div>
                  {renderFileUploadSection()}
                </div>
              </form>
            </Form>
          </div>

          {/* Footer Buttons */}
          <SheetFooter className="gap-2 pt-2 sm:space-x-0 flex-shrink-0">
            <SheetClose asChild>
              <Button type="button" variant="outline" disabled={isPending || uploadingFiles}>
                취소
              </Button>
            </SheetClose>
            <Button
              disabled={isPending || uploadingFiles}
              onClick={handleSaveClick}
            >
              {(isPending || uploadingFiles) && (
                <Loader className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />
              )}
              {uploadingFiles ? "업로드 중..." : isPending ? "저장 중..." : "저장"}
            </Button>
          </SheetFooter>
        </SheetContent>
      </Sheet>

      {/* 불합격 안내 팝업 */}
      <SystemDialog open={showRejectedDialog} onOpenChange={setShowRejectedDialog}>
        <SystemDialogContent>
          <SystemDialogHeader>
            <SystemDialogTitle><AlertTriangle className="mr-2 inline h-6 w-6 text-destructive" />불합격 확정 시 안내</SystemDialogTitle>
          </SystemDialogHeader>
          <div className="mt-2 mb-4 text-base leading-relaxed">
            불합격 확정 시 <b>결과입력완료일부터 1년간 동일 건에 대한 실사는 불가합니다.</b><br/>
            정말 확정 처리하시겠습니까?
          </div>
          <SystemDialogFooter className="flex flex-row justify-end gap-2">
            <Button variant="outline" onClick={() => setShowRejectedDialog(false)}>취소</Button>
            <Button variant="destructive" onClick={handleRejectedConfirm}>확인</Button>
          </SystemDialogFooter>
        </SystemDialogContent>
      </SystemDialog>
    </>
  )
}