import { useRef } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { useMutation } from 'react-query';

import { zodResolver } from '@hookform/resolvers/zod';
import { AxiosResponse } from 'axios';
import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';

import useGeneralError from 'src/hooks/useGeneralError';
import {
  createLivestreamPoll,
  updateLivestreamPoll,
} from 'src/services/streaming';
import { Poll, PollFormSchema, PollFormValues } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { pushPollData, updatePollData } from '../../../queries';

import Form from './Form';

type UsePollDrawerParams = {
  streamId: string;
};

const DEFAULT_FORM_VALUES: PollFormValues = {
  title: '',
  pollOptions: [{ value: '' }, { value: '' }],
  viewVotesResult: false,
};

export const usePollDrawer = (params: UsePollDrawerParams) => {
  const { streamId } = params;
  const { t } = useLokaliseTranslation('livestream');
  const showGeneralError = useGeneralError();

  const pollIdRef = useRef<number | null>(null);

  const form = useForm<PollFormValues>({
    defaultValues: DEFAULT_FORM_VALUES,
    resolver: zodResolver(PollFormSchema),
  });

  const formValues = form.watch();
  const isFormValid = PollFormSchema.safeParse(formValues).success;
  const isFormDirty = form.formState.isDirty;
  const isEditMode = pollIdRef.current !== null;

  const { mutateAsync: savePoll, isLoading: isSavingPoll } = useMutation(
    (variables: { poll: PollFormValues }) =>
      isEditMode
        ? updateLivestreamPoll(streamId, pollIdRef.current!, variables.poll)
        : createLivestreamPoll(streamId, variables.poll),
    {
      onSuccess: (response: AxiosResponse<Poll>) => {
        isEditMode
          ? updatePollData(streamId, response.data)
          : pushPollData(streamId, response.data);
        form.reset(DEFAULT_FORM_VALUES);
        closeDrawer();
      },
      onError: error => {
        showGeneralError(
          error,
          isEditMode ? t('polls.update_error') : t('polls.drawer.create_error'),
        );
      },
    },
  );

  const { drawer, showDrawer, closeDrawer } = useDrawerV2(
    ({ closeDrawer: onCloseDrawer }) => {
      return {
        title: isEditMode ? t('polls.edit') : t('polls.create'),
        children: (
          <FormProvider {...form}>
            <Form />
          </FormProvider>
        ),
        primaryButtonProps: {
          children: isEditMode ? t('general:save') : t('general:create'),
          fullWidth: true,
          disabled: !isFormValid || !isFormDirty,
          loading: isSavingPoll,
          onClick: form.handleSubmit(values => {
            savePoll({ poll: values });
          }),
        },
        secondaryButtonProps: {
          children: t('general:cancel'),
          fullWidth: true,
          onClick: () => {
            onCloseDrawer();
            form.reset(DEFAULT_FORM_VALUES);
          },
        },
        onClose: () => {
          onCloseDrawer();
          form.reset(DEFAULT_FORM_VALUES);
        },
      };
    },
  );

  const showCreatePollDrawer = () => {
    pollIdRef.current = null;
    showDrawer({});
  };

  const showEditPollDrawer = (poll: Poll) => {
    pollIdRef.current = poll.id;
    form.reset({
      title: poll.title || '',
      pollOptions: poll.pollOptions.map(option => ({ value: option.option })),
      viewVotesResult: poll.pollConfiguration.viewVotesResult || false,
    });
    showDrawer({});
  };

  return {
    createPollDrawer: drawer,
    showCreatePollDrawer,
    showEditPollDrawer,
  };
};
