'use client'

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import { Button, IconButton } from '@/components/ui/button'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Textarea } from '@/components/ui/textarea'
import { useParams, useRouter } from 'next/navigation'
import {
  useCreateAI,
  useCreateDict,
  useEditAI,
  useEditFormStorage,
  useGenerateContent,
  useGetAI,
} from '@/hooks/create'
import { useEffect, useState } from 'react'
import Image from 'next/image'
import AIGenerateButton from '@/components/features/ai-generate-button'
import { Chip } from '@/components/ui/chip'
import ImageSelector from '@/app/(main)/create/components/ImageSelector'
import { AvatarCropModal } from '@/components/ui/avatar-crop-modal'
import { AIPermission, CreateOrEditAiRequest, PtType } from '@/services/create'
import CopyrightRuleModal from '@/app/(main)/create/components/CopyrightRuleModal'
import { BizTypeEnum } from '@/services/common'
import ProgressIndicator from '@/app/(main)/create/components/ProgessIndicator'
import CloseIconButton from '@/app/(main)/edit/[aiId]/components/CloseIconButton'
import { useMainLayout } from '@/context/mainLayout'
import { cn } from '@/lib/utils'
import { useCheckText } from '@/hooks/auth'

// 表单验证模式
const imageFormSchema = z
  .object({
    imageUrl: z.string(),
    avatarUrl: z.string(),
    intro: z
      .string()
      .min(10, 'Please enter at least 10 characters')
      .max(400, 'Please enter less than 400 characters'),
    isPublic: z.boolean(),
    imageStyleCode: z.number().optional(),
    imageDesc: z.string().optional(),
  })
  .refine(
    (data) => {
      return !!data.imageUrl && !!data.avatarUrl
    },
    {
      message: 'Please upload or generate an image',
      path: ['imageUrl', 'avatarUrl'],
    }
  )

type ImageFormValues = {
  imageUrl: string
  avatarUrl: string
  intro: string
  isPublic: boolean
  imageStyleCode?: number
  imageDesc?: string
}

type ImageFormSchemaType = z.infer<typeof imageFormSchema>

export default function ImageForm() {
  const { aiId } = useParams<{ aiId: string }>()
  const router = useRouter()
  const { updateImageData, getImageData, formData, isFormDataEmpty, clearFormData } =
    useEditFormStorage()
  const { mutateAsync: generateContent, isPending: isGeneratingContent } = useGenerateContent()
  const { mutateAsync: createAI } = useEditAI(Number(aiId))
  const { data: dict } = useCreateDict()
  const { data: ai } = useGetAI(Number(aiId))
  const { isSidebarExpanded } = useMainLayout()

  const [showCropModal, setShowCropModal] = useState(false)
  const [showCopyrightRuleModal, setShowCopyrightRuleModal] = useState(false)
  const [loading, setLoading] = useState(false)
  const savedData = getImageData()
  const { mutateAsync: checkText } = useCheckText()

  const form = useForm<ImageFormSchemaType>({
    resolver: zodResolver(imageFormSchema),
    defaultValues: {
      imageUrl: savedData?.imageUrl || undefined,
      avatarUrl: savedData?.avatarUrl || undefined,
      intro: savedData?.intro || '',
      isPublic: savedData?.isPublic ?? true,
      imageStyleCode: Number(savedData?.imageStyleCode) || undefined,
      imageDesc: savedData?.imageDesc || undefined,
    },
  })
  const watchImageUrl = form.watch('imageUrl')
  const imageUrl = form.watch('imageUrl')

  useEffect(() => {
    if (ai && isFormDataEmpty({ checkEnum: 'image' })) {
      const imageStyleCode = ai?.aiUserExt?.imageStyleCode
        ? Number(ai.aiUserExt.imageStyleCode)
        : undefined
      const imageDesc = ai?.aiUserExt?.imageDesc || undefined

      form.reset({
        imageUrl: ai.imageUrl || '',
        avatarUrl: ai.headImg || '',
        intro: ai.introduction || '',
        isPublic: ai.permission === AIPermission.Public ? true : false,
        imageStyleCode,
        imageDesc,
      })
      updateImageData({
        imageUrl: ai.imageUrl || '',
        avatarUrl: ai.headImg || '',
        intro: ai.introduction || '',
        isPublic: ai.permission === AIPermission.Public ? true : false,
        imageStyleCode,
        imageDesc,
      })
    }
  }, [ai, isFormDataEmpty])

  useEffect(() => {
    if (isFormDataEmpty({ checkEnum: 'all' })) {
      router.push(`/edit/${aiId}/type`)
    }
  }, [isFormDataEmpty])

  // 当从图片编辑页面返回时，更新表单的 imageUrl, avatarUrl, imageStyleCode, imageDesc
  useEffect(() => {
    const currentFormImageUrl = form.getValues('imageUrl')
    const currentFormAvatarUrl = form.getValues('avatarUrl')

    // 如果 localStorage 中的图片 URL 与表单中的不一致，说明用户刚从图片编辑页面返回
    if (savedData?.imageUrl && savedData.imageUrl !== currentFormImageUrl) {
      form.setValue('imageUrl', savedData.imageUrl)
    }
    if (savedData?.avatarUrl && savedData.avatarUrl !== currentFormAvatarUrl) {
      form.setValue('avatarUrl', savedData.avatarUrl)
    }
    if (savedData?.imageStyleCode !== undefined) {
      form.setValue('imageStyleCode', savedData.imageStyleCode)
    }
    if (savedData?.imageDesc !== undefined) {
      form.setValue('imageDesc', savedData.imageDesc)
    }
  }, [savedData?.imageUrl, savedData?.avatarUrl, savedData?.imageStyleCode, savedData?.imageDesc])

  // 监听表单变化，自动暂存数据
  useEffect(() => {
    const subscription = form.watch((data) => {
      if (data.imageUrl || data.avatarUrl || data.intro || data.isPublic !== undefined) {
        updateImageData({
          imageUrl: data.imageUrl || '',
          avatarUrl: data.avatarUrl || '',
          intro: data.intro || '',
          isPublic: data.isPublic ?? true,
          imageStyleCode: data.imageStyleCode,
          imageDesc: data.imageDesc,
        })
      }
    })
    return () => {
      subscription.unsubscribe()
    }
  }, [form, updateImageData])

  const handleImageEditRouter = () => {
    if (loading) return
    router.push(`/generate/image-edit?id=${aiId}`)
  }

  function onSubmit(data: ImageFormValues) {
    // setShowCopyrightRuleModal(true)
    handleConfirm()
  }

  const handleConfirm = async () => {
    setLoading(true)
    try {
      const { type, character, dialogue, image } = formData
      const timbreDictList = dict?.timbreDictList || []
      const timbreDict = timbreDictList.find(
        (item) => item.code === dialogue?.aiUserExt?.voice?.content
      )
      const { url } = timbreDict || {}
      const { intro, isPublic, avatarUrl, imageUrl, imageStyleCode, imageDesc } = image || {}

      // 如果用户profile和ai的profile相同，则使用ai增强的profile,否则使用用户的profile
      const isSameUserProfile = ai?.aiUserExt?.userProfile === character?.aiUserExt?.userProfile
      // 如果用户对话风格和ai的对话风格相同，则使用ai增强的对话风格,否则使用用户的对话风格
      const isSameUserDialogueStyle =
        ai?.aiUserExt?.userDialogueStyle === dialogue?.aiUserExt?.userDialogueStyle

      if (intro) {
        const resp = await checkText({
          content: intro,
        })
        if (resp) {
          form.setError('intro', {
            message: resp,
          })
          return
        }
      }

      // 当 profile 不同需要重新生成
      let extractJsonResp = null
      if (!isSameUserProfile) {
        const resp = await generateContent({
          ptType: PtType.ExtractJsonContent,
          figure: character?.aiUserExt?.userProfile,
        })
        extractJsonResp = resp?.content
      }

      const result = {
        aiId: Number(aiId),
        ...type,
        ...character,
        headImg: avatarUrl,
        birthday: new Date(character?.birthday || '').getTime(),
        imageUrl,
        introduction: intro,
        permission: isPublic ? AIPermission.Public : AIPermission.Private,
        imageHeight: 1024,
        imageWidth: 1024,
        aiUserExt: {
          profile: isSameUserProfile ? ai?.aiUserExt?.profile : character?.aiUserExt?.userProfile,
          userProfile: character?.aiUserExt?.userProfile,
          dialogueStyle: isSameUserDialogueStyle
            ? ai?.aiUserExt?.dialogueStyle
            : dialogue?.aiUserExt?.userDialogueStyle,
          userDialogueStyle: dialogue?.aiUserExt?.userDialogueStyle,
          dialoguePrologue: dialogue?.aiUserExt?.prologue,
          dialogueTimbreCode: dialogue?.aiUserExt?.voice?.content,
          dialoguePitch: dialogue?.aiUserExt?.voice?.tone,
          dialogueSpeechRate: dialogue?.aiUserExt?.voice?.speed,
          dialogueTimbreUrl: url,
          imageStyleCode,
          imageDesc,
          ...(extractJsonResp && { userProfileExtJson: extractJsonResp }),
        },
      }
      await createAI(result as unknown as CreateOrEditAiRequest)
      router.push(`/@${aiId}`)
      clearFormData()
    } catch (error) {
      console.error(error)
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="mx-auto flex w-[752px] flex-col gap-6 pt-[111px] pb-[200px]">
      {/* 标题区域 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <IconButton
            variant="ghost"
            size="small"
            onClick={() => router.back()}
            className="h-8 w-8 rounded-full p-2 hover:bg-white/10"
          >
            <i className="iconfont icon-arrow-left text-white" />
          </IconButton>
          <h1 className="text-2xl leading-7 font-semibold text-white">Edit Character</h1>
        </div>
        <CloseIconButton />
      </div>

      {/* 进度指示器 */}
      <ProgressIndicator currentStep={4} totalSteps={4} />

      {/* 主要内容区域 */}
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
          <div className="flex flex-col gap-6 rounded-2xl bg-[#352e3e] p-6">
            <div className="flex flex-col gap-6">
              <h2 className="text-xl leading-6 font-semibold text-white">Image</h2>

              {/* 图片上传/预览区域 */}
              <FormField
                control={form.control}
                name="imageUrl"
                render={({ field }) => (
                  <FormItem>
                    <div className="flex items-center justify-between">
                      <FormLabel className="txt-label-m">Image</FormLabel>
                      {watchImageUrl && (
                        <div
                          className="txt-label-m text-primary-variant-normal cursor-pointer"
                          onClick={handleImageEditRouter}
                        >
                          Regenerate
                        </div>
                      )}
                    </div>
                    <FormControl>
                      <ImageSelector
                        value={field.value}
                        onChange={field.onChange}
                        onImageRouter={handleImageEditRouter}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              {watchImageUrl && (
                <FormField
                  control={form.control}
                  name="avatarUrl"
                  render={({ field }) => (
                    <FormItem>
                      <div className="">
                        <div className="flex items-center justify-between">
                          <FormLabel className="txt-label-m">Avatar</FormLabel>
                          {imageUrl && (
                            <div
                              className="txt-label-m text-primary-variant-normal cursor-pointer"
                              onClick={() => {
                                if (loading) return
                                setShowCropModal(true)
                              }}
                            >
                              Crop
                            </div>
                          )}
                        </div>
                        <FormControl>
                          {field.value ? (
                            <Image
                              src={field.value}
                              alt="Avatar"
                              width={80}
                              height={80}
                              className="mt-3 h-20 w-20 rounded-full object-cover"
                            />
                          ) : (
                            <div className="bg-surface-element-normal border-outline-normal mt-3 flex h-20 w-20 items-center justify-center rounded-full border-2 border-dashed">
                              <i className="iconfont icon-user text-txt-secondary-normal text-xl" />
                            </div>
                          )}
                        </FormControl>
                      </div>
                    </FormItem>
                  )}
                />
              )}

              {/* 简介输入 */}
              <FormField
                control={form.control}
                name="intro"
                render={({ field }) => (
                  <FormItem>
                    <div className="flex items-center justify-between">
                      <FormLabel className="txt-label-m">Introduction</FormLabel>
                      <AIGenerateButton
                        showAlert={!!field.value.trim()}
                        disabled={loading}
                        onConfirm={async () => {
                          const resp = await generateContent({
                            ptType: PtType.GenAIIntroduction,
                            nickname: formData.character?.nickname || '',
                            sex: formData.character?.sex || 0,
                            birthday: formData.character?.birthday || '',
                            characterCode: formData.type.characterCode,
                            tagCode: formData.type.tagCode,
                            figure: formData.character?.aiUserExt?.userProfile || '',
                            dialogue: formData.dialogue?.aiUserExt?.userDialogueStyle || '',
                          })
                          if (resp) {
                            form.setValue('intro', resp.content || '')
                          }
                        }}
                        loading={isGeneratingContent}
                      />
                    </div>
                    <FormControl>
                      <Textarea
                        placeholder="Introduce the virtual character to the user"
                        maxLength={400}
                        showCount
                        error={!!form.formState.errors.intro}
                        {...field}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              {/* 隐私设置 */}
              <FormField
                control={form.control}
                name="isPublic"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="">Private</FormLabel>
                    <div className="flex gap-3">
                      <Chip
                        state={field.value ? 'active' : 'inactive'}
                        onClick={() => form.setValue('isPublic', true)}
                      >
                        <i className="iconfont icon-eye-on" />
                        Public
                      </Chip>
                      <Chip
                        state={!field.value ? 'active' : 'inactive'}
                        onClick={() => form.setValue('isPublic', false)}
                      >
                        <i className="iconfont icon-eye-off" />
                        Private
                      </Chip>
                    </div>
                  </FormItem>
                )}
              />
            </div>
          </div>

          {/* 底部导航栏 */}
          <div
            className={cn(
              'fixed right-0 bottom-0 backdrop-blur-[32px]',
              isSidebarExpanded ? 'left-[319px]' : 'left-20'
            )}
          >
            <div className="bg-background-default absolute inset-0 opacity-65" />
            <div className="relative flex items-center justify-center px-12 py-6">
              <div className="flex w-full max-w-[752px] items-center justify-between gap-4">
                <div className="flex items-center justify-start"></div>
                <div className="flex items-center justify-end">
                  <Button type="submit" disabled={!imageUrl} loading={loading}>
                    Submit
                  </Button>
                </div>
              </div>
            </div>
          </div>
        </form>
      </Form>

      {/* 头像裁剪弹窗 */}
      {imageUrl && (
        <AvatarCropModal
          isOpen={showCropModal}
          bizType={BizTypeEnum.Album}
          onClose={() => setShowCropModal(false)}
          image={imageUrl}
          onConfirm={(croppedImageUrl) => {
            form.setValue('avatarUrl', croppedImageUrl)
            setShowCropModal(false)
          }}
          onCancel={() => setShowCropModal(false)}
        />
      )}

      <CopyrightRuleModal
        isOpen={showCopyrightRuleModal}
        onOpenChange={setShowCopyrightRuleModal}
        onConfirm={handleConfirm}
      />
    </div>
  )
}
