import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import classNames from 'clsx';
import {
  CheckCircleRounded,
  ContentCopyRounded,
  PendingRounded,
  SensorsRounded,
  SyncRounded,
} from '@mui/icons-material';

import {
  EVENT_STATUS_ARCHIVED,
  EXTERNAL_ENDPOINT,
  FAILED,
  IDLE,
  INTERNAL_ENDPOINT,
  MAX_FIELD_INPUT_SIZE,
  PROCESSING,
  RUNNING,
  SAVED,
} from '../../constants';
import languages, { booleanList } from '../../constants/livecc';
import regions, { REGIONS } from '../../constants/regions';
import { TYPE_ERROR, TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import {
  deliverySelector,
  errorsSelector,
  eventStatusSelector,
  idSelector,
  isLoadingSelector,
  liveCcEnabledSelector,
  liveCcLangSelector,
  nameSelector,
  playerIdSelector,
  regionSelector,
  rtmpInputUrlSelector,
  rtmpSecondaryInputUrlSelector,
  rtmpSecondaryStreamKeySelector,
  rtmpStreamKeySelector,
  schedulesSelector,
  statusSelector,
  streamIdSelector,
  urlSelector,
} from '../../redux/selectors';
import {
  cancelLiveStreamRequestAction,
  createLiveEventEndpointAction,
  createLiveEventFlowAction,
  setLiveStreamDataAction,
  testLiveEventEndPointAction,
} from '../../redux/slices';
import copyToClipboard from '@/modules/@common/helpers/copy';
import { showNotificationAction } from '@/modules/layout/redux/slices';

import { FormGroup, FormGroupTitle, FormRow, useFormSettings } from '@/modules/@common/Form';
import useIsAllowedToCreateOrEdit from '../../hooks/useIsAllowedToCreateOrEdit';
import {
  Button,
  Chip,
  FormControl,
  IconButton,
  InputAdornment,
  InputLabel,
  MenuItem,
  Select,
  Stack,
  TextField,
  Tooltip,
} from '@/mui/components';

import styles from './EventDelivery.module.scss';

function EventDelivery(props) {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const isAllowedToCreateOrEdit = useIsAllowedToCreateOrEdit();
  const region = useSelector(regionSelector);
  const delivery = useSelector(deliverySelector);
  const rtmpInputUrl = useSelector(rtmpInputUrlSelector);
  const rtmpStreamKey = useSelector(rtmpStreamKeySelector);
  const url = useSelector(urlSelector);
  const schedules = useSelector(schedulesSelector);
  const status = useSelector(statusSelector);
  const streamId = useSelector(streamIdSelector);
  const playerId = useSelector(playerIdSelector);
  const name = useSelector(nameSelector);
  const id = useSelector(idSelector);
  const isLoading = useSelector(isLoadingSelector);
  const eventStatus = useSelector(eventStatusSelector);
  const errors = useSelector(errorsSelector);
  const rtmpSecondaryInputUrl = useSelector(rtmpSecondaryInputUrlSelector);
  const rtmpSecondaryStreamKey = useSelector(rtmpSecondaryStreamKeySelector);
  const liveCcEnabled = useSelector(liveCcEnabledSelector);
  const liveCcLang = useSelector(liveCcLangSelector);

  const isArchived = eventStatus === EVENT_STATUS_ARCHIVED;

  const isRegionNotSupported = () => [REGIONS.nordics, REGIONS.apac, REGIONS.india].includes(region);

  const handleCreateEndpoint = () => {
    if (!streamId && !id) {
      dispatch(createLiveEventFlowAction());
      return;
    }
    dispatch(createLiveEventEndpointAction(streamId));
  };

  const handleTestEndpoint = () => dispatch(testLiveEventEndPointAction());

  useEffect(() => {
    if (isRegionNotSupported()) {
      props.handleOnChange('liveCcEnabled', false);
    }
  }, [region]);

  useEffect(() => {
    dispatch(cancelLiveStreamRequestAction());

    if (status === FAILED) {
      dispatch(
        showNotificationAction({
          type: TYPE_ERROR,
          message: 'Try to create endpoint again',
        }),
      );
    } else if (streamId && [PROCESSING, RUNNING, SAVED].includes(status) && delivery === INTERNAL_ENDPOINT) {
      dispatch(setLiveStreamDataAction({ repeatRequest: true }));
    }

    return () => dispatch(cancelLiveStreamRequestAction());
  }, [streamId, status]);

  const testEndpointProps = {
    label: streamId && url ? 'Test Endpoint' : 'Create Endpoint',
    disabled:
      streamId && url
        ? !isAllowedToCreateOrEdit || status !== IDLE || !streamId || isLoading || isArchived
        : !isAllowedToCreateOrEdit ||
          schedules.length === 0 ||
          !playerId ||
          !name ||
          (url && streamId && status !== FAILED) ||
          [PROCESSING, SAVED, IDLE].includes(status) ||
          isLoading ||
          isArchived ||
          (liveCcEnabled && !liveCcLang) ||
          Object.keys(errors).some((key) => !errors[key].isValid),
    onClick: streamId && url ? handleTestEndpoint : handleCreateEndpoint,
  };

  const { StatusIcon, statusIconColor, StatusChipIcon, statusChipColor, statusLabel, statusTooltip } =
    {
      [RUNNING]: {
        statusLabel: 'Endpoint is deployed',
        statusTooltip: 'live',
        StatusIcon: SensorsRounded,
        statusIconColor: 'success.main',
        StatusChipIcon: CheckCircleRounded,
        statusChipColor: 'success',
        StatusLabel: null,
      },
      [IDLE]: {
        statusLabel: 'Endpoint is deployed',
        statusTooltip: 'Idle',
        StatusIcon: SyncRounded,
        statusIconColor: 'shades.800',
        StatusChipIcon: CheckCircleRounded,
        statusChipColor: 'success',
        StatusLabel: null,
      },
      [PROCESSING]: {
        statusLabel: url
          ? 'Endpoint is going live; this may take up to 5 min'
          : 'Endpoint is deploying; this can take up to 10 min',
        statusTooltip: 'Processing',
        StatusIcon: SyncRounded,
        statusIconColor: 'primary.main',
        StatusChipIcon: PendingRounded,
        statusChipColor: 'primary',
        StatusLabel: null,
      },
    }[status] || {};

  return (
    <>
      <FormRow label="Delivery" tooltip="Select the type of endpoint you want to use">
        <Select
          size={size}
          disabled={!isAllowedToCreateOrEdit || !!streamId || isArchived}
          variant="outlined"
          value={delivery}
          onChange={(e) => props.handleOnChange('delivery', e.target.value)}
        >
          <MenuItem key="anyclip" value={INTERNAL_ENDPOINT}>
            Use AnyClip Endpoint
          </MenuItem>
          <MenuItem key="custom" value={EXTERNAL_ENDPOINT}>
            Use My Endpoint
          </MenuItem>
        </Select>
      </FormRow>
      <>
        {delivery === INTERNAL_ENDPOINT ? (
          <>
            <FormRow
              label="Region"
              tooltip="Select the region for the endpoint based on proximity to your target audience"
            >
              <Select
                size={size}
                disabled={!isAllowedToCreateOrEdit || [PROCESSING, RUNNING, IDLE, SAVED].includes(status) || isArchived}
                value={region}
                onChange={(e) => props.handleOnChange('region', e.target.value)}
              >
                {regions.map(({ label, value }) => (
                  <MenuItem key={value} value={value}>
                    {label}
                  </MenuItem>
                ))}
              </Select>
            </FormRow>
            <FormRow
              label="Live CC"
              tooltip={
                isRegionNotSupported()
                  ? 'There is no Live CC support for this region, please contact your account admin'
                  : null
              }
            >
              <Select
                size={size}
                value={liveCcEnabled}
                disabled={!isAllowedToCreateOrEdit || !!streamId || isRegionNotSupported()}
                onChange={(e) => props.handleOnChange('liveCcEnabled', e.target.value)}
              >
                {booleanList.map((item) => (
                  <MenuItem key={item.label} value={item.value}>
                    {item.label}
                  </MenuItem>
                ))}
              </Select>
            </FormRow>
            {liveCcEnabled && (
              <FormRow label="Language">
                <FormControl size={size} fullWidth>
                  <InputLabel size={size} required>
                    Required
                  </InputLabel>
                  <Select
                    size={size}
                    labelId="language"
                    defaultValue="Select Language"
                    label="Required"
                    required
                    value={liveCcLang ?? ''}
                    disabled={!isAllowedToCreateOrEdit || !!streamId || isRegionNotSupported()}
                    onChange={(e) => props.handleOnChange('liveCcLang', e.target.value)}
                  >
                    <MenuItem value="" disabled>
                      Select Language
                    </MenuItem>
                    {languages.map(({ label, value }) => (
                      <MenuItem key={value} value={value}>
                        {label}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
              </FormRow>
            )}
            <FormRow
              multiline
              label="Endpoint"
              tooltip={
                streamId && url
                  ? 'Test endpoint to preview your live event flow'
                  : 'Creating a new endpoint can take up to 10 minutes. ' +
                    'You can either wait until the endpoint is ready or continue to the “Event Pre/Post” tab.'
              }
            >
              <Button
                size={size}
                disabled={testEndpointProps.disabled}
                variant="outlined"
                onClick={testEndpointProps.onClick}
              >
                {testEndpointProps.label}
              </Button>

              {StatusIcon && (
                <>
                  <Tooltip title={statusTooltip} placement="top">
                    <IconButton size={size} readOnly className={styles.ProcessIconWrapper}>
                      <StatusIcon
                        color={statusIconColor}
                        className={classNames(styles.ProcessIcon, {
                          [styles.ProcessIcon___spin]: status === IDLE,
                        })}
                      />
                    </IconButton>
                  </Tooltip>
                  <Stack fullWidth justifyContent="flex-start" alignItems="flex-start">
                    <Chip
                      color={statusChipColor}
                      variant="text"
                      size={size}
                      label={statusLabel}
                      icon={<StatusChipIcon />}
                    />
                  </Stack>
                </>
              )}
            </FormRow>
            <FormGroupTitle>PRIMARY</FormGroupTitle>
            <FormGroup>
              <FormRow label="RTMP Input URL" tooltip="Add this URL to your RTMP encoder - primary URL">
                <TextField
                  size={size}
                  value={rtmpInputUrl}
                  disabled={!isAllowedToCreateOrEdit}
                  InputProps={{
                    readOnly: true,
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          data-id="copyRtmpInputUrl"
                          onClick={() => {
                            copyToClipboard(rtmpInputUrl).then(() => {
                              dispatch(
                                showNotificationAction({
                                  type: TYPE_SUCCESS,
                                  message: 'RTMP Input URL Copied Successfully',
                                }),
                              );
                            });
                          }}
                        >
                          <ContentCopyRounded />
                        </IconButton>
                      </InputAdornment>
                    ),
                  }}
                />
              </FormRow>
              <FormRow label="RTMP Stream Key" tooltip="Add this stream key to your RTMP encoder - primary stream key">
                <TextField
                  size={size}
                  value={rtmpStreamKey}
                  data-id="rtmpStreamKey"
                  disabled={!isAllowedToCreateOrEdit}
                  InputProps={{
                    readOnly: true,
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          data-id="copyRtmpStreamKey"
                          onClick={() => {
                            copyToClipboard(rtmpStreamKey).then(() => {
                              dispatch(
                                showNotificationAction({
                                  type: TYPE_SUCCESS,
                                  message: 'RTMP Stream Key Copied Successfully',
                                }),
                              );
                            });
                          }}
                        >
                          <ContentCopyRounded />
                        </IconButton>
                      </InputAdornment>
                    ),
                  }}
                />
              </FormRow>
            </FormGroup>
            <FormGroupTitle>SECONDARY</FormGroupTitle>
            <FormGroup>
              <FormRow label="RTMP Input URL" tooltip="Add this URL to your RTMP encoder - secondary URL (optional)">
                <TextField
                  size={size}
                  value={rtmpSecondaryInputUrl}
                  disabled={!isAllowedToCreateOrEdit}
                  InputProps={{
                    readOnly: true,
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          data-id="copyrtmpSecondaryInputUrl"
                          onClick={() => {
                            copyToClipboard(rtmpSecondaryInputUrl).then(() => {
                              dispatch(
                                showNotificationAction({
                                  type: TYPE_SUCCESS,
                                  message: 'RTMP Input URL Copied Successfully',
                                }),
                              );
                            });
                          }}
                        >
                          <ContentCopyRounded />
                        </IconButton>
                      </InputAdornment>
                    ),
                  }}
                />
              </FormRow>
              <FormRow
                label="RTMP Stream Key"
                tooltip="Add this stream key to your RTMP encoder - secondary stream key (optional)"
              >
                <TextField
                  size={size}
                  value={rtmpSecondaryStreamKey}
                  disabled={!isAllowedToCreateOrEdit}
                  InputProps={{
                    readOnly: true,
                    endAdornment: (
                      <InputAdornment position="end">
                        <IconButton
                          data-id="copyrtmpSecondaryStreamKey"
                          onClick={() => {
                            copyToClipboard(rtmpSecondaryStreamKey).then(() => {
                              dispatch(
                                showNotificationAction({
                                  type: TYPE_SUCCESS,
                                  message: 'RTMP Stream Key Copied Successfully',
                                }),
                              );
                            });
                          }}
                        >
                          <ContentCopyRounded />
                        </IconButton>
                      </InputAdornment>
                    ),
                  }}
                />
              </FormRow>
            </FormGroup>
            <FormRow label="HLS Output URL">
              <TextField
                size={size}
                value={delivery === INTERNAL_ENDPOINT && !streamId ? '' : url}
                disabled={!isAllowedToCreateOrEdit}
                InputProps={{
                  readOnly: true,
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton
                        data-id="copyHlsOutputUrl"
                        onClick={() => {
                          copyToClipboard(url).then(() => {
                            dispatch(
                              showNotificationAction({
                                type: TYPE_SUCCESS,
                                message: 'HLS Output URL Copied Successfully',
                              }),
                            );
                          });
                        }}
                      >
                        <ContentCopyRounded />
                      </IconButton>
                    </InputAdornment>
                  ),
                }}
              />
            </FormRow>
          </>
        ) : (
          <FormRow label="HLS Output URL" tooltip="Add the HLS Output URL from your CDN">
            <TextField
              size={size}
              disabled={!isAllowedToCreateOrEdit || isArchived}
              placeholder="Add HLS output URL"
              value={url}
              error={errors.url && !errors.url?.isValid}
              label={errors.url?.message || 'Required'}
              required
              onChange={(event) => props.handleOnChange('url', event.target.value)}
              inputProps={{
                maxlength: MAX_FIELD_INPUT_SIZE,
              }}
            />
          </FormRow>
        )}
      </>
    </>
  );
}

EventDelivery.propTypes = {
  handleOnChange: PropTypes.func.isRequired,
};

export default EventDelivery;
