import { type FC, useEffect, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { useMutation } from 'react-query';

import { IconInfoCircle } 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 useMediaQuery from '@material-hu/mui/useMediaQuery';

import SelectionCard from '@material-hu/components/composed-components/SelectionCard';
import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import HuFormInputSelect from '@material-hu/components/design-system/Inputs/Select/form';
import RadioButton from '@material-hu/components/design-system/RadioButton/RadioButton';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';
import HuFormSwitcher from '@material-hu/components/design-system/Switcher/form';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { isDev } from 'src/constants/env';
import useCommunityFeature from 'src/hooks/useCommunityFeature';
import useGeneralError from 'src/hooks/useGeneralError';
import usePermissions from 'src/hooks/usePermissions';
import FormDeviceControls from 'src/pages/dashboard/liveStream/HostLiveStream/components/FormDeviceControls';
import StreamMetrics from 'src/pages/dashboard/liveStream/HostLiveStream/components/metrics';
import { updateLiveStreamConfig } from 'src/services/streaming';
import { CommunityFeature } from 'src/types/communityFeatures';
import {
  Configuration,
  CopyInputStream,
  type LiveStreamConfig,
  StreamSource,
  StreamStatus,
  VideoOrigin,
} from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { UserPermissions } from 'src/utils/permissions';

import RichTextEditor from 'src/components/RichTextEditor';

import {
  MAX_LIVE_HOURS_DURATION,
  StreamCaptionsLanguages,
} from '../../constants';
import { useStreamDestination } from '../../hooks/useStreamDestination';

const { GENERAL, CONFIGURATION } = Configuration;
const { SEND_PUSH_NOTIFICATION } = UserPermissions;

type FormConfigurationLiveStreamProps = {
  activeStep: Configuration;
  streamStatus: StreamStatus;
  postId?: number;
  streamId: string;
  disabledWebCamOption: boolean;
};

const FormConfigurationLiveStream: FC<
  FormConfigurationLiveStreamProps
> = props => {
  const { activeStep, streamStatus, postId, streamId, disabledWebCamOption } =
    props;

  const [lastCursor, setLastCursor] = useState<number | null>(null);

  const { hasAll: canSendPush } = usePermissions([SEND_PUSH_NOTIFICATION]);
  const canViewStreamMetrics = useCommunityFeature(
    CommunityFeature.VIEW_STREAM_METRICS,
  );
  const { watch, setFocus, setValue } = useFormContext();
  const { t } = useLokaliseTranslation(['livestream', 'general', 'dashboard']);
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();
  const { details: destinationDetails, actions: destinationActions } =
    useStreamDestination();

  const isIdle = streamStatus === StreamStatus.Idle;
  const isPreparing = streamStatus === StreamStatus.Preparing;
  const isConnecting = streamStatus === StreamStatus.Connecting;
  const isStreaming = streamStatus === StreamStatus.Streaming;
  const {
    commentsEnabled,
    captionsEnabled,
    captionsLanguage,
    hlsEnabled,
    videoOrigin,
    streamKey,
    streamServer,
    body,
  } = watch();
  const theme = useTheme();
  const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));

  const canDisableComments = destinationDetails
    ? destinationDetails.supportDisableComments
    : true;

  const captionsLanguagesOptions = StreamCaptionsLanguages.map(language => ({
    value: language,
    label: t(`DASHBOARD:LANGUAGE_${language.toUpperCase()}`),
  })).sort((a, b) => a.label.localeCompare(b.label));

  useEffect(() => {
    if (isStreaming && destinationActions.toggleComments && postId) {
      commentsEnabled
        ? enableComment.mutate({ id: postId })
        : disabledComment.mutate({ id: postId });
    }
  }, [isStreaming, commentsEnabled]);

  useEffect(() => {
    const streamSource =
      videoOrigin === VideoOrigin.SOFTWARE_STREAMING
        ? StreamSource.EXTERNAL
        : StreamSource.WEBCAM;
    if (isStreaming) {
      liveStreamConfigMutation.mutate({
        config: { captionsEnabled },
        streamSource,
      });
    } else {
      liveStreamConfigMutation.mutate({
        config: { captionsEnabled, hlsEnabled, captionsLanguage },
        streamSource,
      });
    }
  }, [captionsEnabled, hlsEnabled, captionsLanguage, videoOrigin]);

  useEffect(() => {
    if (body !== '') {
      const input = document.getElementById(
        'postStreamInput',
      ) as HTMLInputElement;
      setFocus('body');
      if (lastCursor) {
        input.setSelectionRange(lastCursor, lastCursor);
        setLastCursor(null);
      }
    }
  }, [body]);

  const disabledComment = useMutation(
    (variables: { id: number }) =>
      destinationActions.toggleComments!(variables.id, false),
    {
      onError: error => {
        showGeneralError(error, t('ERROR_DISABLE_COMMENT'));
      },
    },
  );

  const enableComment = useMutation(
    (variables: { id: number }) =>
      destinationActions.toggleComments!(variables.id, true),
    {
      onError: error => {
        showGeneralError(error, t('ERROR_ENABLE_COMMENT'));
      },
    },
  );

  const liveStreamConfigMutation = useMutation(
    (variables: { config: LiveStreamConfig; streamSource?: StreamSource }) =>
      updateLiveStreamConfig(streamId, variables),
    {
      onError: error => {
        showGeneralError(error, t('ERROR_UPDATE_STREAM_VIEWER_CONFIG'));
      },
    },
  );

  const handleOnCopyClipboard = async (copyType?: CopyInputStream) => {
    try {
      await navigator.clipboard.writeText(
        copyType === CopyInputStream.STREAM_KEY ? streamKey : streamServer,
      );
      enqueueSnackbar({
        title: t(
          copyType === CopyInputStream.STREAM_KEY
            ? 'SUCCESS_COPY_KEY'
            : 'SUCCESS_COPY_SERVER',
        ),
        variant: 'success',
      });
    } catch (error) {
      enqueueSnackbar({
        title: t(
          copyType === CopyInputStream.STREAM_KEY
            ? 'ERROR_COPY_KEY'
            : 'ERROR_COPY_SERVER',
        ),
        variant: 'error',
      });
    }
  };

  const softwareStreamingElements = [
    {
      title: t('STREAM_SERVER'),
      nameInput: 'streamServer',
      handleClick: () => handleOnCopyClipboard(),
      description: t('STREAM_SERVER_DESCRIPTION'),
    },
    {
      title: t('STREAM_KEY'),
      nameInput: 'streamKey',
      handleClick: () => handleOnCopyClipboard(CopyInputStream.STREAM_KEY),
      description: t('STREAM_KEY_DESCRIPTION'),
    },
  ];

  return (
    <>
      {activeStep === GENERAL && (
        <>
          {(isIdle || isPreparing || isConnecting) && (
            <Stack
              sx={{
                width: '80%',
                gap: theme.spacing(3),
                flexDirection: 'row',
                flexWrap: isSmallScreen ? 'wrap' : 'nowrap',
              }}
            >
              <Stack
                sx={{
                  width: '100%',
                  height: 'fit-content',
                  gap: 3,
                  minWidth: !isSmallScreen ? '220px' : 'auto',
                }}
              >
                <HuCardContainer
                  sx={{
                    py: theme.spacing(1),
                    width: '100%',

                    '& .MuiCardContent-root': {
                      display: 'flex',
                      flexDirection: 'column',
                      gap: theme.spacing(2),
                    },
                  }}
                >
                  <Stack style={{ width: '100%', gap: theme.spacing(2) }}>
                    <Typography
                      variant="globalM"
                      fontWeight="fontWeightSemiBold"
                    >
                      {t('ORIGIN_VIDEO')}
                    </Typography>
                    <HuTooltip
                      description={t('NO_CHANGE_ORIGIN_VIDEO')}
                      disableTooltip={!disabledWebCamOption}
                    >
                      <Stack sx={{ gap: 2 }}>
                        {Object.keys(VideoOrigin).map(value => (
                          <SelectionCard
                            key={value}
                            checked={videoOrigin === value}
                            disabled={disabledWebCamOption}
                            onClick={() =>
                              setValue('videoOrigin', value, {
                                shouldDirty: true,
                              })
                            }
                            fullWidth
                            sx={
                              disabledWebCamOption
                                ? {
                                    '&, &:hover': {
                                      backgroundColor:
                                        theme.palette.new.background.elements
                                          .default,
                                    },
                                  }
                                : undefined
                            }
                          >
                            <RadioButton
                              label={t(value)}
                              isActive={videoOrigin === value}
                              disabled={disabledWebCamOption}
                            />
                          </SelectionCard>
                        ))}
                      </Stack>
                    </HuTooltip>
                  </Stack>
                </HuCardContainer>
                {videoOrigin === VideoOrigin.WEBCAM && (
                  <HuCardContainer
                    sx={{
                      py: theme.spacing(1),
                      width: '100%',

                      '& .MuiCardContent-root': {
                        display: 'flex',
                        flexDirection: 'column',
                        gap: theme.spacing(2),
                      },
                    }}
                  >
                    <Typography
                      variant="globalM"
                      fontWeight="fontWeightSemiBold"
                    >
                      {t('WEBCAM')}
                    </Typography>
                    <FormDeviceControls />
                  </HuCardContainer>
                )}
                {videoOrigin === VideoOrigin.SOFTWARE_STREAMING && (
                  <HuCardContainer
                    sx={{
                      py: 1,
                      width: '100%',

                      '& .MuiCardContent-root': {
                        display: 'flex',
                        flexDirection: 'column',
                        gap: theme.spacing(1),
                      },
                    }}
                  >
                    <Typography
                      variant="globalM"
                      fontWeight="fontWeightSemiBold"
                    >
                      {t('SOFTWARE_STREAMING')}
                    </Typography>
                    <Typography
                      variant="globalXS"
                      color="new.text.neutral.lighter"
                    >
                      {t('CONFIGURATION_SOFTWARE_STREAMING_DESCRIPTION')}
                    </Typography>
                    {softwareStreamingElements.map(elem => (
                      <Stack key={elem.title}>
                        <Typography
                          variant="globalM"
                          fontWeight="fontWeightSemiBold"
                          sx={{ my: 1 }}
                        >
                          {elem.title}
                        </Typography>
                        <Stack
                          sx={{
                            flexDirection: 'row',
                            alignItems: 'center',
                            gap: 1,
                          }}
                        >
                          <HuFormInputClassic
                            name={elem.nameInput}
                            inputProps={{
                              disabled: true,
                              hasCounter: false,
                            }}
                          />
                          <Button
                            variant="secondary"
                            size="small"
                            onClick={elem.handleClick}
                          >
                            {t('COPY')}
                          </Button>
                        </Stack>
                        <Typography
                          variant="globalXS"
                          color="new.text.neutral.lighter"
                          sx={{ my: 1, whiteSpace: 'pre-line' }}
                        >
                          {elem.description}
                        </Typography>
                      </Stack>
                    ))}
                  </HuCardContainer>
                )}
                {(isDev || import.meta.env.DEV || canViewStreamMetrics) && (
                  <StreamMetrics isStreaming={false} />
                )}
              </Stack>
              <Stack
                sx={{
                  width: '100%',
                  maxWidth: isSmallScreen ? '100%' : '410px',
                  gap: 3,
                }}
              >
                {!destinationDetails?.hideAddTitleBox && (
                  <HuCardContainer
                    sx={{
                      py: theme.spacing(1),
                      width: '100%',
                      height: 'fit-content',
                      '& .MuiCardContent-root': {
                        display: 'flex',
                        flexDirection: 'column',
                        gap: 2,
                      },
                    }}
                  >
                    <Typography
                      variant="globalM"
                      fontWeight="fontWeightSemiBold"
                    >
                      {t('ADD_TITLE')}
                    </Typography>
                    <RichTextEditor
                      name="bodyHtml"
                      content=""
                      placeholder={t('general:description')}
                      toolbarOptions={{
                        blockquote: false,
                        code: false,
                      }}
                    />
                  </HuCardContainer>
                )}
              </Stack>
            </Stack>
          )}
        </>
      )}
      {activeStep === CONFIGURATION && (
        <Stack sx={{ width: '80%', gap: theme.spacing(3) }}>
          <Stack sx={{ gap: theme.spacing(3) }}>
            <Typography
              variant="globalM"
              fontWeight="fontWeightSemiBold"
            >
              {t('CONFIGURATION_STREAM')}
            </Typography>
            <Stack sx={{ gap: theme.spacing(2) }}>
              <HuCardContainer sx={{ width: '100%', py: theme.spacing(1) }}>
                <Stack
                  sx={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    justifyContent: 'space-between',
                  }}
                >
                  <Stack
                    sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}
                  >
                    <Typography variant="globalS">
                      {t('NOTIFY_AUDIENCE')}
                    </Typography>
                    {canSendPush && (
                      <HuTooltip description={t('NOTIFY_AUDIENCE_TOOLTIP')}>
                        <IconInfoCircle
                          color={theme.palette.new.text.neutral.default}
                        />
                      </HuTooltip>
                    )}
                  </Stack>
                  <HuFormSwitcher
                    name="sendNotification"
                    switcherProps={{
                      sx: { width: 'unset' },
                      title: '',
                      description: '',
                      disabled: !canSendPush || isStreaming,
                    }}
                  />
                </Stack>
              </HuCardContainer>
              {canDisableComments && (
                <HuCardContainer sx={{ width: '100%', py: theme.spacing(1) }}>
                  <Stack
                    sx={{
                      flexDirection: 'row',
                      alignItems: 'center',
                      justifyContent: 'space-between',
                    }}
                  >
                    <Typography variant="globalS">
                      {t('ALLOW_COMMENTS')}
                    </Typography>
                    <HuFormSwitcher
                      name="commentsEnabled"
                      switcherProps={{
                        sx: { width: 'unset' },
                        title: '',
                        description: '',
                      }}
                    />
                  </Stack>
                </HuCardContainer>
              )}
            </Stack>
          </Stack>
          <Stack sx={{ gap: theme.spacing(3) }}>
            <Typography
              variant="globalM"
              fontWeight="fontWeightSemiBold"
            >
              {t('CONFIGURATION_STREAM_VIEWER')}
            </Typography>
            <Stack sx={{ gap: theme.spacing(2) }}>
              <HuCardContainer sx={{ width: '100%', py: theme.spacing(1) }}>
                <HuFormSwitcher
                  name="hlsEnabled"
                  switcherProps={{
                    title: t('ALLOW_LIVE_REWIND'),
                    description: t('ALLOW_LIVE_REWIND_INFO'),
                    disabled: isStreaming || captionsEnabled,
                    disabledTooltip: {
                      disableTooltip: !(isStreaming || captionsEnabled),
                      description: t('LIVE_REWIND_DISABLED_INFO'),
                    },
                  }}
                />
              </HuCardContainer>
              <HuCardContainer sx={{ width: '100%', py: theme.spacing(1) }}>
                <HuFormSwitcher
                  name="captionsEnabled"
                  switcherProps={{
                    title: t('ALLOW_CLOSED_CAPTIONS'),
                    description: t('ALLOW_CLOSED_CAPTIONS_INFO'),
                    disabled: hlsEnabled,
                    disabledTooltip: {
                      disableTooltip: !hlsEnabled,
                      description: t('CLOSED_CAPTIONS_DISABLED_INFO'),
                    },
                  }}
                />
              </HuCardContainer>
              {captionsEnabled && (
                <HuFormInputSelect
                  name="captionsLanguage"
                  inputProps={{
                    label: t('CAPTIONS_LANGUAGE'),
                    helperText: t('CAPTIONS_LANGUAGE_INFO'),
                    options: captionsLanguagesOptions,
                    disabled: isStreaming,
                  }}
                />
              )}
              <Stack
                sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}
              >
                <IconInfoCircle
                  color={theme.palette.new.text.neutral.default}
                />
                <Typography variant="globalS">
                  {t('MAX_DURATION_WARNING', {
                    hours: MAX_LIVE_HOURS_DURATION,
                  })}
                </Typography>
              </Stack>
            </Stack>
          </Stack>
        </Stack>
      )}
    </>
  );
};

export default FormConfigurationLiveStream;
