import { useMemo, useState } from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';

import { isNil } from 'lodash-es';
import { IconInfoCircle, IconRefresh } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import FormTextArea from '@material-hu/components/design-system/Inputs/TextArea/form';
import useSnackbar from '@material-hu/components/design-system/Snackbar';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { logEvent } from 'src/config/logging';
import useCommunityFeature from 'src/hooks/useCommunityFeature';
import useGeneralError from 'src/hooks/useGeneralError';
import useRules from 'src/hooks/useRules';
import { EventName } from 'src/types/amplitude';
import { CommunityFeature } from 'src/types/communityFeatures';
import { useLokaliseTranslation } from 'src/utils/i18n';

import SegmentedToggle from '../../components/SegmentedToggle';
import { type Goal, GoalProgressChange, GoalProgressTypes } from '../../types';
import { getValueSymbol } from '../../utils';
import { VALUE_FIELD_RULES_CONFIG } from '../constants';
import { useUpdateGoalProgress } from '../hooks/useUpdateGoalProgress';
import { getHasValue, getProgressType, getProgressValue } from '../utils';

export type AddProgressProps = {
  goal: Goal;
};

type FormValues = {
  description: string;
  type: number | GoalProgressChange | null;
  value: number | string | null;
};

const getDefaultProgressType = (
  isBinaryType: boolean,
  hideIncrementOption: boolean,
): GoalProgressChange | null => {
  if (isBinaryType) return null;
  if (hideIncrementOption) return GoalProgressChange.TOTAL_VALUE;
  return GoalProgressChange.DELTA_VALUE;
};

const defaultValues = (
  isBinaryType: boolean,
  hideIncrementOption: boolean,
): FormValues => ({
  description: '',
  type: getDefaultProgressType(isBinaryType, hideIncrementOption),
  value: null,
});

const AddProgress = ({ goal }: AddProgressProps) => {
  const [formResetKey, setFormResetKey] = useState(0);
  const { t } = useLokaliseTranslation('goals');
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();
  const theme = useTheme();
  const primaryColor = theme.palette.primary.main;

  const isBinaryType = goal?.valueType === GoalProgressTypes.BINARY;
  const hideIncrementOption = useCommunityFeature(
    CommunityFeature.GOALS_HIDE_INCREMENT_OPTION,
  );
  const form = useForm<FormValues>({
    defaultValues: defaultValues(isBinaryType, hideIncrementOption),
    mode: 'onChange',
  });

  const options = useMemo(() => {
    if (hideIncrementOption && !isBinaryType) {
      return [
        {
          value: GoalProgressChange.TOTAL_VALUE,
          label: t('detail.total'),
          tooltip: t('detail.tooltip_total'),
        },
      ];
    }

    return [
      {
        value: isBinaryType ? 0 : GoalProgressChange.DELTA_VALUE,
        label: t(
          isBinaryType ? 'detail.binary_values.pending' : 'detail.increase',
        ),
        tooltip: isBinaryType ? null : t('detail.tooltip_increment'),
      },
      {
        value: isBinaryType ? 1 : GoalProgressChange.TOTAL_VALUE,
        label: t(isBinaryType ? 'detail.binary_values.done' : 'detail.total'),
        tooltip: isBinaryType ? null : t('detail.tooltip_total'),
      },
    ];
  }, [isBinaryType, hideIncrementOption, t]);

  const handleChangeType = (
    _: unknown,
    newType: number | GoalProgressChange | null,
  ) => {
    if (!isBinaryType && isNil(newType)) {
      return;
    }

    form.setValue('type', newType);
  };

  const description = useWatch({ control: form.control, name: 'description' });
  const type = useWatch({ control: form.control, name: 'type' });
  const value = useWatch({ control: form.control, name: 'value' });

  const updateGoalMutation = useUpdateGoalProgress(goal.id);

  const handleSubmit = async () => {
    const hasValueToSend = getHasValue(isBinaryType, type, value);
    const progressValue = getProgressValue(isBinaryType, type, value);
    const progressType = getProgressType(isBinaryType, type, hasValueToSend);
    const descriptionToSend = description?.trim() || null;

    try {
      const response = await updateGoalMutation.mutateAsync({
        description: descriptionToSend,
        type: progressType,
        value: progressValue,
      });

      form.reset(defaultValues(isBinaryType, hideIncrementOption));
      setFormResetKey(k => k + 1);

      enqueueSnackbar({
        title: t('detail.progress_created'),
        variant: 'success',
      });

      logEvent(EventName.GOAL_UPDATED, {
        goalId: response.data.id,
        cycleId: response.data.goalCycleId,
        type: progressType,
        value: progressValue,
        progress: response.data.progress,
      });
    } catch (err) {
      showGeneralError(err);
    }
  };

  const option = options.find(o => o.value === type);

  const valueFieldRules = useRules(VALUE_FIELD_RULES_CONFIG);

  const hasDescription = description?.trim()?.length > 0;
  const hasValue = getHasValue(isBinaryType, type, value);
  const isAtLeastOneFieldFilled = hasDescription || hasValue;

  return (
    <FormProvider {...form}>
      <Stack sx={{ gap: 3 }}>
        <Typography
          variant="globalM"
          fontWeight="fontWeightSemiBold"
          color="new.text.neutral.default"
        >
          {t('detail.advances')}
        </Typography>
        <Stack
          sx={{
            border: `1px solid ${theme.palette.new.border.neutral.default}`,
            borderRadius: '16px',
            p: 3,
            gap: 4,
            backgroundColor: theme.palette.new.background.elements.default,
          }}
        >
          <Stack sx={{ gap: 2 }}>
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              color="new.text.neutral.default"
            >
              {t('detail.whats_new')}
            </Typography>
            <FormTextArea
              key={`description-${formResetKey}`}
              name="description"
              textAreaProps={{
                placeholder: t('detail.comment_updates'),
                simplifyEditor: true,
                sx: {
                  backgroundColor:
                    theme.palette.new.background.elements.default,
                  borderRadius: '8px',
                  '& .ProseMirror p.is-editor-empty:first-child::before': {
                    fontSize: '16px',
                    color: theme.palette.new.text.neutral.lighter,
                  },
                },
              }}
            />
          </Stack>
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'flex-start',
              justifyContent: 'space-between',
              gap: 2,
              width: '100%',
            }}
          >
            <Stack sx={{ gap: 1 }}>
              <Stack
                sx={{ flexDirection: 'row', alignItems: 'center', gap: 0.5 }}
              >
                <Typography
                  variant="globalS"
                  fontWeight="fontWeightSemiBold"
                  color="new.text.neutral.default"
                >
                  {t('detail.new_value')}
                </Typography>
                <HuTooltip
                  title={
                    <Stack sx={{ gap: 0.5 }}>
                      <Typography
                        variant="globalS"
                        fontWeight="fontWeightSemiBold"
                        color="new.text.neutral.inverted"
                      >
                        {t('detail.new_value_tooltip_title')}
                      </Typography>
                      <Typography
                        variant="globalXS"
                        color="new.text.neutral.inverted"
                      >
                        {t('detail.new_value_tooltip_body_increment')}
                      </Typography>
                      <Typography
                        variant="globalXS"
                        color="new.text.neutral.inverted"
                      >
                        {t('detail.new_value_tooltip_body_total')}
                      </Typography>
                    </Stack>
                  }
                >
                  <IconInfoCircle
                    size={16}
                    color={theme.palette.new.text.neutral.lighter}
                  />
                </HuTooltip>
              </Stack>
              <SegmentedToggle
                options={options}
                value={option?.value ?? null}
                onChange={newType => handleChangeType(null, newType)}
                activeColor={primaryColor}
                showCheckWhenSelected
              />
            </Stack>
            {!isBinaryType && (
              <Stack sx={{ flex: 1, gap: 0.5, maxWidth: '280px' }}>
                <Typography
                  variant="globalS"
                  fontWeight="fontWeightSemiBold"
                  color="new.text.neutral.default"
                >
                  {t('detail.percentage_label')}
                </Typography>
                <HuFormInputClassic
                  key={`value-${formResetKey}`}
                  name="value"
                  rules={valueFieldRules}
                  inputProps={{
                    size: 'small',
                    type: 'number',
                    hasCounter: false,
                    placeholder: t(
                      `detail.placeholder.${goal.valueType.toLowerCase()}`,
                    ),
                    endAdornment: getValueSymbol(goal.valueType),
                    helperText: goal?.valueUnit ?? null,
                  }}
                />
              </Stack>
            )}
          </Stack>
          <Stack sx={{ alignItems: 'flex-end' }}>
            <Button
              variant="contained"
              size="small"
              disabled={!isAtLeastOneFieldFilled || !form.formState.isValid}
              onClick={handleSubmit}
              endIcon={<IconRefresh size={16} />}
              sx={{
                minWidth: '104px',
                borderRadius: '8px',
                '&.Mui-disabled': {
                  backgroundColor:
                    theme.palette.new.background.elements.disabled,
                  color: theme.palette.new.text.neutral.disabled,
                },
              }}
            >
              {t('detail.update_objetive')}
            </Button>
          </Stack>
        </Stack>
      </Stack>
    </FormProvider>
  );
};

export default AddProgress;
