import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';

import { REDUX_ERROR_PROP_NAME } from '@/modules/@common/Form/constants';
import { TYPE_WARNING } from '@/modules/@common/notify/constants';
import { NAME_MAX_LENGTH, PLAYER_WIDTH_UNITS_PERCENT } from '@/modules/players/Editor/constants';

import * as playerSelectors from '../../../redux/selectors';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { notifyAction } from '@/modules/@common/notify/redux/slices';
import { castToInt, isOutstreamType } from '@/modules/players/Editor/helpers';
import {
  getPublishersOptionsAction,
  removeErrorByPropAction,
  setAction,
  setActiveTabIdAction,
  setErrorByPropAction,
  setScrollToFieldNameAction,
  validateSingleField,
} from '@/modules/players/Editor/redux/slices';

import { FormRow, FormRowItem, FormSection, useFormSettings } from '@/modules/@common/Form';
import { Autocomplete, Divider, MenuItem, Select, TextField, Typography } from '@/mui/components';

function GeneralTab() {
  const { size } = useFormSettings();
  const dispatch = useDispatch();
  const router = useRouter();

  const playerType = useSelector(playerSelectors.typeSelector);
  const publisher = useSelector(playerSelectors.publisherSelector);
  const publishersOptions = useSelector(playerSelectors.publishersOptionsSelector);

  const publisherDomain = useSelector(playerSelectors.publisherDomainSelector);
  const publisherDomainsOptions = useSelector(playerSelectors.publisherDomainsOptionsSelector);

  const comments = useSelector(playerSelectors.commentsSelector);
  const alias = useSelector(playerSelectors.aliasSelector);

  const playerWidthUnitOptions = useSelector(playerSelectors.playerWidthUnitOptionsSelector);
  const playerWidthUnit = useSelector(playerSelectors.playerWidthUnitSelector);
  const playerWidth = useSelector(playerSelectors.playerWidthSelector);

  const playerAspectRatio = useSelector(playerSelectors.playerAspectRatioSelector);
  const playerAspectRatioOptions = useSelector(playerSelectors.playerAspectRatioOptionsSelector);

  const scheme = useSelector(playerSelectors.schemeSelector);

  const [domainDropDownOpen, setDomainDropDownOpen] = useState(false);

  const id = parseInt(router.query.params[1], 10) || null;
  const copyFromId = parseInt(router.query.copy, 10) || null;

  return (
    <FormSection>
      <FormRow label="Hub">
        <Autocomplete
          size={size}
          disabled={!!id || (!!copyFromId && !playerType)}
          value={publisher}
          options={id ? [publisher] : publishersOptions || []}
          loading={!publishersOptions}
          onOpen={() => dispatch(getPublishersOptionsAction({ playerType }))}
          onChange={(_, selectedPublisher) => {
            dispatch(
              setAction({
                publisher: selectedPublisher,
                publisherId: selectedPublisher?.id,
                publisherDomainsOptions: selectedPublisher?.publisherDomains ?? [],
                ...(!selectedPublisher && {
                  publisherDomain: null,
                  publisherDomainId: 0,
                  playerContentOwnerFeeds: [],
                  useDefaultContentOwner: 0,
                  editorialPlaylist: null,
                  playerEditorialPlaylistsOptions: [],
                }),
              }),
            );
            if (!selectedPublisher) {
              dispatch(removeErrorByPropAction(['playerContentOwnerFeeds']));
              dispatch(removeErrorByPropAction(['playerFeedLanguages']));
            }
          }}
          onInputChange={(_, searchText) =>
            !id &&
            dispatch(
              getPublishersOptionsAction({
                searchText,
                playerType,
              }),
            )
          }
          optionLabelKey="name"
          renderInput={(params) => (
            <TextField
              {...params}
              placeholder="Select Hub"
              {...getInputPropsByName(scheme, ['publisher'])}
              onFocus={() => dispatch(removeErrorByPropAction(['publisher']))}
            />
          )}
        />
      </FormRow>
      <FormRow label="Name">
        <TextField
          size={size}
          required
          placeholder="Enter Player Name"
          variant="outlined"
          value={alias}
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={({ target }) => dispatch(setAction({ alias: target.value }))}
          {...getInputPropsByName(scheme, ['alias'])}
          onFocus={() => dispatch(removeErrorByPropAction(['alias']))}
        />
      </FormRow>
      <FormRow label="Domain" tooltip="The list of available domains is defined under the Hub setup.">
        <Autocomplete
          open={domainDropDownOpen}
          size={size}
          value={publisherDomain}
          options={publisherDomainsOptions}
          onBlur={() => {
            setDomainDropDownOpen(false);
          }}
          onOpen={() => {
            const validation = validateSingleField('publisher', publisher);

            if (validation[REDUX_ERROR_PROP_NAME]) {
              dispatch(setErrorByPropAction([validation]));
              dispatch(setActiveTabIdAction(validation.tabId));
              dispatch(setScrollToFieldNameAction(validation.fieldName));
              dispatch(
                notifyAction({
                  type: TYPE_WARNING,
                  message: 'Please select a Hub from the list',
                }),
              );
            } else {
              setDomainDropDownOpen(true);
            }
          }}
          onChange={(_, selectedPublisherDomain) => {
            dispatch(
              setAction({
                publisherDomain: selectedPublisherDomain,
                publisherDomainId: selectedPublisherDomain?.id,
              }),
            );
            setDomainDropDownOpen(false);
          }}
          optionLabelKey="domain"
          renderInput={(params) => (
            <TextField
              {...params}
              value=""
              variant="outlined"
              placeholder="Select Domain"
              {...getInputPropsByName(scheme, ['publisherDomain'])}
              onFocus={() => {
                if (publisher) {
                  dispatch(removeErrorByPropAction(['publisherDomain']));
                }
              }}
            />
          )}
        />
      </FormRow>
      <FormRow label="Description">
        <TextField
          size={size}
          value={comments}
          multiline
          rows={5}
          placeholder="Enter Description"
          onChange={({ target }) =>
            dispatch(
              setAction({
                comments: target.value,
              }),
            )
          }
        />
      </FormRow>

      {isOutstreamType(playerType) && (
        <>
          <Divider flexItem />
          <FormRow label="Player Size">
            <Select
              size={size}
              value={playerWidthUnit}
              onChange={({ target }) =>
                dispatch(
                  setAction({
                    playerWidthUnit: target.value,
                    playerWidth: playerWidthUnitOptions.find((option) => option.value === target.value)?.defaultWidth,
                  }),
                )
              }
            >
              {playerWidthUnitOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
            <FormRowItem>
              <Typography variant="body2">Width</Typography>
            </FormRowItem>
            <FormRowItem itemsInRow={1}>
              <TextField
                value={playerWidth}
                size={size}
                disabled={playerWidthUnit === PLAYER_WIDTH_UNITS_PERCENT}
                onChange={({ target }) =>
                  dispatch(
                    setAction({
                      playerWidth: target.value,
                    }),
                  )
                }
                onBlur={({ target }) =>
                  dispatch(
                    setAction({
                      playerWidth: castToInt(target.value),
                    }),
                  )
                }
                {...getInputPropsByName(scheme, ['playerWidth'])}
                onFocus={() => dispatch(removeErrorByPropAction(['playerWidth']))}
              />
            </FormRowItem>
          </FormRow>
          <FormRow label="Aspect Ratio">
            <Select
              size={size}
              value={playerAspectRatio}
              onChange={({ target }) =>
                dispatch(
                  setAction({
                    playerAspectRatio: target.value,
                  }),
                )
              }
            >
              {playerAspectRatioOptions.map(({ value, label }) => (
                <MenuItem key={value} value={value}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          </FormRow>
        </>
      )}
    </FormSection>
  );
}

export default GeneralTab;
