import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import { Close } from '@mui/icons-material';

import { REDUX_ERROR_PROP_NAME } from '@/modules/@common/Form/constants';

import { getDefaultDomain } from '../../../helpers/getDefaultDomain';
import { getCanReadOnly, getHasAccount, shouldDisablePublish } from '../../../helpers/getRestrictions';
import * as selectors from '../../../redux/selectors';
import {
  getAccountOptionsAction,
  removeErrorByPropAction,
  setAction,
  setErrorByPropAction,
  setInitialAction,
  validateSingleField,
} from '../../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import { getUserPermissionsSelector, getUserRoleTypeSelector } from '@/modules/@common/user/redux/selectors';

import { FormRow, useFormSettings } from '@/modules/@common/Form';
import ItemList from '../../ItemList/ItemList';
import { Autocomplete, Button, IconButton, InputAdornment, Switch, TextField } from '@/mui/components';

const NAME_MAX_LENGTH = 45;

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

  // selectors
  const account = useSelector(selectors.accountSelector);
  const accountOptions = useSelector(selectors.accountOptionsSelector);
  const name = useSelector(selectors.nameSelector);
  const domains = useSelector(selectors.domainsSelector);
  const publish = useSelector(selectors.publishSelector);
  const scheme = useSelector(selectors.schemeSelector);
  const userRoleType = useSelector(getUserRoleTypeSelector);
  const userPermissions = useSelector(getUserPermissionsSelector);

  // local state
  const [domain, setDomain] = useState('');

  const id = parseInt(router.query.id, 10);
  const hasAccount = getHasAccount(userRoleType);
  const canReadOnly = getCanReadOnly(id, userPermissions);

  // handlers
  const handleSetState = (state) => dispatch(setAction(state));

  const handleAddDomain = () => {
    const regExp = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$/;

    const newDomainsList = [].concat(domains, {
      label: domain,
      isDisabled: false,
    });
    const data = validateSingleField('domains', newDomainsList);

    if (!data[REDUX_ERROR_PROP_NAME] && !regExp.test(domain)) {
      data[REDUX_ERROR_PROP_NAME] = 'Invalid domain name';
    }

    if (!data[REDUX_ERROR_PROP_NAME]) {
      handleSetState({
        domains: newDomainsList,
      });
      setDomain('');
    }

    dispatch(setErrorByPropAction([data]));
  };

  const handleDeleteDomain = (indexForDelete) => {
    handleSetState({
      domains: domains.filter((_, index) => index !== indexForDelete),
    });
  };

  useEffect(() => {
    dispatch(setInitialAction());
    if (!id) {
      const defaultDomain = getDefaultDomain();
      handleSetState({
        domains: defaultDomain ? [{ label: defaultDomain, isDisabled: true }] : [],
      });
    }
  }, []);

  return (
    <>
      {!hasAccount && (
        <FormRow label="Account">
          <Autocomplete
            size={size}
            loading={!accountOptions}
            options={accountOptions || []}
            value={account}
            disabled={!!id || canReadOnly}
            renderInput={(params) => (
              <TextField
                {...params}
                required
                value=""
                variant="outlined"
                placeholder="Select Account"
                label="Required"
                onChange={(e) => dispatch(getAccountOptionsAction({ searchText: e.target.value }))}
                {...getInputPropsByName(scheme, ['account'])}
                onFocus={() => dispatch(removeErrorByPropAction(['account']))}
              />
            )}
            onOpen={() => dispatch(getAccountOptionsAction())}
            onChange={(e, account$) => handleSetState({ account: account$ })}
          />
        </FormRow>
      )}

      <FormRow label="Name">
        <TextField
          size={size}
          placeholder="Enter Hub Name"
          label="Required"
          variant="outlined"
          value={name}
          disabled={canReadOnly}
          required
          inputProps={{ maxLength: NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ name: e.target.value })}
          {...getInputPropsByName(scheme, ['name'])}
          onFocus={() => dispatch(removeErrorByPropAction(['name']))}
        />
      </FormRow>

      <FormRow label="Domains">
        <TextField
          size={size}
          placeholder="Enter Domain"
          label="Required"
          value={domain}
          disabled={canReadOnly}
          inputProps={{ maxLength: 255 }}
          InputProps={{
            endAdornment: domain ? (
              <InputAdornment position="end">
                <IconButton size={size} onClick={() => setDomain('')}>
                  <Close />
                </IconButton>
              </InputAdornment>
            ) : null,
          }}
          onChange={({ target: { value } }) => setDomain(value)}
          onKeyDown={(event) => {
            if (event.key === 'Enter') {
              handleAddDomain();
            }
          }}
          {...getInputPropsByName(scheme, ['domains'])}
          onFocus={() => dispatch(removeErrorByPropAction(['domains']))}
        />
        <Button
          variant="outlined"
          size={size}
          color="neutral"
          shape="rounded"
          disabled={canReadOnly || !domain?.trim()}
          onClick={handleAddDomain}
        >
          Add
        </Button>
      </FormRow>
      <FormRow label>
        <ItemList items={domains} onDelete={handleDeleteDomain} disabled={canReadOnly} />
      </FormRow>
      <FormRow label="Publish" tooltip="Enable the publishing of videos to YouTube and Facebook for hub users">
        <Switch
          color="primary"
          size={size}
          checked={publish}
          disabled={canReadOnly || shouldDisablePublish(userPermissions)}
          onChange={(e) => handleSetState({ publish: e.target.checked })}
        />
      </FormRow>
    </>
  );
}

export default GeneralTab;
