"use client"

import * as React from "react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Loader2, Check, ChevronsUpDown } from "lucide-react"
import { useForm } from "react-hook-form"
import { toast } from "sonner"
import { z } from "zod"

import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command"
import { Badge } from "@/components/ui/badge"
import { cn } from "@/lib/utils"

import { Tag } from "@/db/schema/vendorData"
import { updateTag, getSubfieldsByTagType, getClassOptions, TagTypeOption } from "@/lib/tags/service"

// SubFieldDef 인터페이스
interface SubFieldDef {
  name: string
  label: string
  type: "select" | "text"
  options?: { value: string; label: string }[]
  expression?: string
  delimiter?: string
}

// 클래스 옵션 인터페이스
interface UpdatedClassOption {
  code: string
  label: string
  tagTypeCode: string
  tagTypeDescription?: string
}

// UpdateTagSchema 정의
const updateTagSchema = z.object({
  class: z.string().min(1, "Class is required"),
  tagType: z.string().min(1, "Tag Type is required"),
  tagNo: z.string().min(1, "Tag Number is required"),
  description: z.string().optional(),
  // 추가 필드들은 동적으로 처리됨
})

// TypeScript 타입 정의
type UpdateTagSchema = z.infer<typeof updateTagSchema> & Record<string, string>

interface UpdateTagSheetProps extends React.ComponentPropsWithRef<typeof Sheet> {
  tag: Tag | null
  selectedPackageId: number
}

export function UpdateTagSheet({ tag, selectedPackageId, ...props }: UpdateTagSheetProps) {
  const [isUpdatePending, startUpdateTransition] = React.useTransition()
  const [tagTypeList, setTagTypeList] = React.useState<TagTypeOption[]>([])
  const [selectedTagTypeCode, setSelectedTagTypeCode] = React.useState<string | null>(null)
  const [subFields, setSubFields] = React.useState<SubFieldDef[]>([])
  const [classOptions, setClassOptions] = React.useState<UpdatedClassOption[]>([])
  const [classSearchTerm, setClassSearchTerm] = React.useState("")
  const [isLoadingClasses, setIsLoadingClasses] = React.useState(false)
  const [isLoadingSubFields, setIsLoadingSubFields] = React.useState(false)

  // ID management for popover elements
  const selectIdRef = React.useRef(0)
  const fieldIdsRef = React.useRef<Record<string, string>>({})
  const classOptionIdsRef = React.useRef<Record<string, string>>({})


  // Load class options when sheet opens
  React.useEffect(() => {
    const loadClassOptions = async () => {
      if (!props.open || !tag) return

      setIsLoadingClasses(true)
      try {
        const result = await getClassOptions(selectedPackageId)
        setClassOptions(result)
      } catch (err) {
        toast.error("클래스 옵션을 불러오는데 실패했습니다.")
      } finally {
        setIsLoadingClasses(false)
      }
    }

    loadClassOptions()
  }, [props.open, tag])

  // Form setup
  const form = useForm<UpdateTagSchema>({
    resolver: zodResolver(updateTagSchema),
    defaultValues: {
      class: "",
      tagType: "",
      tagNo: "",
      description: "",
    },
  })

  // Load tag data into form when tag changes
  React.useEffect(() => {
    if (!tag) return

    // 필요한 필드만 선택적으로 추출
    const formValues = {
      tagNo: tag.tagNo,
      tagType: tag.tagType,
      class: tag.class,
      description: tag.description || ""
      // 참고: 실제 태그 데이터에는 서브필드(functionCode, seqNumber 등)가 없음
    };

    // 폼 초기화
    form.reset(formValues)

    // 태그 타입 코드 설정 (추가 필드 로딩을 위해)
    if (tag.tagType) {
      // 해당 태그 타입에 맞는 클래스 옵션을 찾아서 태그 타입 코드 설정
      const foundClass = classOptions.find(opt => opt.label === tag.class)
      if (foundClass?.tagTypeCode) {
        setSelectedTagTypeCode(foundClass.tagTypeCode)
        loadSubFieldsByTagTypeCode(foundClass.tagTypeCode)
      }
    }
  }, [tag, classOptions, form])

  // Load subfields by tag type code
  async function loadSubFieldsByTagTypeCode(tagTypeCode: string) {
    setIsLoadingSubFields(true)
    try {
      const { subFields: apiSubFields } = await getSubfieldsByTagType(tagTypeCode, selectedPackageId)
      const formattedSubFields: SubFieldDef[] = apiSubFields.map(field => ({
        name: field.name,
        label: field.label,
        type: field.type,
        options: field.options || [],
        expression: field.expression ?? undefined,
        delimiter: field.delimiter ?? undefined,
      }))
      setSubFields(formattedSubFields)
      return true
    } catch (err) {
      toast.error("서브필드를 불러오는데 실패했습니다.")
      setSubFields([])
      return false
    } finally {
      setIsLoadingSubFields(false)
    }
  }

  // Handle class selection
  async function handleSelectClass(classOption: UpdatedClassOption) {
    form.setValue("class", classOption.label, { shouldValidate: true })

    if (classOption.tagTypeCode) {
      setSelectedTagTypeCode(classOption.tagTypeCode)

      // Set tag type
      const tagType = tagTypeList.find(t => t.id === classOption.tagTypeCode)
      if (tagType) {
        form.setValue("tagType", tagType.label, { shouldValidate: true })
      } else if (classOption.tagTypeDescription) {
        form.setValue("tagType", classOption.tagTypeDescription, { shouldValidate: true })
      }

      await loadSubFieldsByTagTypeCode(classOption.tagTypeCode)
    }
  }

  // Form submission handler
  function onSubmit(data: UpdateTagSchema) {
    startUpdateTransition(async () => {
      if (!tag) return

      try {
        // 기본 필드와 서브필드 데이터 결합
        const tagData = {
          id: tag.id,
          tagType: data.tagType,
          class: data.class,
          tagNo: data.tagNo,
          description: data.description,
          ...Object.fromEntries(
            subFields.map(field => [field.name, data[field.name] || ""])
          ),
        }

        const result = await updateTag(tagData, selectedPackageId)

        if ("error" in result) {
          toast.error(result.error)
          return
        }

        form.reset()
        props.onOpenChange?.(false)
        toast.success("태그가 성공적으로 업데이트되었습니다")
      } catch (error) {
        console.error("Error updating tag:", error)
        toast.error("태그 업데이트 중 오류가 발생했습니다")
      }
    })
  }

  // Render class field
  function renderClassField(field: any) {
    const [popoverOpen, setPopoverOpen] = React.useState(false)

    const buttonId = React.useMemo(
      () => `class-button-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
      []
    )
    const popoverContentId = React.useMemo(
      () => `class-popover-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
      []
    )
    const commandId = React.useMemo(
      () => `class-command-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
      []
    )

    return (
      <FormItem>
        <FormLabel>Class</FormLabel>
        <FormControl>
          <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
            <PopoverTrigger asChild>
              <Button
                key={buttonId}
                type="button"
                variant="outline"
                className="w-full justify-between relative h-9"
                disabled={isLoadingClasses}
              >
                {isLoadingClasses ? (
                  <>
                    <span>클래스 로딩 중...</span>
                    <Loader2 className="ml-2 h-4 w-4 animate-spin" />
                  </>
                ) : (
                  <>
                    <span className="truncate mr-1 flex-grow text-left">
                      {field.value || "클래스 선택..."}
                    </span>
                    <ChevronsUpDown className="h-4 w-4 opacity-50 flex-shrink-0" />
                  </>
                )}
              </Button>
            </PopoverTrigger>
            <PopoverContent key={popoverContentId} className="w-[300px] p-0">
              <Command key={commandId}>
                <CommandInput
                  key={`${commandId}-input`}
                  placeholder="클래스 검색..."
                  value={classSearchTerm}
                  onValueChange={setClassSearchTerm}
                />
                <CommandList key={`${commandId}-list`} className="max-h-[300px]">
                  <CommandEmpty key={`${commandId}-empty`}>검색 결과가 없습니다.</CommandEmpty>
                  <CommandGroup key={`${commandId}-group`}>
                    {classOptions.map((opt, optIndex) => {
                      if (!classOptionIdsRef.current[opt.code]) {
                        classOptionIdsRef.current[opt.code] =
                          `class-${opt.code}-${Date.now()}-${Math.random()
                            .toString(36)
                            .slice(2, 9)}`
                      }
                      const optionId = classOptionIdsRef.current[opt.code]

                      return (
                        <CommandItem
                          key={`${optionId}-${optIndex}`}
                          onSelect={() => {
                            field.onChange(opt.label)
                            setPopoverOpen(false)
                            handleSelectClass(opt)
                          }}
                          value={opt.label}
                          className="truncate"
                          title={opt.label}
                        >
                          <span className="truncate">{opt.label}</span>
                          <Check
                            key={`${optionId}-check`}
                            className={cn(
                              "ml-auto h-4 w-4 flex-shrink-0",
                              field.value === opt.label ? "opacity-100" : "opacity-0"
                            )}
                          />
                        </CommandItem>
                      )
                    })}
                  </CommandGroup>
                </CommandList>
              </Command>
            </PopoverContent>
          </Popover>
        </FormControl>
        <FormMessage />
      </FormItem>
    )
  }

  // Render TagType field (readonly)
  function renderTagTypeField(field: any) {
    return (
      <FormItem>
        <FormLabel>Tag Type</FormLabel>
        <FormControl>
          <div className="relative">
            <Input
              {...field}
              readOnly
              className="h-9 bg-muted"
            />
          </div>
        </FormControl>
        <FormMessage />
      </FormItem>
    )
  }

  // Render Tag Number field (readonly)
  function renderTagNoField(field: any) {
    return (
      <FormItem>
        <FormLabel>Tag Number</FormLabel>
        <FormControl>
          <div className="relative">
            <Input
              {...field}
              readOnly
              className="h-9 bg-muted font-mono"
            />
          </div>
        </FormControl>
        <FormMessage />
      </FormItem>
    )
  }

  // Render form fields for each subfield
  function renderSubFields() {
    if (isLoadingSubFields) {
      return (
        <div className="flex justify-center items-center py-4">
          <Loader2 className="h-6 w-6 animate-spin text-primary" />
          <div className="ml-3 text-muted-foreground">필드 로딩 중...</div>
        </div>
      )
    }

    if (subFields.length === 0) {
      return null
    }

    return (
      <div className="space-y-4">
        <div className="text-sm font-medium text-muted-foreground">추가 필드</div>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {subFields.map((sf, index) => (
            <FormField
              key={`subfield-${sf.name}-${index}`}
              control={form.control}
              name={sf.name}
              render={({ field }) => (
                <FormItem>
                  <FormLabel>{sf.label}</FormLabel>
                  <FormControl>
                    {sf.type === "select" ? (
                      <Select
                        value={field.value || ""}
                        onValueChange={field.onChange}
                      >
                        <SelectTrigger className="w-full h-9">
                          <SelectValue placeholder={`${sf.label} 선택...`} />
                        </SelectTrigger>
                        <SelectContent
                          align="start"
                          side="bottom"
                          className="max-h-[250px]"
                          style={{ minWidth: "250px", maxWidth: "350px" }}
                        >
                          {sf.options?.map((opt, optIndex) => (
                            <SelectItem
                              key={`${sf.name}-${opt.value}-${optIndex}`}
                              value={opt.value}
                              title={opt.label}
                              className="whitespace-normal py-2 break-words"
                            >
                              {opt.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    ) : (
                      <Input
                        {...field}
                        className="h-9"
                        placeholder={`${sf.label} 입력...`}
                      />
                    )}
                  </FormControl>
                  {sf.expression && (
                    <p className="text-xs text-muted-foreground mt-1" title={sf.expression}>
                      {sf.expression}
                    </p>
                  )}
                  <FormMessage />
                </FormItem>
              )}
            />
          ))}
        </div>
      </div>
    )
  }

  // 컴포넌트 렌더링
  return (
    <Sheet {...props}>
      {/* <SheetContent className="flex flex-col gap-0 sm:max-w-md overflow-y-auto"> */}
      <SheetContent className="flex flex-col gap-6 sm:max-w-lg overflow-y-auto">
        <SheetHeader className="text-left">
          <SheetTitle>태그 수정</SheetTitle>
          <SheetDescription>
            태그 정보를 업데이트하고 변경 사항을 저장하세요
          </SheetDescription>
        </SheetHeader>

        <div className="flex-1 overflow-y-auto py-4">
          <Form {...form}>
            <form
              id="update-tag-form"
              onSubmit={form.handleSubmit(onSubmit)}
              className="space-y-6"
            >
              {/* 기본 태그 정보 */}
              <div className="space-y-4">
                {/* Class */}
                <FormField
                  control={form.control}
                  name="class"
                  render={({ field }) => renderClassField(field)}
                />

                {/* Tag Type */}
                <FormField
                  control={form.control}
                  name="tagType"
                  render={({ field }) => renderTagTypeField(field)}
                />

                {/* Tag Number */}
                <FormField
                  control={form.control}
                  name="tagNo"
                  render={({ field }) => renderTagNoField(field)}
                />

                {/* Description */}
                <FormField
                  control={form.control}
                  name="description"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Description</FormLabel>
                      <FormControl>
                        <Input
                          {...field}
                          placeholder="태그 설명 입력..."
                          className="h-9"
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>

              {/* 서브필드 */}
              {renderSubFields()}
            </form>
          </Form>
        </div>

        <SheetFooter className="pt-2">
          <SheetClose asChild>
            <Button type="button" variant="outline">
              취소
            </Button>
          </SheetClose>
          <Button
            type="submit"
            form="update-tag-form"
            disabled={isUpdatePending || isLoadingSubFields}
          >
            {isUpdatePending ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />
                저장 중...
              </>
            ) : (
              "저장"
            )}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  )
}