import { useEffect } from 'react';
import { FormProvider } from 'react-hook-form';
import { QueryClient, QueryClientProvider } from 'react-query';

import Spinner from '@design-system/ProgressIndicators/Spinner';
import useSnackbar from '@design-system/Snackbar';
import Stack from '@mui/material/Stack';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { SAMPLE_FILE_ASSET } from '@src/mock/data/dynamic-form';
import dynamicFormService from '@src/mock/services/dynamic-form';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { SnackbarProvider } from 'notistack';

import DynamicFormContextProvider from './components/DynamicFormContextProvider';
import FormFooter from './components/FormFooter';
import FormInputsCatalog from './components/FormInputsCatalog';
import FormSectionSkeleton from './components/FormSectionSkeleton';
import FormSuccessScreen from './components/FormSuccessScreen';
import useDynamicForm from './hooks/useDynamicForm';
import useDynamicFormAnswer from './hooks/useDynamicFormAnswer';
import { type DynamicFormResponse } from './types';

const DynamicFormWithProviders = () => {
  const { enqueueSnackbar } = useSnackbar();

  const methods = useDynamicForm<DynamicFormResponse>({
    initializeFn: dynamicFormService.initDynamicForm,
    getProgressionFn: dynamicFormService.getDynamicFormProgress,
    updateProgressionFn: dynamicFormService.updateDynamicFormProgress,
    onError: () => {
      enqueueSnackbar({
        title: 'Error al inicializar el formulario',
        variant: 'error',
      });
    },
    errorTexts: {
      required: 'Este campo es requerido',
    },
  });

  useEffect(() => {
    methods.getProgressionMutation.mutate();
  }, []);

  if (methods.isInitializingForm) {
    return <Spinner />;
  }

  return (
    <DynamicFormContextProvider {...methods}>
      {methods.shouldShowFormSuccess && (
        <FormSuccessScreen
          action={{
            children: 'Siguiente',
            onClick: () => {},
          }}
          title="Formulario completado"
          description="El formulario se ha completado correctamente"
        />
      )}
      {methods.shouldShowFormBody && (
        <FormInputsCatalog.Connected
          slotProps={{
            fields: {
              TEXT: {
                placeholder: 'Ingrese un valor',
              },
              FLOAT: {
                placeholder: '0.00',
              },
              INTEGER: {
                placeholder: '0',
              },
              FILE: {
                uploadFn: () => Promise.resolve([SAMPLE_FILE_ASSET]),
              },
              SIGNATURE: {
                signProps: {
                  uploadFn: () => Promise.resolve([SAMPLE_FILE_ASSET]),
                },
                buttonProps: {
                  children: 'Firma',
                },
                deleteButtonProps: {
                  children: 'Eliminar',
                },
                editButtonProps: {
                  children: 'Editar',
                },
              },
            },
          }}
        />
      )}
      {methods.shouldShowFormFooter && (
        <FormFooter
          nextButton={{
            children: 'Siguiente',
            onClick: () => methods.submitSection(),
          }}
          backButton={{
            children: 'Atrás',
            onClick: () => methods.changeStep({ isBackStep: true }),
          }}
        />
      )}
    </DynamicFormContextProvider>
  );
};

const meta: Meta<typeof DynamicFormWithProviders> = {
  component: DynamicFormWithProviders,
  title: 'Composed Components/DynamicForms/DynamicForm',
  tags: ['autodocs'],
  decorators: [
    Story => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: {
            retry: false,
          },
        },
      });

      return (
        <LocalizationProvider dateAdapter={AdapterDateFns}>
          <QueryClientProvider client={queryClient}>
            <SnackbarProvider>
              <div style={{ minHeight: '100vh', width: '100%' }}>
                <Story />
              </div>
            </SnackbarProvider>
          </QueryClientProvider>
        </LocalizationProvider>
      );
    },
  ],
};

export const Loading: Story = {
  render: () => {
    return <FormSectionSkeleton />;
  },
};

export const DynamicFormResults: Story = {
  render: () => {
    return <DynamicFormResultsWithProviders />;
  },
};

const DynamicFormResultsWithProviders = () => {
  const methods = useDynamicFormAnswer({
    getAnswerFn: dynamicFormService.getDynamicFormAnswer,
    errorTexts: {
      required: 'Este campo es requerido',
    },
  });

  useEffect(() => {
    methods.getAnswerMutation.mutate();
  }, []);

  if (methods.isLoading) {
    return <Spinner />;
  }

  return (
    <Stack sx={{ minHeight: '100vh' }}>
      <FormProvider {...methods.form}>
        <Stack sx={{ flex: 1 }}>
          <FormInputsCatalog
            section={methods.currentSection}
            isFrozen={methods.isFrozen}
          />
        </Stack>
        <FormFooter
          nextButton={{
            children: 'Siguiente',
            onClick: () => methods.changeStep({}),
          }}
          backButton={{
            children: 'Atrás',
            onClick: () => methods.changeStep({ isBackStep: true }),
          }}
        />
      </FormProvider>
    </Stack>
  );
};

export default meta;

type Story = StoryObj<typeof DynamicFormWithProviders>;

export const Default: Story = {};
