import { SubmitHandler, useForm } from 'react-hook-form'
import { CreateField } from '../interfaces/create'
import { Box, Button, CircularProgress, Stack, SxProps, TextField, Typography } from '@mui/material';
import { AxiosResponse } from 'axios';

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

function FormFields({
    title = '',
    submitHandler,
    fields,
    submitButtonText = 'Сохранить',
    mutateHandler,
    defaultValues,
    sx
}: 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)}>
            <Stack sx={sx} spacing={2} width='100%'>
                <Typography variant="h6" component="h6" gutterBottom>
                    {title}
                </Typography>

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

                <Box sx={{
                    display: "flex",
                    justifyContent: "space-between",
                    gap: "8px"
                }}>
                    <Button disabled={isSubmitting || Object.keys(dirtyFields).length === 0 || !isValid} type="submit" variant="contained" color="primary">
                        {isSubmitting ? <CircularProgress size={16} /> : submitButtonText}
                    </Button>
                </Box>
            </Stack>
        </form>
    )
}

export default FormFields