import { Box, Button, CircularProgress, LinearProgress, TextField } from '@mui/material';
import { useForm } from '@tanstack/react-form';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from '@tanstack/react-router';
import { FC, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Api from '../../../api/Api';
import { PostCreate } from '../../../types/Post';
import ErrorComponent from '../../Error/ErrorComponent';

const PostForm: FC = () => {
  //eslint-disable-next-line @typescript-eslint/no-explicit-any
  const [error, setError] = useState<any>();
  const [characterCount, setCharacterCount] = useState(0);

  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const navigate = useNavigate();

  const newMutation = useMutation({
    mutationFn: ({ data }: { data: PostCreate }) => {
      return Api.newPost(data);
    },
  });

  const form = useForm<PostCreate>({
    defaultValues: {
      content: '',
    },
    onSubmit: async ({ value }) => {
      try {
        newMutation.mutate(
          { data: value },
          {
            onSuccess: async (data) => {
              form.reset();
              await queryClient.invalidateQueries({ queryKey: ['posts'] });
              navigate({ to: '/', search: { page: data.pages - 1 } });
            },
            onError: setError,
          }
        );

        //eslint-disable-next-line @typescript-eslint/no-explicit-any
      } catch (error: any) {
        setError(error);
      }
    },
  });

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        e.stopPropagation();
        form.handleSubmit();
      }}
      onKeyDown={(event) => {
        if (event.key === 'Tab') {
          event.stopPropagation();
        }
      }}
      noValidate
    >
      <Box sx={{ display: 'grid', gap: 2, padding: 1 }}>
        <form.Field
          name="content"
          validators={{
            onChange: ({ value }) => (!value ? t('Content required') : undefined),
            onChangeAsyncDebounceMs: 250,
            onChangeAsync: async ({ value }) => {
              return !value && t('Content required');
            },
          }}
          children={(field) => {
            return (
              <>
                <TextField
                  variant="outlined"
                  multiline
                  minRows={3}
                  name={field.name}
                  value={field.state.value}
                  onBlur={field.handleBlur}
                  onChange={(e) => {
                    if (e.target.value.length <= 250) {
                      setCharacterCount(e.target.value.length);
                      field.handleChange(e.target.value);
                    }
                  }}
                  size="small"
                  label={t('Comment')}
                  required
                  error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
                  helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
                  autoComplete="off"
                  fullWidth
                />
                <LinearProgress
                  variant="determinate"
                  value={(characterCount / 250) * 100}
                  color={characterCount === 250 ? 'error' : characterCount >= 200 ? 'warning' : 'primary'}
                />
              </>
            );
          }}
        />
        <form.Subscribe
          selector={(state) => [state.canSubmit, state.isSubmitting]}
          children={([canSubmit]) => (
            <>
              <Button
                type="submit"
                disabled={!canSubmit || newMutation.isPending}
                variant="contained"
                endIcon={newMutation.isPending && <CircularProgress color="inherit" size="20px" />}
              >
                {t('Post comment')}
              </Button>
            </>
          )}
        />
        {error && <ErrorComponent error={error} context="newPost" />}
      </Box>
    </form>
  );
};

export default PostForm;
