import { useState } from 'react';
import { UseFormReturn } from 'react-hook-form';
import { useQuery } from 'react-query';
import { useParams, useLocation, useNavigate } from 'react-router-dom';

import { AxiosResponse } from 'axios';

import CardContent from '@material-hu/mui/CardContent';
import CardHeader from '@material-hu/mui/CardHeader';
import Collapse from '@material-hu/mui/Collapse';
import Switch from '@material-hu/mui/Switch';

import HuCircularProgress from '@material-hu/components/design-system/ProgressIndicators/Spinner';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import useOnboardingCategories from 'src/hooks/queryHooks/useOnboardingCategories';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useTimeInScreen from 'src/hooks/useTimeInScreen';
import { usersRoutes } from 'src/pages/dashboard/Users/routes';
import * as onboardingsService from 'src/services/onboardingsService';
import {
  CustomDueDatePeriod,
  CustomDueDateRelation,
  DueDateType,
  OnboardingTask,
  OnboardingTaskNotifications,
} from 'src/types/onboarding';
import { Audience } from 'src/types/segmentation';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { logEvent, LogEvents } from 'src/utils/logging';
import {
  formatSegmentationIds,
  formatFormSegmentation,
} from 'src/utils/segmentationUtils';

import ArticleEditLayout from 'src/components/ArticleEditLayout';
import FormSegmentation from 'src/components/FormInputs/FormSegmentation';
import FormSelect from 'src/components/FormInputs/FormSelect';

import { onboardingsKeys } from '../queries';
import { onboardingsRoutes } from '../routes';

import DateSelection from './DateSelection';

function Task() {
  const { t } = useLokaliseTranslation(['onboarding', 'general']);
  const HuGoThemeProvider = useHuGoTheme();
  const { state } = useLocation() as { state: { defaultCategoryId?: number } };
  const getTimeInScreen = useTimeInScreen();
  const navigate = useNavigate();
  const { enqueueSnackbar } = useHuSnackbar();

  const { userId, taskId } = useParams();
  const isEditing = !!taskId;

  const [hasAutoAssign, setHasAutoAssign] = useState(false);

  const { data: task } = useQuery(
    onboardingsKeys.task(taskId!),
    () => onboardingsService.getOnboardingTask(taskId!),
    {
      select: response => response.data,
      enabled: isEditing,
      cacheTime: 0,
      onSuccess: (r: OnboardingTask) => setHasAutoAssign(!!r.autoAssignDate),
      onError: () => {
        navigate('/');
        enqueueSnackbar({ title: t('general:not_found'), variant: 'error' });
      },
    },
  );

  const { data: categories } = useOnboardingCategories();

  if ((isEditing && !task) || !categories) {
    return (
      <HuGoThemeProvider>
        <HuCircularProgress centered />
      </HuGoThemeProvider>
    );
  }

  const mutationFn = (taskData: any) => {
    const formattedTaskData = {
      attachments: taskData.attachments,
      body: taskData.body,
      icon: taskData.icon,
      coverPictureUrl: taskData.coverPictureUrl,
      name: taskData.title,
      dueDate: {
        dueDateType: taskData.dueDate.dueDateType,
        customDueDateAmount: undefined as number | undefined,
        customDueDatePeriod: undefined,
        customDueDateRelation: undefined,
      },
      autoAssignDate: hasAutoAssign
        ? {
            autoAssignDateType: taskData.autoAssignDate.autoAssignDateType,
            customAssignDate: taskData.autoAssignDate.customAssignDate,
          }
        : null,
      notificationTime: taskData.notificationTime,
      categoryId: taskData.categoryId,
      ...formatSegmentationIds(taskData.segmentation),
    };
    if (
      hasAutoAssign &&
      taskData.autoAssignDate?.autoAssignDateType === DueDateType.CUSTOM
    ) {
      formattedTaskData.autoAssignDate!.customAssignDate!.fromDateAmount =
        parseInt(taskData.autoAssignDate.customAssignDate.fromDateAmount);
      formattedTaskData.autoAssignDate!.customAssignDate.toDateAmount =
        parseInt(taskData.autoAssignDate.customAssignDate.toDateAmount);
    }
    if (taskData.dueDate.dueDateType === DueDateType.CUSTOM) {
      formattedTaskData.dueDate.customDueDateAmount = parseInt(
        taskData.dueDate.customDueDateAmount,
      );
      formattedTaskData.dueDate.customDueDatePeriod =
        taskData.dueDate.customDueDatePeriod;
      formattedTaskData.dueDate.customDueDateRelation =
        taskData.dueDate.customDueDateRelation;
    }
    if (isEditing) {
      return onboardingsService.updateOnboardingTask(taskId, formattedTaskData);
    }
    if (userId) {
      return onboardingsService.createOnboardingIndividualTask(
        parseInt(userId),
        taskData.categoryId,
        formattedTaskData,
      );
    }
    return onboardingsService.createOnboardingTask(
      taskData.categoryId,
      formattedTaskData,
    );
  };

  return (
    <ArticleEditLayout
      title={t(
        `${isEditing ? 'edit' : 'create'}${userId ? '_individual' : ''}_task`,
      )}
      successMessage={t('success')}
      article={
        task
          ? {
              title: task.name,
              body: task.body,
              coverPicture: task.coverPicture || '',
              attachments: task.attachments || [],
              segmentation: task.segmentation || undefined,
              userSegmentation: task.userSegmentation || undefined,
              icon: task.icon,
            }
          : undefined
      }
      backLink={userId ? usersRoutes.user(userId) : onboardingsRoutes.base()}
      mutationFn={mutationFn}
      onSuccess={(response: AxiosResponse<OnboardingTask>) => {
        const screenTime = getTimeInScreen();
        logEvent(
          isEditing
            ? LogEvents.ONBOARDING_TASK_UPDATE
            : LogEvents.ONBOARDING_TASK_CREATE,
          {
            categoryId: response.data.categoryId,
            taskId: response.data.id,
            screenTime,
          },
        );
      }}
      ExtraStuff={(form: UseFormReturn<OnboardingTask>) => {
        const noDueDate =
          form.watch('dueDate.dueDateType') === DueDateType.NO_DUE_DATE;
        if (
          noDueDate &&
          form.watch('notificationTime') !==
            OnboardingTaskNotifications.NO_NOTIFICATION
        ) {
          form.setValue(
            'notificationTime',
            OnboardingTaskNotifications.NO_NOTIFICATION,
          );
        }
        return (
          <>
            <CardHeader title={t('due_date')} />
            <CardContent>
              <DateSelection customDateType="dueDate.dueDateType" />
            </CardContent>
            <CardHeader title={t('general:category')} />
            <CardContent>
              <FormSelect
                name="categoryId"
                options={categories.map(category => ({
                  label: category.name,
                  value: category.id,
                }))}
                label={t('general:category')}
                adaptWidthToOptions
              />
            </CardContent>
            <CardHeader title={t('send_notifications')} />
            <CardContent>
              <FormSelect
                name="notificationTime"
                options={Object.keys(OnboardingTaskNotifications).map(
                  option => ({
                    label: t(`send_notification_option_${option}`),
                    value: option,
                  }),
                )}
                adaptWidthToOptions
                selectProps={{ disabled: noDueDate }}
              />
            </CardContent>
            {!userId && (
              <>
                <CardHeader title={t('audience')} />
                <CardContent>
                  <FormSegmentation
                    name="segmentation"
                    showLabel={false}
                    segmentationErrorMessage={t('must_select_segmentation')}
                    useAudienceApi
                  />
                </CardContent>
                <CardHeader
                  title={`${t('auto_assign')} ⚡`}
                  action={
                    <Switch
                      checked={hasAutoAssign}
                      onChange={() => setHasAutoAssign(!hasAutoAssign)}
                    />
                  }
                />
                <CardContent>
                  <Collapse in={hasAutoAssign}>
                    <DateSelection
                      customDateType="autoAssignDate.autoAssignDateType"
                      autoAssign
                    />
                  </Collapse>
                </CardContent>
              </>
            )}
          </>
        );
      }}
      extraDefaultValues={{
        dueDate: {
          dueDateType: task?.dueDate.dueDateType || DueDateType.NO_DUE_DATE,
          customDueDateAmount: task?.dueDate.customDueDateAmount ?? 1,
          customDueDatePeriod:
            task?.dueDate.customDueDatePeriod || CustomDueDatePeriod.DAYS,
          customDueDateRelation:
            task?.dueDate.customDueDateRelation || CustomDueDateRelation.BEFORE,
        },
        autoAssignDate: {
          autoAssignDateType:
            task?.autoAssignDate?.autoAssignDateType || DueDateType.HIRE_DATE,
          customAssignDate: {
            fromDateAmount:
              task?.autoAssignDate?.customAssignDate?.fromDateAmount ?? 1,
            fromDatePeriod:
              task?.autoAssignDate?.customAssignDate?.fromDatePeriod ||
              CustomDueDatePeriod.DAYS,
            fromDateRelation:
              task?.autoAssignDate?.customAssignDate?.fromDateRelation ||
              CustomDueDateRelation.BEFORE,
            toDateAmount:
              task?.autoAssignDate?.customAssignDate?.toDateAmount ?? 1,
            toDatePeriod:
              task?.autoAssignDate?.customAssignDate?.toDatePeriod ||
              CustomDueDatePeriod.DAYS,
            toDateRelation:
              task?.autoAssignDate?.customAssignDate?.toDateRelation ||
              CustomDueDateRelation.AFTER,
          },
        },
        categoryId:
          task?.categoryId || state?.defaultCategoryId || categories[0].id,
        notificationTime:
          task?.notificationTime || OnboardingTaskNotifications.NO_NOTIFICATION,
        segmentation: formatFormSegmentation(task as unknown as Audience),
      }}
    />
  );
}
export default Task;
