"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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"

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, getTechSalesRfqAttachments } from "@/lib/techsales-rfq/service"

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" | "VENDOR_SPECIFIC"
  description?: string
  createdBy: number
  createdAt: Date
}

/** 새로 업로드할 파일 */
const newUploadSchema = z.object({
  fileObj: z.any().optional(), // 실제 File
  attachmentType: z.enum(["RFQ_COMMON", "VENDOR_SPECIFIC"]).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", "VENDOR_SPECIFIC"]),
  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
  /** 업로드/삭제 후 상위 테이블에 attachmentCount 등을 업데이트하기 위한 콜백 */
  onAttachmentsUpdated?: (rfqId: number, newAttachmentCount: number) => void
  /** 강제 읽기 전용 모드 (파트너/벤더용) */
  readOnly?: boolean
}

export function TechSalesRfqAttachmentsSheet({
  defaultAttachments = [],
  onAttachmentsUpdated,
  rfq,
  readOnly = false,
  ...props
}: TechSalesRfqAttachmentsSheetProps) {
  const [isPending, setIsPending] = React.useState(false)

  // RFQ 상태에 따른 편집 가능 여부 결정 (readOnly prop이 true면 항상 false)
  const isEditable = React.useMemo(() => {
    if (!rfq || readOnly) return false
    // RFQ Created, RFQ Vendor Assignned 상태에서만 편집 가능
    return ["RFQ Created", "RFQ Vendor Assignned"].includes(rfq.status)
  }, [rfq, readOnly])

  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: upload.attachmentType,
          description: upload.description,
        }))

      // 실제 API 호출
      const result = await processTechSalesRfqAttachments({
        techSalesRfqId: rfq.id,
        newFiles,
        deleteAttachmentIds,
        createdBy: 1, // TODO: 실제 사용자 ID로 변경
      })

      if (result.error) {
        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)
      
      // 즉시 첨부파일 목록 새로고침
      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" | "VENDOR_SPECIFIC",
          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)
    }
  }

  return (
    <Sheet {...props}>
      <SheetContent className="flex flex-col gap-6 sm:max-w-md">
        <SheetHeader className="text-left">
          <SheetTitle>첨부파일 관리</SheetTitle>
          <SheetDescription>
            RFQ: {rfq?.rfqCode || "N/A"}
            {!isEditable && (
              <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 = field.attachmentType === "RFQ_COMMON" ? "공통" : "벤더별"
                const sizeText = field.fileSize ? prettyBytes(field.fileSize) : "알 수 없음"
                const dateText = field.createdAt ? formatDate(field.createdAt) : ""

                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 && (
                        <a
                          href={`/api/tech-sales-rfq-download?path=${encodeURIComponent(field.filePath)}`}
                          download={field.originalFileName || field.fileName}
                          className="inline-block"
                        >
                          <Button variant="ghost" size="icon" type="button" className="h-8 w-8">
                            <Download className="h-4 w-4" />
                          </Button>
                        </a>
                      )}
                      {/* Remove button - 편집 가능할 때만 표시 */}
                      {isEditable && (
                        <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 - 편집 가능할 때만 표시 */}
            {isEditable ? (
              <>
                <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>
                            
                            {/* 파일별 설정 */}
                            <div className="px-4 pb-3 space-y-3">
                              <FormField
                                control={form.control}
                                name={`newUploads.${idx}.attachmentType`}
                                render={({ field: formField }) => (
                                  <FormItem>
                                    <FormLabel className="text-xs">파일 타입</FormLabel>
                                    <Select onValueChange={formField.onChange} defaultValue={formField.value}>
                                      <FormControl>
                                        <SelectTrigger className="h-8">
                                          <SelectValue placeholder="파일 타입 선택" />
                                        </SelectTrigger>
                                      </FormControl>
                                      <SelectContent>
                                        <SelectItem value="RFQ_COMMON">공통 파일</SelectItem>
                                        {/* <SelectItem value="VENDOR_SPECIFIC">벤더별 파일</SelectItem> */}
                                      </SelectContent>
                                    </Select>
                                    <FormMessage />
                                  </FormItem>
                                )}
                              />
                            </div>
                          </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">
                  {isEditable ? "취소" : "닫기"}
                </Button>
              </SheetClose>
              {isEditable && (
                <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>
    </Sheet>
  )
} 