'use client';

import { saveArticle } from '@/lib/feature/article/article.external';
import { Button } from '@/ui/components/shadcn/button';
import {
    Field,
    FieldDescription,
    FieldError,
    FieldGroup,
    FieldLabel,
} from '@/ui/components/shadcn/field';
import { Input } from '@/ui/components/shadcn/input';
import {
    InputGroup,
    InputGroupTextarea,
} from '@/ui/components/shadcn/input-group';
import { zodResolver } from '@hookform/resolvers/zod';
import { useCallback, useEffect, useRef } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import slugify from 'slugify';
import { toast } from 'sonner';
import { z } from 'zod';

export const CreateArticleForm = () => {
    const fileInputRef = useRef<HTMLInputElement>(null);

    const formSchema = z.object({
        title: z.string().min(3).max(255),
        slug: z.string().min(3),
        description: z.string().min(10),
        coverImageUrl: z.url(),
        content: z.instanceof(File),
    });

    const form = useForm<z.infer<typeof formSchema>>({
        resolver: zodResolver(formSchema),
        defaultValues: {
            title: '',
            slug: '',
            description: '',
            coverImageUrl: '',
            content: undefined,
        },
    });

    const title = useWatch({
        control: form.control,
        name: 'title',
    });
    useEffect(() => {
        if (!title) return;

        form.setValue('slug', slugify(title).toLowerCase());
    }, [form, title]);

    const handleFormSubmit = useCallback(
        async (data: z.infer<typeof formSchema>) => {
            try {
                const result = await saveArticle({
                    ...data,
                    content: await data.content.text(),
                });
                toast.success('Article created successfully!', {
                    description: `Article "${result.title}" has been created.`,
                    position: 'bottom-right',
                });
                form.reset();

                if (fileInputRef.current) {
                    fileInputRef.current.value = '';
                }
            } catch (error) {
                toast.error('Failed to create article', {
                    description:
                        error instanceof Error
                            ? error.message
                            : 'An error occurred',
                    position: 'bottom-right',
                });
            }
        },
        [form]
    );

    return (
        <form
            id='form-create-article'
            // eslint-disable-next-line react-hooks/refs
            onSubmit={form.handleSubmit(handleFormSubmit)}
        >
            <FieldGroup>
                <Controller
                    name='title'
                    control={form.control}
                    render={({ field, fieldState }) => (
                        <Field data-invalid={fieldState.invalid}>
                            <FieldLabel htmlFor='form-create-article-title'>
                                Title
                            </FieldLabel>
                            <Input
                                {...field}
                                id='form-create-article-title'
                                aria-invalid={fieldState.invalid}
                                placeholder='Article title'
                                autoComplete='off'
                            />
                            {fieldState.invalid && (
                                <FieldError errors={[fieldState.error]} />
                            )}
                        </Field>
                    )}
                />
                <Controller
                    name='slug'
                    control={form.control}
                    render={({ field, fieldState }) => (
                        <Field data-invalid={fieldState.invalid}>
                            <FieldLabel htmlFor='form-create-article-slug'>
                                Slug
                            </FieldLabel>
                            <Input
                                {...field}
                                id='form-create-article-slug'
                                aria-invalid={fieldState.invalid}
                                placeholder='article-slug'
                                autoComplete='off'
                            />
                            {fieldState.invalid && (
                                <FieldError errors={[fieldState.error]} />
                            )}
                        </Field>
                    )}
                />
                <Controller
                    name='description'
                    control={form.control}
                    render={({ field, fieldState }) => (
                        <Field data-invalid={fieldState.invalid}>
                            <FieldLabel htmlFor='form-create-article-description'>
                                Description
                            </FieldLabel>
                            <InputGroup>
                                <InputGroupTextarea
                                    {...field}
                                    id='form-create-article-description'
                                    placeholder='A simple but nice description of the article here.'
                                    rows={3}
                                    className='min-h-24 resize-none'
                                    aria-invalid={fieldState.invalid}
                                />
                            </InputGroup>
                            {fieldState.invalid && (
                                <FieldError errors={[fieldState.error]} />
                            )}
                        </Field>
                    )}
                />
                <Controller
                    name='coverImageUrl'
                    control={form.control}
                    render={({ field, fieldState }) => (
                        <Field data-invalid={fieldState.invalid}>
                            <FieldLabel htmlFor='form-create-article-cover-image-url'>
                                Cover Image URL
                            </FieldLabel>
                            <Input
                                {...field}
                                id='form-create-article-cover-image-url'
                                aria-invalid={fieldState.invalid}
                                placeholder='https://example.com/image.jpg'
                                type='url'
                                autoComplete='off'
                            />
                            {fieldState.invalid && (
                                <FieldError errors={[fieldState.error]} />
                            )}
                        </Field>
                    )}
                />
                <Controller
                    name='content'
                    control={form.control}
                    render={({ field, fieldState }) => (
                        <Field data-invalid={fieldState.invalid}>
                            <FieldLabel htmlFor='form-create-article-content'>
                                Content (Markdown File)
                            </FieldLabel>
                            <Input
                                ref={fileInputRef}
                                id='form-create-article-content'
                                type='file'
                                accept='.md,.markdown'
                                aria-invalid={fieldState.invalid}
                                onChange={(event) =>
                                    field.onChange(
                                        event.target.files &&
                                            event.target.files[0]
                                    )
                                }
                            />
                            <FieldDescription>
                                Select your article.
                            </FieldDescription>
                            {fieldState.invalid && (
                                <FieldError errors={[fieldState.error]} />
                            )}
                        </Field>
                    )}
                />
            </FieldGroup>
            <div className='flex w-full justify-end'>
                <Button type='submit' className='mt-6'>
                    Create Article
                </Button>
            </div>
        </form>
    );
};

export default CreateArticleForm;
