"use client"

import * as React from "react"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"

import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover"
import {
  Command,
  CommandInput,
  CommandList,
  CommandGroup,
  CommandItem,
  CommandEmpty,
} from "@/components/ui/command"
import { Check, ChevronsUpDown, Loader, Copy } from "lucide-react"
import { cn } from "@/lib/utils"
import { toast } from "sonner"

import { cloneGtcDocumentSchema, type CloneGtcDocumentSchema } from "@/lib/gtc-contract/validations"
import { cloneGtcDocument, getAvailableProjectsForGtcExcluding, hasStandardGtcDocument } from "@/lib/gtc-contract/service"
import { type ProjectForFilter } from "@/lib/gtc-contract/service"
import { type GtcDocumentWithRelations } from "@/db/schema/gtc"
import { useSession } from "next-auth/react"
import { Input } from "@/components/ui/input"
import { useRouter } from "next/navigation"

interface CloneGtcDocumentDialogProps {
  sourceDocument: GtcDocumentWithRelations
  open?: boolean
  onOpenChange?: (open: boolean) => void
}

export function CloneGtcDocumentDialog({ 
  sourceDocument, 
  open: controlledOpen, 
  onOpenChange: controlledOnOpenChange 
}: CloneGtcDocumentDialogProps) {
  const [internalOpen, setInternalOpen] = React.useState(false)
  const [projects, setProjects] = React.useState<ProjectForFilter[]>([])
  const [isClonePending, startCloneTransition] = React.useTransition()
  const { data: session } = useSession()
  const router = useRouter()
  const [defaultType, setDefaultType] = React.useState<"standard" | "project">("standard")

  const isControlled = controlledOpen !== undefined
  const open = isControlled ? controlledOpen! : internalOpen
  const setOpen = isControlled ? controlledOnOpenChange! : setInternalOpen

  const currentUserId = React.useMemo(() => {
    return session?.user?.id ? Number(session.user.id) : null
  }, [session])




  const form = useForm<CloneGtcDocumentSchema>({
    resolver: zodResolver(cloneGtcDocumentSchema),
    defaultValues: {
      sourceDocumentId: sourceDocument.id,
      type: sourceDocument.type,
      projectId: sourceDocument.projectId,
      title: sourceDocument.title || "",
      editReason: "",
    },
  })

  const resetForm = React.useCallback((type: "standard" | "project") => {
    form.reset({
      sourceDocumentId: sourceDocument.id,
      type,
      projectId: sourceDocument.projectId,
      title: sourceDocument.title || "",
      editReason: "",
    })
  }, [form, sourceDocument])

  React.useEffect(() => {
    if (open) {
      // 표준 GTC 존재 여부와 사용 가능한 프로젝트 동시 조회
      Promise.all([
        hasStandardGtcDocument(),
        getAvailableProjectsForGtcExcluding(sourceDocument.projectId || undefined)
      ]).then(([hasStandard, availableProjects]) => {
        const initialType = hasStandard ? "project" : "standard"
        setDefaultType(initialType)
        setProjects(availableProjects)
        
        // 폼 기본값 설정: 원본 문서 타입을 우선으로 하되, 표준이 이미 있고 원본도 표준이면 프로젝트로 변경
        const targetType = hasStandard && sourceDocument.type === "standard" ? "project" : sourceDocument.type
        resetForm(targetType)
      })
    }
  }, [open, sourceDocument.projectId, sourceDocument.type, resetForm])


  const watchedType = form.watch("type")

  React.useEffect(() => {
    // 소스 문서가 변경되면 폼 기본값 업데이트 (다이얼로그가 열려있을 때만)
    if (open) {
      hasStandardGtcDocument().then((hasStandard) => {
        const targetType = hasStandard && sourceDocument.type === "standard" ? "project" : sourceDocument.type
        resetForm(targetType)
      })
    }
  }, [sourceDocument, resetForm, open])

  async function onSubmit(data: CloneGtcDocumentSchema) {
    startCloneTransition(async () => {
      if (!currentUserId) {
        toast.error("로그인이 필요합니다")
        return
      }

      try {
        const result = await cloneGtcDocument({
          ...data,
          createdById: currentUserId
        })

        if (result.error) {
          toast.error(`에러: ${result.error}`)
          return
        }

        resetForm(sourceDocument.type)
        setOpen(false)
        router.refresh()

        toast.success("GTC 문서가 복제되었습니다.")
      } catch (error) {
        toast.error("문서 복제 중 오류가 발생했습니다.")
      }
    })
  }

  function handleDialogOpenChange(nextOpen: boolean) {
    if (!nextOpen) {
      // 다이얼로그 닫을 때는 원본 문서 정보로 리셋
      resetForm(sourceDocument.type)
    }
    setOpen(nextOpen)
  }

  const DialogWrapper = isControlled ? React.Fragment : Dialog

  return (
    <DialogWrapper>
      {!isControlled && (
        <DialogTrigger asChild>
          <Button variant="outline" size="sm">
            <Copy className="mr-2 h-4 w-4" />
            복제하기
          </Button>
        </DialogTrigger>
      )}

      <Dialog open={open} onOpenChange={handleDialogOpenChange}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>GTC 문서 복제</DialogTitle>
            <DialogDescription>
              기존 문서를 복제하여 새로운 문서를 생성합니다. <br />
              <span className="font-medium text-foreground">
                원본: {sourceDocument.title || `${sourceDocument.type === 'standard' ? '표준' : '프로젝트'} GTC v${sourceDocument.revision}`}
              </span>
            </DialogDescription>
          </DialogHeader>

          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)}>
              <div className="space-y-4 py-4">
                {/* 구분 (Type) */}
                <FormField
                  control={form.control}
                  name="type"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>구분</FormLabel>
                      <FormControl>
                        <Select
                          onValueChange={(value) => {
                            field.onChange(value)
                            // 표준으로 변경시 프로젝트 ID 초기화
                            if (value === "standard") {
                              form.setValue("projectId", null)
                            }
                          }}
                          value={field.value}
                        >
                          <SelectTrigger>
                            <SelectValue placeholder="구분을 선택하세요" />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="standard">표준</SelectItem>
                            <SelectItem value="project">프로젝트</SelectItem>
                          </SelectContent>
                        </Select>
                      </FormControl>
                      {defaultType === "project" && sourceDocument.type === "standard" && (
                        <FormDescription>
                          표준 GTC 문서가 이미 존재합니다. 복제시에는 프로젝트 타입을 권장합니다.
                        </FormDescription>
                      )}
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {/* 프로젝트 선택 (프로젝트 타입인 경우만) */}
                {watchedType === "project" && (
                  <FormField
                    control={form.control}
                    name="projectId"
                    render={({ field }) => {
                      const selectedProject = projects.find(
                        (p) => p.id === field.value
                      )
                      const [popoverOpen, setPopoverOpen] = React.useState(false)

                      return (
                        <FormItem>
                          <FormLabel>프로젝트</FormLabel>
                          <FormControl>
                            <Popover
                              open={popoverOpen}
                              onOpenChange={setPopoverOpen}
                              modal={true}
                            >
                              <PopoverTrigger asChild>
                                <Button
                                  variant="outline"
                                  role="combobox"
                                  aria-expanded={popoverOpen}
                                  className="w-full justify-between"
                                >
                                  {selectedProject
                                    ? `${selectedProject.name} (${selectedProject.code})`
                                    : "프로젝트를 선택하세요..."}
                                  <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                                </Button>
                              </PopoverTrigger>

                              <PopoverContent className="w-full p-0">
                                <Command>
                                  <CommandInput
                                    placeholder="프로젝트 검색..."
                                    className="h-9"
                                  />
                                  <CommandList>
                                    <CommandEmpty>
                                      {projects.length === 0 
                                        ? "사용 가능한 프로젝트가 없습니다."
                                        : "프로젝트를 찾을 수 없습니다."
                                      }
                                    </CommandEmpty>
                                    <CommandGroup>
                                      {projects.map((project) => {
                                        const label = `${project.name} (${project.code})`
                                        return (
                                          <CommandItem
                                            key={project.id}
                                            value={label}
                                            onSelect={() => {
                                              field.onChange(project.id)
                                              setPopoverOpen(false)
                                            }}
                                          >
                                            {label}
                                            <Check
                                              className={cn(
                                                "ml-auto h-4 w-4",
                                                selectedProject?.id === project.id
                                                  ? "opacity-100"
                                                  : "opacity-0"
                                              )}
                                            />
                                          </CommandItem>
                                        )
                                      })}
                                    </CommandGroup>
                                  </CommandList>
                                </Command>
                              </PopoverContent>
                            </Popover>
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )
                    }}
                  />
                )}

                <FormField
                  control={form.control}
                  name="title"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>GTC 제목 (선택사항)</FormLabel>
                      <FormControl>
                        <Input
                          placeholder="GTC 제목을 입력하세요..."
                          {...field}
                        />
                      </FormControl>
                      <FormDescription>
                        워드의 제목으로 사용됩니다.
                      </FormDescription>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                {/* 편집 사유 */}
                <FormField
                  control={form.control}
                  name="editReason"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>복제 사유 (선택사항)</FormLabel>
                      <FormControl>
                        <Textarea
                          placeholder="복제 사유를 입력하세요..."
                          {...field}
                          rows={3}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>

              <DialogFooter>
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => setOpen(false)}
                  disabled={isClonePending}
                >
                  Cancel
                </Button>
                <Button type="submit" disabled={isClonePending}>
                  {isClonePending && (
                    <Loader
                      className="mr-2 size-4 animate-spin"
                      aria-hidden="true"
                    />
                  )}
                  복제하기
                </Button>
              </DialogFooter>
            </form>
          </Form>
        </DialogContent>
      </Dialog>
    </DialogWrapper>
  )
}