/**
 * Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
 */
import React, {useState} from 'react';
import {useSelector} from 'react-redux';

import LoggerFactory from 'services/logger/LoggerFactory';
import {forkChannel} from 'services/Channel.service';
import {AppStore} from 'store';
import {channelsSelector} from 'store/action/channels';

import {transformToPortalError} from 'utility/error-handler';
import {forkChannelErrorMessages} from 'constants/error-messages';

import {MultiStepModal} from 'components/modal/multi-step-modal';

import ForkChannelForm from './fork-channel-form';
import {FormResponse} from 'components/modal/modal-form-response';

interface IForkChannelModal {
  isOpen: boolean;
  setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
  channelId: string;
  alias: string;
}

export const ForkChannelModal = ({isOpen, setIsOpen, channelId, alias}: IForkChannelModal): React.JSX.Element => {
  const logger = LoggerFactory.getLogger('components/channel-icon-menu/fork-channel/ForkChannelModal');
  const channelsState = useSelector((state: AppStore) => channelsSelector(state));
  const channelList = channelsState.channels || [];
  const [formData, setFormData] = useState({
    streamCapabilities: [] as string[],
    streamTags: [] as string[],
    options: [] as string[],
    destinationChannelId: ''
  });
  const [isFormValid, setIsFormValid] = useState(false);
  const [isFetching, setIsFetching] = useState(false);
  const [forkResponse, setForkResponse] = useState<{error: string | boolean | Error; status: string | number; data?: any} | null>(null);
  const handleSubmit = async () => {
    if (!isFormValid) {
      return;
    }

    try {
      setIsFetching(true);

      const {streamCapabilities, streamTags, options, destinationChannelId} = formData;

      logger.info('Forking a channel [%s] to [%s]', channelId, destinationChannelId);

      const response = await forkChannel({
        sourceChannelId: channelId,
        destinationChannelId,
        streamCapabilities,
        streamTags,
        options
      });

      logger.info('The channel [%s] was successfully forked to [%s]', channelId, destinationChannelId);

      setForkResponse({
        status: 'ok',
        error: false,
        data: response
      });
      setIsFetching(false);
    } catch (e) {
      const {status, message, requestPayload, statusCode} = transformToPortalError(e);

      setIsFetching(false);

      const errorMessage = (forkChannelErrorMessages as Record<string, string>)[status] || message || forkChannelErrorMessages['default'];
      setForkResponse({
        status: statusCode || 'error',
        error: errorMessage
      });

      logger.error(`${errorMessage} [%s]`, status, requestPayload);
    }
  };

  const handleCloseModal = (): void => {
    setIsOpen(false);
  };

  return (
    <MultiStepModal
      isOpen={isOpen}
      closeModal={handleCloseModal}
      steps={[
        {
          title: 'Fork Channel',
          component: <ForkChannelForm alias={alias} channelList={channelList} setIsValid={setIsFormValid} setFormData={setFormData} />,
          saveButton: {
            text: 'Fork Channel',
            className: 'testId-forkChannel',
            disabled: !isFormValid || isFetching,
            onClick: handleSubmit
          }
        },
        {
          title: 'Fork Channel',
          component: <FormResponse response={forkResponse || {error: '', status: '', data: null}} />,
          cancelDisabled: true,
          saveButton: {className: 'testId-doneButton'}
        }
      ]}
    />
  );
};

export default ForkChannelModal;
