"use client"

import * as React from "react"
import { z } from "zod"
import { useForm, useFieldArray } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
  SheetFooter,
  SheetClose,
} from "@/components/ui/sheet"
import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  FormDescription
} from "@/components/ui/form"
import { Loader, Download, X, Eye, AlertCircle } from "lucide-react"
import { toast } from "sonner"
import { Badge } from "@/components/ui/badge"

import {
  Dropzone,
  DropzoneDescription,
  DropzoneInput,
  DropzoneTitle,
  DropzoneUploadIcon,
  DropzoneZone,
} from "@/components/ui/dropzone"
import {
  FileList,
  FileListAction,
  FileListDescription,
  FileListHeader,
  FileListIcon,
  FileListInfo,
  FileListItem,
  FileListName,
} from "@/components/ui/file-list"

import prettyBytes from "pretty-bytes"
import { formatDate } from "@/lib/utils"
import { processTechSalesRfqAttachments } from "@/lib/techsales-rfq/service"
import { useSession } from "next-auth/react"
import { ApprovalPreviewDialog } from "@/lib/approval/client"
import { ApplicationReasonDialog } from "@/lib/rfq-last/vendor/application-reason-dialog"
import { requestRfqResendWithDrmApproval } from "@/lib/techsales-rfq/approval-actions"
import { mapTechSalesRfqSendToTemplateVariables } from "@/lib/techsales-rfq/approval-handlers"

const MAX_FILE_SIZE = 6e8 // 600MB

/** 기존 첨부 파일 정보 (techSalesAttachments 테이블 구조) */
export interface ExistingTechSalesAttachment {
  id: number
  techSalesRfqId: number
  fileName: string
  originalFileName: string
  filePath: string
  fileSize?: number
  fileType?: string
  attachmentType: "RFQ_COMMON" | "TBE_RESULT" | "CBE_RESULT"
  description?: string
  createdBy: number
  createdAt: Date
}

/** 새로 업로드할 파일 */
const newUploadSchema = z.object({
  fileObj: z.any().optional(), // 실제 File
  attachmentType: z.enum(["RFQ_COMMON", "TBE_RESULT", "CBE_RESULT"]).default("RFQ_COMMON"),
  description: z.string().optional(),
})

/** 기존 첨부 (react-hook-form에서 관리) */
const existingAttachSchema = z.object({
  id: z.number(),
  techSalesRfqId: z.number(),
  fileName: z.string(),
  originalFileName: z.string(),
  filePath: z.string(),
  fileSize: z.number().optional(),
  fileType: z.string().optional(),
  attachmentType: z.enum(["RFQ_COMMON", "TBE_RESULT", "CBE_RESULT"]),
  description: z.string().optional(),
  createdBy: z.number(),
  createdAt: z.custom<Date>(),
})

/** RHF 폼 전체 스키마 */
const attachmentsFormSchema = z.object({
  techSalesRfqId: z.number().int(),
  existing: z.array(existingAttachSchema),
  newUploads: z.array(newUploadSchema),
})

type AttachmentsFormValues = z.infer<typeof attachmentsFormSchema>

// TechSalesRfq 타입 (간단 버전)
interface TechSalesRfq {
  id: number
  rfqCode: string | null
  status: string
  // 필요한 다른 필드들...
}

interface TechSalesRfqAttachmentsSheetProps
  extends React.ComponentPropsWithRef<typeof Sheet> {
  defaultAttachments?: ExistingTechSalesAttachment[]
  rfq: TechSalesRfq | null
  /** 첨부파일 타입 */
  attachmentType?: "RFQ_COMMON" | "TBE_RESULT" | "CBE_RESULT"
  /** 읽기 전용 모드 (벤더용) */
  readOnly?: boolean
  /** 업로드/삭제 후 상위 테이블에 attachmentCount 등을 업데이트하기 위한 콜백 */
  // onAttachmentsUpdated?: (rfqId: number, newAttachmentCount: number) => void

}

export function TechSalesRfqAttachmentsSheet({
  defaultAttachments = [],
  // onAttachmentsUpdated,
  rfq,
  attachmentType = "RFQ_COMMON",
  readOnly = false,
  ...props
}: TechSalesRfqAttachmentsSheetProps) {
  const [isPending, setIsPending] = React.useState(false)
  const session = useSession()
  
  // 재발송 결재 관련 상태
  const [showResendApprovalDialog, setShowResendApprovalDialog] = React.useState(false)
  const [showApplicationReasonDialog, setShowApplicationReasonDialog] = React.useState(false)
  const [resendApprovalData, setResendApprovalData] = React.useState<{
    rfqId: number
    drmFiles: Array<{
      file: File
      attachmentType: string
      description?: string
    }>
  } | null>(null)
  const [approvalPreviewData, setApprovalPreviewData] = React.useState<{
    templateVariables: Record<string, string>
    applicationReason: string
  } | null>(null)

  // 파일 다운로드 핸들러
  const handleDownloadClick = React.useCallback(async (filePath: string, fileName: string) => {
    try {
      const { downloadFile } = await import('@/lib/file-download')
      await downloadFile(filePath, fileName, {
        showToast: true,
        onError: (error) => {
          console.error('다운로드 오류:', error)
          toast.error(error)
        },
        onSuccess: (fileName, fileSize) => {
          console.log(`다운로드 성공: ${fileName} (${fileSize} bytes)`)
        }
      })
    } catch (error) {
      console.error('다운로드 오류:', error)
      toast.error('파일 다운로드 중 오류가 발생했습니다.')
    }
  }, [])
  // 첨부파일 타입별 제목과 설명 설정
  const attachmentConfig = React.useMemo(() => {
    switch (attachmentType) {
      case "TBE_RESULT":
        return {
          title: "TBE 결과 첨부파일",
          description: "기술 평가(TBE) 결과 파일을 관리합니다.",
          fileTypeLabel: "TBE 결과",
          canEdit: !readOnly
        }
      case "CBE_RESULT":
        return {
          title: "CBE 결과 첨부파일",
          description: "상업성 평가(CBE) 결과 파일을 관리합니다.",
          fileTypeLabel: "CBE 결과",
          canEdit: !readOnly
        }
      default: // RFQ_COMMON
        return {
          title: "RFQ 첨부파일",
          description: readOnly ? "RFQ 공통 첨부파일을 조회합니다." : "RFQ 공통 첨부파일을 관리합니다.",
          fileTypeLabel: "공통",
          canEdit: !readOnly
        }
    }
  }, [attachmentType, readOnly])

  // // RFQ 상태에 따른 편집 가능 여부 결정 (readOnly prop이 true면 항상 false)
  // const isEditable = React.useMemo(() => {
  //   if (!rfq) return false
  //   return attachmentConfig.canEdit
  // }, [rfq, attachmentConfig.canEdit])

  const form = useForm<AttachmentsFormValues>({
    resolver: zodResolver(attachmentsFormSchema),
    defaultValues: {
      techSalesRfqId: rfq?.id || 0,
      existing: defaultAttachments.map(att => ({
        id: att.id,
        techSalesRfqId: att.techSalesRfqId,
        fileName: att.fileName,
        originalFileName: att.originalFileName,
        filePath: att.filePath,
        fileSize: att.fileSize || undefined,
        fileType: att.fileType || undefined,
        attachmentType: att.attachmentType,
        description: att.description || undefined,
        createdBy: att.createdBy,
        createdAt: att.createdAt,
      })),
      newUploads: [],
    },
  })

  // useFieldArray for existing and new uploads
  const {
    fields: existingFields,
    remove: removeExisting,
  } = useFieldArray({
    control: form.control,
    name: "existing",
  })

  const {
    fields: newUploadFields,
    append: appendNewUpload,
    remove: removeNewUpload,
  } = useFieldArray({
    control: form.control,
    name: "newUploads",
  })

  // Reset form when defaultAttachments changes
  React.useEffect(() => {
    if (defaultAttachments) {
      form.reset({
        techSalesRfqId: rfq?.id || 0,
        existing: defaultAttachments.map(att => ({
          id: att.id,
          techSalesRfqId: att.techSalesRfqId,
          fileName: att.fileName,
          originalFileName: att.originalFileName,
          filePath: att.filePath,
          fileSize: att.fileSize || undefined,
          fileType: att.fileType || undefined,
          attachmentType: att.attachmentType,
          description: att.description || undefined,
          createdBy: att.createdBy,
          createdAt: att.createdAt,
        })),
        newUploads: [],
      })
    }
  }, [defaultAttachments, rfq?.id, form])

  // Handle dropzone accept
  const handleDropAccepted = React.useCallback((acceptedFiles: File[]) => {
    acceptedFiles.forEach((file) => {
      appendNewUpload({
        fileObj: file,
        attachmentType: "RFQ_COMMON",
        description: "",
      })
    })
  }, [appendNewUpload])

  // Handle dropzone reject
  const handleDropRejected = React.useCallback(() => {
    toast.error("파일 크기가 너무 크거나 지원하지 않는 파일 형식입니다.")
  }, [])

  // Handle remove existing attachment
  const handleRemoveExisting = React.useCallback((index: number) => {
    removeExisting(index)
  }, [removeExisting])

  // Handle form submission
  const onSubmit = async (data: AttachmentsFormValues) => {
    if (!rfq) {
      toast.error("RFQ 정보를 찾을 수 없습니다.")
      return
    }

    setIsPending(true)
    try {
      // 삭제할 첨부파일 ID 수집
      const deleteAttachmentIds = defaultAttachments
        .filter((original) => !data.existing.find(existing => existing.id === original.id))
        .map(attachment => attachment.id)

      // 새 파일 정보 수집
      const newFiles = data.newUploads
        .filter(upload => upload.fileObj)
        .map(upload => ({
          file: upload.fileObj as File,
          attachmentType: attachmentType,
          description: upload.description,
        }))

      // 실제 API 호출
      const result = await processTechSalesRfqAttachments({
        techSalesRfqId: rfq.id,
        newFiles,
        deleteAttachmentIds,
        createdBy: parseInt(session.data?.user.id || "0"),
      })

      if (result.error) {
        // DRM 파일 추가로 인한 재발송 결재 필요
        if (result.error === "DRM_FILE_ADDED_TO_SENT_RFQ") {
          // DRM 파일만 필터링
          const drmFiles = newFiles.filter((_, index) => {
            // DRM 파일 검출은 서버에서 이미 완료되었으므로, 업로드된 파일 중 DRM 파일만 추출
            // 실제로는 서버에서 반환된 정보를 사용해야 하지만, 여기서는 업로드된 파일을 그대로 사용
            return true // 임시로 모든 새 파일을 DRM 파일로 간주 (실제로는 서버에서 필터링 필요)
          })
          
          setResendApprovalData({
            rfqId: rfq.id,
            drmFiles: newFiles, // 모든 새 파일을 DRM 파일로 간주
          })
          setShowApplicationReasonDialog(true)
          setIsPending(false)
          return
        } else {
          toast.error(result.error)
          return
        }
      }

      // 성공 메시지 표시 (업로드된 파일 수 포함)
      const uploadedCount = newFiles.length
      const deletedCount = deleteAttachmentIds.length
      
      let successMessage = "첨부파일이 저장되었습니다."
      if (uploadedCount > 0 && deletedCount > 0) {
        successMessage = `${uploadedCount}개 파일 업로드, ${deletedCount}개 파일 삭제 완료`
      } else if (uploadedCount > 0) {
        successMessage = `${uploadedCount}개 파일이 업로드되었습니다.`
      } else if (deletedCount > 0) {
        successMessage = `${deletedCount}개 파일이 삭제되었습니다.`
      }
      
      toast.success(successMessage)
      
      // 다이얼로그 자동 닫기
      props.onOpenChange?.(false)
      
      // // 즉시 첨부파일 목록 새로고침
      // const refreshResult = await getTechSalesRfqAttachments(rfq.id)
      // if (refreshResult.error) {
      //   console.error("첨부파일 목록 새로고침 실패:", refreshResult.error)
      //   toast.warning("첨부파일 목록 새로고침에 실패했습니다. 시트를 다시 열어주세요.")
      // } else {
      //   // 새로운 첨부파일 목록으로 폼 업데이트
      //   const refreshedAttachments = refreshResult.data.map(att => ({
      //     id: att.id,
      //     techSalesRfqId: att.techSalesRfqId || rfq.id,
      //     fileName: att.fileName,
      //     originalFileName: att.originalFileName,
      //     filePath: att.filePath,
      //     fileSize: att.fileSize,
      //     fileType: att.fileType,
      //     attachmentType: att.attachmentType as "RFQ_COMMON" | "TBE_RESULT" | "CBE_RESULT",
      //     description: att.description,
      //     createdBy: att.createdBy,
      //     createdAt: att.createdAt,
      //   }))

      //   // 폼을 새로운 데이터로 리셋 (새 업로드 목록은 비움)
      //   form.reset({
      //     techSalesRfqId: rfq.id,
      //     existing: refreshedAttachments.map(att => ({
      //       ...att,
      //       fileSize: att.fileSize || undefined,
      //       fileType: att.fileType || undefined,
      //       description: att.description || undefined,
      //     })),
      //     newUploads: [],
      //   })
        
      //   // 즉시 UI 업데이트를 위한 추가 피드백
      //   if (uploadedCount > 0) {
      //     toast.success("첨부파일 목록이 업데이트되었습니다.", { duration: 2000 })
      //   }
      // }
      
      // // 콜백으로 상위 컴포넌트에 변경사항 알림
      // const newAttachmentCount = refreshResult.error ? 
      //   (data.existing.length + newFiles.length - deleteAttachmentIds.length) : 
      //   refreshResult.data.length
      // onAttachmentsUpdated?.(rfq.id, newAttachmentCount)
      
    } catch (error) {
      console.error("첨부파일 저장 오류:", error)
      toast.error("첨부파일 저장 중 오류가 발생했습니다.")
    } finally {
      setIsPending(false)
    }
  }

  // 신청사유 입력 완료 핸들러
  const handleApplicationReasonConfirm = React.useCallback(async (reason: string) => {
    if (!resendApprovalData) {
      toast.error("결재 데이터가 없습니다.")
      return
    }

    try {
      // 템플릿 변수 생성 (신청사유 포함)
      const templateVariables = await mapTechSalesRfqSendToTemplateVariables({
        attachments: resendApprovalData.drmFiles.map(f => ({
          fileName: f.file.name,
          fileSize: f.file.size,
        })),
        vendorNames: [], // 기존 벤더 목록은 후처리에서 조회
        applicationReason: reason,
      })

      // 결재 미리보기 데이터 업데이트
      setApprovalPreviewData({
        templateVariables,
        applicationReason: reason,
      })

      // 신청사유 다이얼로그 닫고 결재 미리보기 열기
      setShowApplicationReasonDialog(false)
      setShowResendApprovalDialog(true)
    } catch (error) {
      console.error("템플릿 변수 생성 실패:", error)
      toast.error("결재 문서 생성에 실패했습니다.")
    }
  }, [resendApprovalData])

  // 결재 미리보기 확인 핸들러
  const handleApprovalConfirm = React.useCallback(async (approvalData: {
    approvers: string[]
    title: string
    description?: string
  }) => {
    if (!resendApprovalData || !approvalPreviewData || !session?.data?.user) {
      toast.error("결재 데이터가 없습니다.")
      return
    }

    try {
      const result = await requestRfqResendWithDrmApproval({
        rfqId: resendApprovalData.rfqId,
        rfqCode: rfq?.rfqCode || undefined,
        drmFiles: resendApprovalData.drmFiles,
        applicationReason: approvalPreviewData.applicationReason,
        currentUser: {
          id: Number(session.data.user.id),
          epId: session.data.user.epId || null,
          name: session.data.user.name || undefined,
          email: session.data.user.email || undefined,
        },
        approvers: approvalData.approvers,
      })

      if (result.success) {
        toast.success(result.message)
        setShowResendApprovalDialog(false)
        setResendApprovalData(null)
        setApprovalPreviewData(null)
        props.onOpenChange?.(false)
      }
    } catch (error) {
      console.error("재발송 결재 상신 실패:", error)
      toast.error(error instanceof Error ? error.message : "재발송 결재 상신에 실패했습니다.")
    }
  }, [resendApprovalData, approvalPreviewData, session, rfq, props])

  return (
    <Sheet {...props}>
      <SheetContent className="flex flex-col gap-6 sm:max-w-md">
        <SheetHeader className="text-left">
          <SheetTitle>{attachmentConfig.title}</SheetTitle>
          <SheetDescription>
            <div>RFQ: {rfq?.rfqCode || "N/A"}</div>
            <div className="mt-1">{attachmentConfig.description}</div>
            {!attachmentConfig.canEdit && (
              <div className="mt-2 flex items-center gap-2 text-amber-600">
                <AlertCircle className="h-4 w-4" />
                <span className="text-sm">현재 상태에서는 편집할 수 없습니다</span>
              </div>
            )}
          </SheetDescription>
        </SheetHeader>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-1 flex-col gap-6">
            {/* 1) Existing attachments */}
            <div className="grid gap-4">
              <h6 className="font-semibold leading-none tracking-tight">
                기존 첨부파일 ({existingFields.length}개)
              </h6>
              {existingFields.map((field, index) => {
                const typeLabel = attachmentConfig.fileTypeLabel
                const sizeText = field.fileSize ? prettyBytes(field.fileSize) : "알 수 없음"
                const dateText = field.createdAt ? formatDate(field.createdAt, "KR") : ""

                return (
                  <div key={field.id} className="flex items-start justify-between p-3 border rounded-md gap-3">
                    <div className="flex-1 min-w-0 overflow-hidden">
                      <div className="flex items-center gap-2 mb-1 flex-wrap">
                        <p className="text-sm font-medium break-words leading-tight">
                          {field.originalFileName || field.fileName}
                        </p>
                        <Badge variant="outline" className="text-xs shrink-0">
                          {typeLabel}
                        </Badge>
                      </div>
                      <p className="text-xs text-muted-foreground">
                        {sizeText} • {dateText}
                      </p>
                      {field.description && (
                        <p className="text-xs text-muted-foreground mt-1 break-words">
                          {field.description}
                        </p>
                      )}
                    </div>

                    <div className="flex items-center gap-1 shrink-0">
                      {/* Download button */}
                      {field.filePath && (
                        <Button 
                          variant="ghost" 
                          size="icon" 
                          type="button" 
                          className="h-8 w-8"
                          onClick={() => handleDownloadClick(field.filePath, field.originalFileName || field.fileName)}
                          title="다운로드"
                        >
                          <Download className="h-4 w-4" />
                        </Button>
                      )}
                      {/* Remove button - 편집 가능할 때만 표시 */}
                      {attachmentConfig.canEdit && (
                        <Button
                          type="button"
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => handleRemoveExisting(index)}
                        >
                          <X className="h-4 w-4" />
                        </Button>
                      )}
                    </div>
                  </div>
                )
              })}
            </div>

            {/* 2) Dropzone for new uploads - 편집 가능할 때만 표시 */}
            {attachmentConfig.canEdit ? (
              <>
                <Dropzone
                  maxSize={MAX_FILE_SIZE}
                  onDropAccepted={handleDropAccepted}
                  onDropRejected={handleDropRejected}
                >
                  {({ maxSize }) => (
                    <FormField
                      control={form.control}
                      name="newUploads"
                      render={() => (
                        <FormItem>
                          <FormLabel>새 파일 업로드</FormLabel>
                          <DropzoneZone className="flex justify-center">
                            <FormControl>
                              <DropzoneInput />
                            </FormControl>
                            <div className="flex items-center gap-6">
                              <DropzoneUploadIcon />
                              <div className="grid gap-0.5">
                                <DropzoneTitle>파일을 드래그하거나 클릭하세요</DropzoneTitle>
                                <DropzoneDescription>
                                  최대 크기: {maxSize ? prettyBytes(maxSize) : "600MB"}
                                </DropzoneDescription>
                              </div>
                            </div>
                          </DropzoneZone>
                          <FormDescription>파일을 여러 개 선택할 수 있습니다.</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  )}
                </Dropzone>

                {/* newUpload fields -> FileList */}
                {newUploadFields.length > 0 && (
                  <div className="grid gap-4">
                    <h6 className="font-semibold leading-none tracking-tight">
                      새 파일 ({newUploadFields.length}개)
                    </h6>
                    <FileList>
                      {newUploadFields.map((field, idx) => {
                        const fileObj = form.getValues(`newUploads.${idx}.fileObj`)
                        if (!fileObj) return null

                        const fileName = fileObj.name
                        const fileSize = fileObj.size
                        return (
                          <FileListItem key={field.id}>
                            <FileListHeader>
                              <FileListIcon />
                              <FileListInfo>
                                <FileListName>{fileName}</FileListName>
                                <FileListDescription>
                                  {prettyBytes(fileSize)}
                                </FileListDescription>
                              </FileListInfo>
                              <FileListAction onClick={() => removeNewUpload(idx)}>
                                <X />
                                <span className="sr-only">제거</span>
                              </FileListAction>
                            </FileListHeader>
                            
                          </FileListItem>
                        )
                      })}
                    </FileList>
                  </div>
                )}
              </>
            ) : (
              <div className="p-3 bg-muted rounded-md flex items-center justify-center">
                <div className="text-center text-sm text-muted-foreground">
                  <Eye className="h-4 w-4 mx-auto mb-2" />
                  <p>보기 모드에서는 파일 첨부를 할 수 없습니다.</p>
                </div>
              </div>
            )}

            <SheetFooter className="gap-2 pt-2 sm:space-x-0">
              <SheetClose asChild>
                <Button type="button" variant="outline">
                  {attachmentConfig.canEdit ? "취소" : "닫기"}
                </Button>
              </SheetClose>
              {attachmentConfig.canEdit && (
                <Button 
                  type="submit" 
                  disabled={
                    isPending || 
                    (
                      form.getValues().newUploads.length === 0 && 
                      form.getValues().existing.length === defaultAttachments.length &&
                      form.getValues().existing.every(existing => 
                        defaultAttachments.some(original => original.id === existing.id)
                      )
                    )
                  }
                >
                  {isPending && <Loader className="mr-2 h-4 w-4 animate-spin" />}
                  {isPending ? "저장 중..." : "저장"}
                </Button>
              )}
            </SheetFooter>
          </form>
        </Form>
      </SheetContent>

      {/* 신청사유 입력 다이얼로그 */}
      {resendApprovalData && (
        <ApplicationReasonDialog
          open={showApplicationReasonDialog}
          onOpenChange={setShowApplicationReasonDialog}
          onConfirm={handleApplicationReasonConfirm}
          vendorCount={0} // 재발송이므로 기존 벤더에게 발송
          attachmentCount={resendApprovalData.drmFiles.length}
        />
      )}

      {/* 결재 미리보기 다이얼로그 */}
      {resendApprovalData && session?.data?.user?.epId && approvalPreviewData && (
        <ApprovalPreviewDialog
          open={showResendApprovalDialog}
          onOpenChange={setShowResendApprovalDialog}
          templateName="암호화해제 신청"
          variables={approvalPreviewData.templateVariables}
          title={`DRM 파일 재발송 결재 - ${rfq?.rfqCode || 'RFQ'}`}
          currentUser={{
            id: Number(session.data.user.id),
            epId: session.data.user.epId,
            name: session.data.user.name || undefined,
            email: session.data.user.email || undefined,
          }}
          onConfirm={handleApprovalConfirm}
          allowTitleEdit={false}
        />
      )}
    </Sheet>
  )
} 