"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 { Trash2, Plus, Loader, Download, X, Eye, AlertCircle } from "lucide-react"
import { useToast } from "@/hooks/use-toast"
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,
  FileListSize,
} from "@/components/ui/file-list"

import prettyBytes from "pretty-bytes"
import { processRfqAttachments } from "../service"
import { format } from "path"
import { formatDate } from "@/lib/utils"
import { RfqType } from "../validations"
import { RfqWithItemCount } from "@/db/schema/rfq"

const MAX_FILE_SIZE = 6e8 // 600MB

/** 기존 첨부 파일 정보 */
interface ExistingAttachment {
  id: number
  fileName: string
  filePath: string
  createdAt?: Date // or Date
  vendorId?: number | null
  size?: number
}

/** 새로 업로드할 파일 */
const newUploadSchema = z.object({
  fileObj: z.any().optional(), // 실제 File
})

/** 기존 첨부 (react-hook-form에서 관리) */
const existingAttachSchema = z.object({
  id: z.number(),
  fileName: z.string(),
  filePath: z.string(),
  vendorId: z.number().nullable().optional(),
  createdAt: z.custom<Date>().optional(),    // or use z.any().optional()
  size: z.number().optional(),
})

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

type AttachmentsFormValues = z.infer<typeof attachmentsFormSchema>

interface RfqAttachmentsSheetProps
  extends React.ComponentPropsWithRef<typeof Sheet> {
  defaultAttachments?: ExistingAttachment[]
  rfqType?: RfqType
  rfq: RfqWithItemCount | null
  /** 업로드/삭제 후 상위 테이블에 itemCount 등을 업데이트하기 위한 콜백 */
  onAttachmentsUpdated?: (rfqId: number, newItemCount: number) => void
}

/**
 * RfqAttachmentsSheet:
 * - 기존 첨부 목록 (다운로드 + 삭제)
 * - 새 파일 Dropzone
 * - Save 시 processRfqAttachments(server action)
 */
export function RfqAttachmentsSheet({
  defaultAttachments = [],
  onAttachmentsUpdated,
  rfq,
  rfqType,
  ...props
}: RfqAttachmentsSheetProps) {
  const { toast } = useToast()
  const [isPending, startUpdate] = React.useTransition()
  const rfqId = rfq?.rfqId ?? 0;
  
  // 편집 가능 여부 확인 - DRAFT 상태일 때만 편집 가능
  const isEditable = rfq?.status === "DRAFT";

  // React Hook Form
  const form = useForm<AttachmentsFormValues>({
    resolver: zodResolver(attachmentsFormSchema),
    defaultValues: {
      rfqId,
      existing: [],
      newUploads: [],
    },
  })

  const { reset, control, handleSubmit } = form

  // defaultAttachments가 바뀔 때마다, RHF 상태를 reset
  React.useEffect(() => {
    reset({
      rfqId,
      existing: defaultAttachments.map((att) => ({
        ...att,
        vendorId: att.vendorId ?? null,
        size: att.size ?? undefined,
      })),
      newUploads: [],
    })
  }, [rfqId, defaultAttachments, reset])

  // Field Arrays
  const {
    fields: existingFields,
    remove: removeExisting,
  } = useFieldArray({ control, name: "existing" })

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

  // 기존 첨부 항목 중 삭제된 것 찾기
  function findRemovedExistingIds(data: AttachmentsFormValues): number[] {
    const finalIds = data.existing.map((att) => att.id)
    const originalIds = defaultAttachments.map((att) => att.id)
    return originalIds.filter((id) => !finalIds.includes(id))
  }

  async function onSubmit(data: AttachmentsFormValues) {
    // 편집 불가능한 상태에서는 제출 방지
    if (!isEditable) return;
    
    startUpdate(async () => {
      try {
        const removedExistingIds = findRemovedExistingIds(data)
        const newFiles = data.newUploads
          .map((it) => it.fileObj)
          .filter((f): f is File => !!f)

        // 서버 액션
        const res = await processRfqAttachments({
          rfqId,
          removedExistingIds,
          newFiles,
          vendorId: null, // vendor ID if needed 
          rfqType
        })

        if (!res.ok) throw new Error(res.error ?? "Unknown error")

        const newCount = res.updatedItemCount ?? 0

        toast({
          variant: "default",
          title: "Success",
          description: "File(s) updated",
        })

        // 상위 테이블 등에 itemCount 업데이트
        onAttachmentsUpdated?.(rfqId, newCount)

        // 모달 닫기
        props.onOpenChange?.(false)
      } catch (err) {
        toast({
          variant: "destructive",
          title: "Error",
          description: String(err),
        })
      }
    })
  }

  /** 기존 첨부 - X 버튼 */
  function handleRemoveExisting(idx: number) {
    // 편집 불가능한 상태에서는 삭제 방지
    if (!isEditable) return;
    removeExisting(idx)
  }

  /** 드롭존에서 파일 받기 */
  function handleDropAccepted(acceptedFiles: File[]) {
    // 편집 불가능한 상태에서는 파일 추가 방지
    if (!isEditable) return;
    const mapped = acceptedFiles.map((file) => ({ fileObj: file }))
    appendNewUpload(mapped)
  }

  /** 드롭존에서 파일 거부(에러) */
  function handleDropRejected(fileRejections: any[]) {
    // 편집 불가능한 상태에서는 무시
    if (!isEditable) return;
    
    fileRejections.forEach((rej) => {
      toast({
        variant: "destructive",
        title: "File Error",
        description: rej.file.name + " not accepted",
      })
    })
  }

  return (
    <Sheet {...props}>
      <SheetContent className="flex flex-col gap-6 sm:max-w-sm">
        <SheetHeader>
          <SheetTitle className="flex items-center gap-2">
            {isEditable ? "Manage Attachments" : "View Attachments"}
            {rfq?.status && (
              <Badge 
                variant={rfq.status === "DRAFT" ? "outline" : "secondary"} 
                className="ml-1"
              >
                {rfq.status}
              </Badge>
            )}
          </SheetTitle>
          <SheetDescription>
            {`RFQ ${rfq?.rfqCode} - `}
            {isEditable ? '파일 첨부/삭제' : '첨부 파일 보기'}
            {!isEditable && (
              <div className="mt-1 text-xs flex items-center gap-1 text-amber-600">
                <AlertCircle className="h-3 w-3" />
                <span>드래프트 상태가 아닌 RFQ는 첨부파일을 수정할 수 없습니다.</span>
              </div>
            )}
          </SheetDescription>
        </SheetHeader>

        <Form {...form}>
          <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-4">
            {/* 1) 기존 첨부 목록 */}
            <div className="space-y-2">
              <p className="font-semibold text-sm">Existing Attachments</p>
              {existingFields.length === 0 && (
                <p className="text-sm text-muted-foreground">No existing attachments</p>
              )}
              {existingFields.map((field, index) => {
                const vendorLabel = field.vendorId ? "(Vendor)" : "(Internal)"
                return (
                  <div
                    key={field.id}
                    className="flex items-center justify-between rounded border p-2"
                  >
                    <div className="flex flex-col text-sm">
                      <span className="font-medium">
                        {field.fileName} {vendorLabel}
                      </span>
                      {field.size && (
                        <span className="text-xs text-muted-foreground">
                          {Math.round(field.size / 1024)} KB
                        </span>
                      )}
                      {field.createdAt && (
                        <span className="text-xs text-muted-foreground">
                          Created at {formatDate(field.createdAt)}
                        </span>
                      )}
                    </div>
                    <div className="flex items-center gap-2">
                      {/* 1) Download button (if filePath) */}
                      {field.filePath && (
                        <a
                          href={`/api/rfq-download?path=${encodeURIComponent(field.filePath)}`}
                          download={field.fileName}
                          className="text-sm"
                        >
                          <Button variant="ghost" size="icon" type="button">
                            <Download className="h-4 w-4" />
                          </Button>
                        </a>
                      )}
                      {/* 2) Remove button - 편집 가능할 때만 표시 */}
                      {isEditable && (
                        <Button
                          type="button"
                          variant="ghost"
                          size="icon"
                          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={control}
                      name="newUploads" // not actually used for storing each file detail
                      render={() => (
                        <FormItem>
                          <FormLabel>Drop Files Here</FormLabel>
                          <DropzoneZone className="flex justify-center">
                            <FormControl>
                              <DropzoneInput />
                            </FormControl>
                            <div className="flex items-center gap-6">
                              <DropzoneUploadIcon />
                              <div className="grid gap-0.5">
                                <DropzoneTitle>Drop to upload</DropzoneTitle>
                                <DropzoneDescription>
                                  Max size: {maxSize ? prettyBytes(maxSize) : "??? MB"}
                                </DropzoneDescription>
                              </div>
                            </div>
                          </DropzoneZone>
                          <FormDescription>Alternatively, click browse.</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  )}
                </Dropzone>

                {/* newUpload fields -> FileList */}
                {newUploadFields.length > 0 && (
                  <div className="grid gap-4">
                    <h6 className="font-semibold leading-none tracking-tight">
                      {`Files (${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">Remove</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">
                  {isEditable ? "Cancel" : "Close"}
                </Button>
              </SheetClose>
              {isEditable && (
                <Button 
                  type="submit" 
                  disabled={isPending || (form.getValues().newUploads.length === 0 && defaultAttachments.length === form.getValues().existing.length)}
                >
                  {isPending && <Loader className="mr-2 h-4 w-4 animate-spin" />}
                  Save
                </Button>
              )}
            </SheetFooter>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  )
}