import { SubmitHandler, useForm } from 'react-hook-form'
import { CreateField } from '../interfaces/create'
import { AxiosResponse } from 'axios';
import { Button, Field, Input, Spinner, Text } from '@fluentui/react-components';

interface Props {
    title?: string;
    submitHandler?: (data: any) => Promise<AxiosResponse<any, any>>;
    fields: CreateField[];
    submitButtonText?: string;
    mutateHandler?: any;
    defaultValues?: {};
    watchValues?: string[];
}

function FormFields({
    title = '',
    submitHandler,
    fields,
    submitButtonText = 'Сохранить',
    mutateHandler,
    defaultValues
}: Props) {
    const getDefaultValues = (fields: CreateField[]) => {
        let result: { [key: string]: string | boolean } = {}
        fields.forEach((field: CreateField) => {
            result[field.key] = field.defaultValue || defaultValues?.[field.key as keyof {}]
        })
        return result
    }

    const { register, handleSubmit, reset, watch, formState: { errors, isSubmitting, dirtyFields, isValid } } = useForm({
        mode: 'onChange',
        defaultValues: defaultValues ? getDefaultValues(fields) : {}
    })

    const onSubmit: SubmitHandler<any> = async (data) => {
        fields.forEach((field: CreateField) => {
            if (field.include === false) {
                delete data[field.key]
            }
        })
        try {
            const submitResponse = await submitHandler?.(data)
            mutateHandler?.(JSON.stringify(submitResponse?.data))
            reset(submitResponse?.data)
        } catch (error) {
            console.error(error)
        }
    }

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', width: '100%' }}>
                {title.length > 0 &&
                    <Text size={500} weight='semibold'>
                        {title}
                    </Text>
                }

                {fields.map((field: CreateField) => {
                    return (
                        <Field key={field.key} validationState={errors[field.key]?.message ? 'error' : 'none'} label={field.headerName || field.key.charAt(0).toUpperCase() + field.key.slice(1)}>
                            <Input type={field.inputType ? field.inputType : 'text'}
                                {...register(field.key, {
                                    required: field.required ? `${field.headerName} обязателен` : false,
                                    validate: (val: string | boolean) => {
                                        if (field.watch) {
                                            if (watch(field.watch) != val) {
                                                return field.watchMessage || ''
                                            }
                                        }
                                    },
                                })}
                                required={field.required || false}
                            />
                        </Field>
                    )
                })}

                <Button disabled={isSubmitting || Object.keys(dirtyFields).length === 0 || !isValid} type='submit'>
                    {isSubmitting ? <Spinner size='extra-small' /> : submitButtonText}
                </Button>
            </div>
        </form>
    )
}

export default FormFields