import { type ReactNode } from 'react';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
import { Trans } from 'react-i18next';
import { useQuery } from 'react-query';

import Stack, { type StackProps } from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuAlert, {
  type AlertProps,
} from '@material-hu/components/design-system/Alert';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';

import { getAudienceCount } from 'src/services/usersService';
import { type AudienceCriteria, CriteriaType } from 'src/types/audience';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useCriteriaColaborators } from 'src/components/Audience/NewSeeCollaborators';
import {
  audienceKeys,
  type SegmentationCondition,
} from 'src/components/Audience/queries';

import ConditionLineGroup from './components/ConditionLineGroup';
import { defaultConditionLineValues } from './constants';
import { type SegmentationSelectionDrawerProps } from './types';

const SegmentationDrawerHeader = ({ description }: { description: string }) => {
  return (
    <Stack
      sx={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        gap: 4,
        mb: 2,
      }}
    >
      <Typography
        variant="globalXS"
        sx={{
          color: theme => theme.palette.textColors?.neutralTextLighter,
        }}
      >
        <Trans>{description}</Trans>
      </Typography>
    </Stack>
  );
};

const SegmentationDrawerFooter = ({
  count,
  showCount,
  children,
  loadingCount,
  criteria,
  alertProps,
}: {
  children?: ReactNode;
  count: number;
  showCount: boolean;
  loadingCount: boolean;
  criteria?: AudienceCriteria[];
  alertProps?: Pick<AlertProps, 'severity' | 'description'>;
}) => {
  const { t } = useLokaliseTranslation('audience');

  const { showDrawer: showSelectedUsersDrawer, drawer: selectedUsersDrawer } =
    useCriteriaColaborators({
      criteria: criteria || [],
      type: CriteriaType.SEGMENTED_USERS,
      usersCount: count,
    });

  return (
    <Stack
      sx={{
        mt: 'auto',
        pt: 3,
        gap: 1.25,
        borderTop: theme => `1px solid ${theme.palette.border?.neutralBorder}`,
      }}
    >
      {children}
      {selectedUsersDrawer}
      <HuAlert
        severity={alertProps?.severity || 'info'}
        loading={loadingCount}
        title={
          !showCount
            ? t('total_audience_none')
            : t('total_audience', {
                count,
              })
        }
        description={alertProps?.description || ''}
        action={
          showCount && count
            ? {
                text: t('see_collaborators'),
                onClick: () => showSelectedUsersDrawer(),
              }
            : undefined
        }
      />
    </Stack>
  );
};

const SegmentationDrawerConditionLines = ({
  disabled,
  minimumSelectionCount,
  slotProps,
  onlyAnd,
}: {
  disabled?: boolean;
  minimumSelectionCount?: number;
  slotProps?: {
    root?: {
      sx: StackProps['sx'];
    };
  };
  onlyAnd?: boolean;
}) => {
  const { t } = useLokaliseTranslation('audience');
  const { formState, watch } = useFormContext();
  const segmentationConditions: SegmentationCondition[] = watch(
    'segmentationConditions',
  );

  const showWarning =
    formState.submitCount > 0 &&
    segmentationConditions.some(condition => condition.value.length === 0);

  return (
    <Stack
      sx={{
        marginTop: 3,
        backgroundColor: theme => theme?.palette.hugoBackground?.neutralBg,
        border: 'none',
        borderRadius: 2,
        ...slotProps?.root?.sx,
      }}
    >
      <Stack sx={{ padding: 2 }}>
        <ConditionLineGroup
          name="segmentationConditions"
          disabled={disabled ?? false}
          minimumSelectionCount={minimumSelectionCount}
          onlyAnd={onlyAnd}
        />
      </Stack>
      {showWarning && (
        <HuAlert
          severity="warning"
          title={t('segmented_users_pending_values')}
          sx={{
            borderRadius: 2,
            borderTopLeftRadius: 0,
            borderTopRightRadius: 0,
            border: theme => `1px solid ${theme.palette.border?.warningBorder}`,
            padding: 0.5,
            alignItems: 'center',
            justifyContent: 'center',
            display: 'flex',
            gap: 1,
            '&:before': {
              display: 'none',
            },
            '& .MuiAlert-icon': {
              height: '0.75rem',
              width: '0.75rem',
              fontSize: '0.75rem',
              marginRight: 0,
              '& svg': {
                height: '0.75rem',
                width: '0.75rem',
              },
            },
            '& .MuiAlert-message': {
              padding: 0,
              '.MuiTypography-root': {
                fontSize: '12px',
                fontWeight: 400,
                padding: 0,
              },
            },
            '& .MuiAlert-action': {
              display: 'none',
            },
          }}
        />
      )}
    </Stack>
  );
};

const SegmentationSelectionDrawer = ({
  onConfirm,
  formId,
  values: defaultValues,
  description,
}: SegmentationSelectionDrawerProps) => {
  const { t } = useLokaliseTranslation('audience');
  const methods = useForm<{
    segmentationConditions: SegmentationCondition[];
  }>({
    defaultValues: {
      segmentationConditions: [defaultConditionLineValues],
      ...defaultValues,
    },
  });

  const segmentationConditions = methods.watch('segmentationConditions');

  const audienceCountQuery = useQuery({
    queryKey: audienceKeys.segmentationConditionsCount(segmentationConditions),
    queryFn: () =>
      getAudienceCount(
        {
          page: 0,
          limit: 10,
          segmentationItemIds: segmentationConditions.flatMap(
            condition => condition.value,
          ),
        },
        true,
      ),
    select: response => response.data as { count: number },
    enabled: !!segmentationConditions[0]?.value?.length,
  });

  const handleSubmit = async (values: {
    segmentationConditions: SegmentationCondition[];
  }) => {
    await onConfirm?.(values);
  };

  return (
    <FormProvider {...methods}>
      <form
        id={formId}
        onSubmit={methods.handleSubmit(handleSubmit)}
        style={{ display: 'contents' }}
      >
        <Stack
          sx={{
            flexDirection: 'row',
            justifyContent: 'space-between',
            alignItems: 'center',
            gap: 4,
            mb: 2,
          }}
        >
          <Typography
            variant="globalXS"
            sx={{
              color: theme => theme.palette.textColors?.neutralTextLighter,
            }}
          >
            <Trans>{description}</Trans>
          </Typography>
        </Stack>

        <HuCardContainer
          sx={{
            marginTop: 3,
            backgroundColor: theme => theme.palette.hugoBackground?.neutralBg,
            border: 'none',
          }}
          fullWidth
        >
          <ConditionLineGroup name="segmentationConditions" />
        </HuCardContainer>

        <Stack
          sx={{
            mt: 'auto',
            pt: 3,
            borderTop: theme =>
              `1px solid ${theme.palette.border?.neutralBorder}`,
          }}
        >
          <HuAlert
            severity="info"
            loading={audienceCountQuery.isLoading}
            title={
              !segmentationConditions[0]?.value?.length
                ? t('total_audience_none')
                : t('total_audience', {
                    count: audienceCountQuery.data?.count,
                  })
            }
          />
        </Stack>
      </form>
    </FormProvider>
  );
};

SegmentationSelectionDrawer.Header = SegmentationDrawerHeader;
SegmentationSelectionDrawer.ConditionLines = SegmentationDrawerConditionLines;
SegmentationSelectionDrawer.Footer = SegmentationDrawerFooter;

export default SegmentationSelectionDrawer;
