import { DevTool } from '@hookform/devtools'
import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect, useState } from 'react'
import { useFetcher, useNavigate, useRouteLoaderData } from 'react-router'
import { RemixFormProvider, useRemixForm } from 'remix-hook-form'
import { z } from 'zod'

import { TextEditor } from '~/components/text-editor'
import { Button } from '~/components/ui/button'
import { Combobox } from '~/components/ui/combobox'
import { Input } from '~/components/ui/input'
import { Switch } from '~/components/ui/switch'
import { TitleDashboard } from '~/components/ui/title-dashboard'
import type { loader } from '~/routes/_admin.lg-admin'

export const contentSchema = z.object({
  categories: z
    .array(
      z
        .object({
          id: z.string(),
          code: z.string(),
          name: z.string(),
        })
        .optional()
        .nullable(),
    )
    .refine((data) => data.length, {
      message: 'Please select a category',
    }),
  tags: z
    .array(
      z
        .object({
          id: z.string(),
          code: z.string(),
          name: z.string(),
        })
        .optional()
        .nullable(),
    )
    .optional(),
  title: z.string().min(1, {
    message: 'Judul is required',
  }),
  content: z.string().min(1, {
    message: 'Konten is required',
  }),
  featured_image: z.string().optional(),
  is_premium: z.boolean().optional(),
  live_at: z.string().min(1, {
    message: 'Tanggal live is required',
  }),
})

export type TContentSchema = z.infer<typeof contentSchema>

export const CreateContentsPage = () => {
  const fetcher = useFetcher()
  const navigate = useNavigate()
  const loaderData = useRouteLoaderData<typeof loader>('routes/_admin.lg-admin')
  const categories = loaderData?.categoriesData
  const tags = loaderData?.tagsData
  const [error, setError] = useState<string>()
  const [disabled, setDisabled] = useState(false)

  const formMethods = useRemixForm<TContentSchema>({
    mode: 'onSubmit',
    fetcher,
    resolver: zodResolver(contentSchema),
    defaultValues: {
      categories: [],
      tags: [],
      title: '',
      content: '',
      featured_image: '',
      is_premium: false,
      live_at: '',
    },
  })

  const { handleSubmit, control, watch } = formMethods
  const watchCategories = watch('categories')
  const watchTags = watch('tags')

  useEffect(() => {
    if (!fetcher.data?.success) {
      setError(fetcher.data?.message)
      setDisabled(false)
      return
    }

    navigate('/lg-admin/contents')
    setDisabled(true)
    setError(undefined)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fetcher])

  return (
    <div className="relative">
      <TitleDashboard title="Buat Artikel" />
      <RemixFormProvider {...formMethods}>
        <fetcher.Form
          method="post"
          onSubmit={handleSubmit}
          action="/actions/admin/contents/create"
          className="space-y-4"
        >
          {error && (
            <div className="text-sm text-red-500 capitalize">{error}</div>
          )}
          <div className="flex items-end justify-between gap-4">
            <Input
              id="title"
              label="Judul"
              placeholder="Masukkan Judul"
              name="title"
              className="border-0 bg-white shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
              labelClassName="text-sm font-medium text-[#363636]"
              containerClassName="flex-1"
            />
            <Input
              id="featured_image"
              label="Gambar Unggulan"
              placeholder="Masukkan Gambar Unggulan"
              name="featured_image"
              className="border-0 bg-white shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
              labelClassName="text-sm font-medium text-[#363636]"
              containerClassName="flex-1"
            />
            <Button
              disabled={disabled}
              type="submit"
              size="lg"
              className="text-md h-[42px] rounded-md"
            >
              Save
            </Button>
          </div>
          <div className="flex items-end justify-between gap-4">
            <Combobox
              multiple
              id="categories"
              name="categories"
              label="Kategori"
              placeholder={
                watchCategories
                  ? watchCategories.map((category) => category?.name).join(', ')
                  : 'Pilih Kategori'
              }
              options={categories}
              className="border-0 bg-white shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
              labelClassName="text-sm font-medium text-[#363636]"
              containerClassName="flex-1"
            />
            <Combobox
              multiple
              id="tags"
              name="tags"
              label="Tags"
              placeholder={
                watchTags
                  ? watchTags.map((tag) => tag?.name).join(', ')
                  : 'Pilih Tags'
              }
              options={tags}
              className="border-0 bg-white shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
              labelClassName="text-sm font-medium text-[#363636]"
              containerClassName="flex-1"
            />
            <Input
              id="live_at"
              label="Tanggal Live"
              placeholder="Pilih Tanggal"
              name="live_at"
              type="date"
              className="border-0 bg-white shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
              labelClassName="text-sm font-medium text-[#363636]"
            />
            <Switch
              id="is_premium"
              name="is_premium"
              label="Premium"
              labelClassName="text-sm font-medium text-[#363636]"
              className="h-[42px]"
            />
          </div>

          <TextEditor
            id="content"
            name="content"
            label="Konten"
            placeholder="Masukkan Konten"
            className="shadow"
            inputClassName="bg-white focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none border-0"
            labelClassName="text-sm font-medium text-[#363636]"
            category="content"
          />
        </fetcher.Form>
      </RemixFormProvider>

      <DevTool control={control} />
    </div>
  )
}
