'use client'

import React, { createContext, useContext, useEffect, useRef, useState } from 'react'
import { UseFormReturn, ControllerRenderProps } from 'react-hook-form'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
} from '@/components/ui/drawer'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { useIsMobile } from '@/hooks/use-mobile'
import { cn } from '@/lib/utils'
import { Loader2 } from 'lucide-react'
import { Skeleton } from '@/components/ui/skeleton'

// FormDialog Context
export interface FormDialogContextValue {
  form: UseFormReturn<any>
  close: () => void
  fields: FormFieldConfig[]
  isLoading?: boolean
}

const FormDialogContext = createContext<FormDialogContextValue | null>(null)

export function useFormDialogContext() {
  const context = useContext(FormDialogContext)
  if (!context) {
    throw new Error('useFormDialogContext must be used within FormDialog')
  }
  return context
}

// 字段配置类型定义
export interface FormFieldConfig {
  name: string
  label: string
  required?: boolean
  render: (props: { field: ControllerRenderProps<any, any> }) => React.ReactNode // 将...field传递给UI控件交给react-hook-form管理
  className?: string // 允许为单个字段指定自定义样式
}

// 取消按钮组件
export interface FormCancelActionProps extends Omit<React.ComponentProps<typeof Button>, 'onClick' | 'type'> {
  children?: React.ReactNode
  onCancel?: () => void
}

export function FormCancelAction({ children = '取消', variant = 'outline', onCancel, ...props }: FormCancelActionProps) {
  const { close } = useFormDialogContext()
  
  const handleClick = () => {
    if (onCancel) {
      onCancel()
    } else {
      close()
    }
  }
  
  return (
    <Button type="button" variant={variant} onClick={handleClick} disabled={props.disabled} {...props}>
      {children}
    </Button>
  )
}

// 重置按钮组件
export interface FormResetActionProps extends Omit<React.ComponentProps<typeof Button>, 'onClick' | 'type'> {
  children?: React.ReactNode
  onReset?: () => void
  confirmTitle?: string
  confirmDescription?: string
}

export function FormResetAction({
  children = '重置',
  variant = 'outline',
  onReset,
  confirmTitle = '确认重置',
  confirmDescription = '确定要重置表单吗？表单将回到打开时的状态。',
  ...props
}: FormResetActionProps) {
  const { form, isLoading } = useFormDialogContext()
  const [showConfirm, setShowConfirm] = useState(false)
  
  const handleConfirm = () => {
    if (onReset) {
      onReset()
    } else {
      form.reset()
    }
    setShowConfirm(false)
  }
  
  return (
    <>
      <Button type="button" variant={variant} onClick={() => setShowConfirm(true)} disabled={isLoading || props.disabled} {...props}>
        {children}
      </Button>
      
      <AlertDialog open={showConfirm} onOpenChange={setShowConfirm}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{confirmTitle}</AlertDialogTitle>
            <AlertDialogDescription>{confirmDescription}</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleConfirm}>确认</AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}

// 提交按钮组件
export interface FormSubmitActionProps extends Omit<React.ComponentProps<typeof Button>, 'onClick' | 'type'> {
  onSubmit: (data: any) => Promise<void> | void
  children?: React.ReactNode
  disabled?: boolean
  isSubmitting?: boolean
  showSpinningLoader?: boolean
}

export function FormSubmitAction({
  onSubmit,
  children = '提交',
  disabled = false,
  isSubmitting = false,
  showSpinningLoader = true,
  variant = 'default',
  ...props
}: FormSubmitActionProps) {
  const { form, isLoading } = useFormDialogContext()
  
  return (
    <Button
      type="button"
      variant={variant}
      onClick={form.handleSubmit(onSubmit)}
      disabled={isSubmitting || disabled || isLoading}
      {...props}
    >
      {children}
      {isSubmitting && showSpinningLoader && <Loader2 className="ml-2 h-4 w-4 animate-spin" />}
    </Button>
  )
}

// 操作按钮栏组件
export interface FormActionBarProps {
  children?: React.ReactNode
}

export function FormActionBar({ children }: FormActionBarProps) {
  return (
    <div className="flex justify-end space-x-2">
      {children}
    </div>
  )
}

// FormGridContent 组件
export interface FormGridContentProps {
  className?: string
}

export function FormGridContent({ className = 'grid grid-cols-1 gap-4' }: FormGridContentProps) {
  const { form, fields, isLoading } = useFormDialogContext()
  
  // 如果正在加载，显示骨架屏
  if (isLoading) {
    return (
      <div className={cn("p-1", className)}>
        {fields.map((fieldConfig) => (
          <div key={fieldConfig.name} className={cn("space-y-2", fieldConfig.className || '')}>
            <Skeleton className="h-4 w-20" />
            <Skeleton className="h-10 w-full" />
          </div>
        ))}
      </div>
    )
  }
  
  return (
    <div className={cn("p-1", className)}>
      {fields.map((fieldConfig) => (
        <FormField
          key={fieldConfig.name}
          control={form.control}
          name={fieldConfig.name}
          render={({ field }) => (
            <FormItem className={fieldConfig.className || ''}>
              <FormLabel className="flex items-center gap-1">
                {fieldConfig.label}
                {fieldConfig.required && <span className="text-red-500">*</span>}
              </FormLabel>
              <FormControl>
                {fieldConfig.render({ field })}
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
      ))}
    </div>
  )
}

export interface FormDialogProps {
  isOpen: boolean
  title: string
  description: string
  form: UseFormReturn<any>
  fields: FormFieldConfig[]
  onClose: () => void
  className?: string // 允许自定义对话框内容样式，可控制宽度
  formClassName?: string // 允许自定义表格样式
  children: React.ReactNode // 操作按钮区域内容
  isLoading?: boolean // 是否正在加载数据
}

export function FormDialog({
  isOpen,
  title,
  description,
  form,
  fields,
  onClose,
  className = 'max-w-md',
  formClassName,
  children,
  isLoading = false,
}: FormDialogProps) {
  const isMobile = useIsMobile()
  const formRef = useRef<HTMLFormElement>(null)

  // 当对话框打开时，自动聚焦到第一个表单输入控件
  useEffect(() => {
    if (isOpen && !isLoading) {
      // 使当前拥有焦点的元素（通常是用来触发打开这个drawer的控件）失去焦点，不然控制台会警告焦点在一个要被隐藏于屏幕阅读器的控件上
      (document.activeElement as HTMLElement)?.blur();
      // 使用 setTimeout 确保 DOM 已完全渲染
      const timer = setTimeout(() => {
        if (formRef.current) {
          // 查找第一个可聚焦的输入元素
          const firstInput = formRef.current.querySelector<HTMLElement>(
            'input:not([type="hidden"]):not([disabled]), textarea:not([disabled]), select:not([disabled])'
          )
          if (firstInput) {
            firstInput.focus()
          }
        }
      }, 100)

      return () => clearTimeout(timer)
    }
  }, [isOpen, isLoading])

  const close = () => {
    onClose()
  }

  // Context 值
  const contextValue: FormDialogContextValue = {
    form,
    close,
    fields,
    isLoading
  }

  // 表单内容组件，在 Dialog 和 Drawer 中复用
  const formContent = (
    <FormDialogContext.Provider value={contextValue}>
      <Form {...form}>
        <form ref={formRef} className={cn("space-y-6", formClassName)}>
          {children}
        </form>
      </Form>
    </FormDialogContext.Provider>
  )

  // 根据设备类型渲染不同的组件
  if (isMobile) {
    return (
      <Drawer open={isOpen} onOpenChange={(open) => !open && close()}>
        <DrawerContent className={className}>
          <DrawerHeader>
            <DrawerTitle>{title}</DrawerTitle>
            <DrawerDescription>{description}</DrawerDescription>
          </DrawerHeader>
          <div className="px-4 pb-4 overflow-y-auto max-h-[70vh]">
            {formContent}
          </div>
        </DrawerContent>
      </Drawer>
    )
  }

  return (
    <Dialog open={isOpen} onOpenChange={(open) => !open && close()}>
      <DialogContent className={className} showCloseButton={false}>
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>
        <div className='overflow-y-auto max-h-[70vh]'>
          {formContent}
        </div>
      </DialogContent>
    </Dialog>
  )
}
