import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AddOutlined, ContentCopyRounded, DeleteRounded, InfoOutlined } from '@mui/icons-material';

import { PROVIDER_VALUE_GOOGLE } from '../../../../List/constants';
import { ALL_HUB_OPTION, ALL_OPTION_ID } from '../../../constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import * as selectors from '../../../redux/selectors';
import { getHubOptionsAction, removeErrorByPropAction, setAction } from '../../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';
import copyToClipboard from '@/modules/@common/helpers/copy';
import { showNotificationAction } from '@/modules/layout/redux/slices';
import { addAllHubsOption } from '@/modules/sso/Editor/helpers/addAllHubsOption';

import { FormGroupTitle, FormRow, useFormSettings } from '@/modules/@common/Form';
import AttributeTable from './components/AttributeTable';
import {
  Alert,
  Autocomplete,
  Button,
  IconButton,
  InputAdornment,
  Stack,
  Switch,
  TextField,
  Tooltip,
} from '@/mui/components';

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

const DISPLAY_NAME_MAX_LENGTH = 100;
const URL_NAME_MAX_LENGTH = 250;
const DOMAIN_NAME_MAX_LENGTH = 255;

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

  // selectors
  const displayName = useSelector(selectors.displayNameSelector);
  const allDomains = useSelector(selectors.allDomainsSelector);
  const onlyExisting = useSelector(selectors.onlyExistingSelector);
  const domains = useSelector(selectors.domainsSelector);
  const metadataURL = useSelector(selectors.metadataURLSelector);
  const settingsSingleSignOnUrl = useSelector(selectors.settingsSingleSignOnUrlSelector);
  const settingsAudienceUri = useSelector(selectors.settingsAudienceUriSelector);
  const settingsAllDomainsDisabled = useSelector(selectors.settingsAllDomainsDisabledSelector);
  const ssoDefaultHubs = useSelector(selectors.ssoDefaultHubsSelector);
  const hubOptions = useSelector(selectors.hubOptionsSelector);
  const provider = useSelector(selectors.providerSelector);
  const settingsCannotCreateProfile = useSelector(selectors.settingsCannotCreateProfileSelector);

  const scheme = useSelector(selectors.schemeSelector);

  // handlers
  const handleSetState = (state) => dispatch(setAction(state));
  const handleAddDomainFiled = () => {
    dispatch(setAction({ domains: [...domains, ''] }));
  };
  const handleRemoveDomainField = (index) => {
    const newDomains = [...domains.slice(0, index), ...domains.slice(index + 1)];
    dispatch(setAction({ domains: newDomains }));
  };
  const handleOnChangeDomainField = (index, value) => {
    const newDomains = domains.map((domainValue, domainIndex) => (domainIndex === index ? value : domainValue));
    dispatch(setAction({ domains: newDomains }));
  };
  const handleCopyToClipboard = async (value) => {
    const res = await copyToClipboard(value);
    if (res) {
      dispatch(
        showNotificationAction({
          type: TYPE_SUCCESS,
          message: 'Copied',
        }),
      );
    }
  };

  return (
    <>
      {settingsCannotCreateProfile && (
        <FormRow fullWidth>
          <Alert severity="error" variant="outlined" size="small" shape="rounded">
            This option is disabled since other profile is set with &#34;Allow users to use any domain when they use
            Single Sign-On&#34;
          </Alert>
        </FormRow>
      )}
      <FormGroupTitle>Settings</FormGroupTitle>
      <FormRow label="Profile Name">
        <TextField
          size={size}
          placeholder="Profile Name"
          value={displayName}
          inputProps={{ maxLength: DISPLAY_NAME_MAX_LENGTH }}
          onChange={(e) => handleSetState({ displayName: e.target.value })}
          {...getInputPropsByName(scheme, ['displayName'])}
          onFocus={() => dispatch(removeErrorByPropAction(['displayName']))}
        />
      </FormRow>
      <FormRow
        label="Allow users to use any domain when they use Single Sign-On"
        tooltip="This toggle can be turned on ONLY when there are no other profiles from the same type set"
      >
        <Switch
          size={size}
          color="primary"
          checked={allDomains}
          disabled={settingsAllDomainsDisabled}
          onChange={({ target }) =>
            handleSetState({
              allDomains: target.checked,
              domains: !domains.length ? [''] : domains,
              onlyExisting: target.checked || onlyExisting,
            })
          }
        />
      </FormRow>

      <FormRow
        label="Only existing users can use Single Sign-On"
        tooltip="Toggled On - Only users that currently exist in AnyClip will be able to use Single Sign-On. Toggled Off - Users that currently do not exist in AnyClip will be created in the system as soon as they are authenticated by Single Sign-On"
      >
        <Switch
          size={size}
          color="primary"
          checked={onlyExisting}
          disabled={allDomains}
          onChange={({ target }) =>
            handleSetState({
              onlyExisting: target.checked,
            })
          }
        />
      </FormRow>

      {!allDomains && (
        <FormRow
          label="Domains"
          tooltip="Enter the domain name you want Single Sign-On to apply to. Ensure the domain name is valid (e.g. DomainName.com)."
          multiline
        >
          {domains.map((_, index) => (
            <FormRow fullWidth key={index} multiline>
              <Stack direction="row" gap={1} fullWidth className={styles.DomainFieldRow}>
                <TextField
                  size={size}
                  placeholder="Add domain"
                  value={domains[index]}
                  inputProps={{ maxLength: DOMAIN_NAME_MAX_LENGTH }}
                  onChange={(e) => handleOnChangeDomainField(index, e.target.value)}
                  {...getInputPropsByName(scheme, ['domains', index])}
                  onFocus={() => dispatch(removeErrorByPropAction(['domains', index]))}
                />
                {domains.length > 1 && (
                  <div className={styles.DomainFieldDelete}>
                    <IconButton size={size} component="span" onClick={() => handleRemoveDomainField(index)}>
                      <DeleteRounded />
                    </IconButton>
                  </div>
                )}
              </Stack>
            </FormRow>
          ))}
          <FormRow justifyContent="flex-end" fullWidth>
            <Button
              size={size}
              variant="text"
              color="primary"
              label="ADD OPTION"
              startIcon={<AddOutlined />}
              onClick={handleAddDomainFiled}
            >
              Add Domain
            </Button>
          </FormRow>
        </FormRow>
      )}

      {provider !== PROVIDER_VALUE_GOOGLE && (
        <FormRow
          label="IdP Metadata"
          tooltip="SAML metadata is a URL to an XML document set in the IdP account, which contains information necessary for interaction with a SAML-enabled identity or service provider"
        >
          <TextField
            size={size}
            placeholder="IdP Metadata"
            value={metadataURL}
            inputProps={{ maxLength: URL_NAME_MAX_LENGTH }}
            onChange={(e) => handleSetState({ metadataURL: e.target.value })}
            {...getInputPropsByName(scheme, ['metadataURL'])}
            onFocus={() => dispatch(removeErrorByPropAction(['metadataURL']))}
          />
        </FormRow>
      )}

      {provider !== PROVIDER_VALUE_GOOGLE && (
        <>
          <FormGroupTitle>
            <Stack direction="row" gap={1} alignItems="center">
              <span>The following properties are required for {provider} settings</span>
              <Tooltip title="The following parameters need to be set in your IdP profile">
                <InfoOutlined fontSize={size} htmlColor="info.main" />
              </Tooltip>
            </Stack>
          </FormGroupTitle>
          <FormRow label="Single Sign-On URL">
            <TextField
              size={size}
              placeholder="Single Sign-On URL"
              value={settingsSingleSignOnUrl}
              inputProps={{
                readOnly: true,
              }}
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <IconButton onClick={() => handleCopyToClipboard(settingsSingleSignOnUrl)}>
                      <ContentCopyRounded />
                    </IconButton>
                  </InputAdornment>
                ),
              }}
            />
          </FormRow>
          <FormRow label="Audience URI (SP Entity ID)">
            <TextField
              size={size}
              placeholder="Audience URI (SP Entity ID)"
              value={settingsAudienceUri}
              inputProps={{
                readOnly: true,
              }}
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <IconButton onClick={() => handleCopyToClipboard(settingsAudienceUri)}>
                      <ContentCopyRounded />
                    </IconButton>
                  </InputAdornment>
                ),
              }}
            />
          </FormRow>
        </>
      )}

      {!onlyExisting && (
        <>
          <FormGroupTitle>
            <Stack direction="row" gap={1} alignItems="center">
              <span>Assign New Users To Hubs</span>
              <Tooltip title="Create rules for assigning new users to Hubs. Default or customer rules determine Hub assignment.">
                <InfoOutlined fontSize={size} htmlColor="info.main" />
              </Tooltip>
            </Stack>
          </FormGroupTitle>

          <FormRow label="By default new users will be assigned to the following Hubs">
            <Stack fullWidth>
              <Autocomplete
                fullWidth
                multiple
                value={ssoDefaultHubs || []}
                options={addAllHubsOption(hubOptions) || []}
                optionValueKey="id"
                optionLabelKey="name"
                loading={!hubOptions}
                size={size}
                filterSelectedOptions
                disableClearable
                filterOptions={(options) => {
                  const hasAllOption = ssoDefaultHubs.some((option) => option.id === ALL_OPTION_ID);
                  return hasAllOption ? [] : options;
                }}
                onChange={(e, selected) => {
                  const hasAllOption = selected.some((option) => option.id === ALL_OPTION_ID);
                  handleSetState({
                    allHubs: hasAllOption,
                    ssoDefaultHubs: hasAllOption ? [ALL_HUB_OPTION] : selected,
                  });
                }}
                onOpen={() => {
                  dispatch(getHubOptionsAction(''));
                }}
                onInputChange={(e, searchText) => dispatch(getHubOptionsAction(searchText))}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    value=""
                    placeholder="Select Hub"
                    {...getInputPropsByName(scheme, ['ssoDefaultHubs'])}
                    onFocus={() => dispatch(removeErrorByPropAction(['ssoDefaultHubs']))}
                  />
                )}
              />
            </Stack>
          </FormRow>

          {provider !== PROVIDER_VALUE_GOOGLE && (
            <>
              <FormGroupTitle>Create custom rules for assigning users to Hubs</FormGroupTitle>
              <FormRow fullWidth>
                <AttributeTable />
              </FormRow>
            </>
          )}
        </>
      )}
    </>
  );
}

export default GeneralTab;
