import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import {
  CLEAN_RULE_OPTIONS,
  CLEAN_RULE_TYPE_ALL,
  CLEAN_RULE_TYPE_CUSTOM,
  CLEAN_RULE_TYPE_REGEXP,
} from '../../../constants';

import * as selectors from '../../../redux/selectors';
import { removeErrorByPropAction, setAction } from '../../../redux/slices';
import { getInputPropsByName } from '@/modules/@common/Form/helpers';

import { FormGroupTitle, FormRow, useFormSettings } from '@/modules/@common/Form';
import RuleList from './components/RuleList';
import { Button, MenuItem, Select, Switch, TextField } from '@/mui/components';

const ruleValuePlaceholderMapper = {
  [CLEAN_RULE_TYPE_CUSTOM]: 'Enter comma-separated list of params to keep for all domains',
  [CLEAN_RULE_TYPE_REGEXP]: 'Enter REGEX formula for all domains',
};

const customRuleDefault = {
  cleanUrl: '',
  cleanUrlRuleType: CLEAN_RULE_TYPE_ALL,
  cleanUrlRuleValue: '',
};

const infoUrl = 'https://anyclip.atlassian.net/wiki/spaces/RD/pages/243499011/Augmentor+DMPs+-+support+unique+URLs';

function validateCustomRuleDomain(customRuleDomain, rules) {
  let error = '';

  // this regExp was taken from PCN for this module

  const regExp =
    // eslint-disable-next-line max-len
    /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i;

  if (!regExp.test(customRuleDomain)) {
    error = 'Specify valid url';
  }

  const isNotUniq = rules.some((rule) => {
    // remove http, https
    const removeProtocol = (u) => u.replace(/(^\w+:|^)\/\//, '');
    return removeProtocol(rule.cleanUrl) === removeProtocol(customRuleDomain);
  });

  if (isNotUniq) {
    error = 'Url must be unique';
  }

  return {
    error,
  };
}

function transformRefreshAttributesToInt(value = '') {
  if (!value) {
    return '';
  }

  const MAX_VALUE = 999;
  const newValue = parseInt(value, 10);

  if (newValue > MAX_VALUE) {
    return MAX_VALUE;
  }

  return newValue;
}

function AdvancedTab() {
  const { size } = useFormSettings();
  const [customRule, setCustomRule] = useState(customRuleDefault);
  const [customRuleValidationDomain, setCustomRuleValidationDomain] = useState({ error: '' });

  const dispatch = useDispatch();

  const pageRefresh = useSelector(selectors.pageRefreshSelector);
  const refreshIntervalMinutes = useSelector(selectors.refreshIntervalMinutesSelector);
  const refreshTimesLimit = useSelector(selectors.refreshTimesLimitSelector);
  const ddSpecificPublisher = useSelector(selectors.ddSpecificPublisherSelector);
  const defaultRule = useSelector(selectors.defaultRuleSelector);
  const cleanUrl = useSelector(selectors.cleanUrlSelector);
  const scheme = useSelector(selectors.schemeSelector);

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

  const handleSetCustomRule = (state = {}) => setCustomRule((rule) => ({ ...rule, ...state }));

  const handleAddCustomRule = () => {
    const { error } = validateCustomRuleDomain(customRule.cleanUrl, cleanUrl);

    setCustomRuleValidationDomain({ error });

    if (!error) {
      const cleanUrlRule = {
        cleanOrder: cleanUrl.length + 1,
        cleanUrl: customRule.cleanUrl,
        cleanUrlRuleType: customRule.cleanUrlRuleType,
        cleanUrlRuleValue: customRule.cleanUrlRuleValue,
      };

      handleSetState({ cleanUrl: [].concat(cleanUrlRule, cleanUrl) });

      setCustomRule(customRuleDefault);
    }
  };

  return (
    <>
      <FormRow
        label="Page Refresh"
        tooltip={
          <div>
            {'The interval for AnyClip Page Analyzer to be called to refresh the page content that can be\n'}
            {'needed for news sites, which content changes much more often than the default refresh period.\n'}
          </div>
        }
      >
        <Switch
          color="primary"
          size={size}
          checked={pageRefresh}
          onChange={(e) => handleSetState({ pageRefresh: e.target.checked })}
        />
      </FormRow>
      <FormRow label="Refresh every (minutes)">
        <TextField
          size={size}
          placeholder="0"
          label=""
          value={refreshIntervalMinutes}
          disabled={!pageRefresh}
          onChange={(e) =>
            handleSetState({
              refreshIntervalMinutes: transformRefreshAttributesToInt(e.target.value),
            })
          }
        />
      </FormRow>
      <FormRow label="Refresh attempts">
        <TextField
          size={size}
          placeholder="0"
          label=""
          value={refreshTimesLimit}
          disabled={!pageRefresh}
          onChange={(e) =>
            handleSetState({
              refreshTimesLimit: transformRefreshAttributesToInt(e.target.value),
            })
          }
        />
      </FormRow>
      <FormRow label="Export Data to DataDog">
        <Switch
          color="primary"
          size={size}
          checked={ddSpecificPublisher}
          onChange={(e) => handleSetState({ ddSpecificPublisher: e.target.checked })}
        />
      </FormRow>
      <FormGroupTitle>Cache URL Rules</FormGroupTitle>
      <FormRow
        label="Default Rule"
        tooltip={
          <>
            <div>Traffic Manager uses URLs as a part of the key in the cache.</div>
            <div>
              Cache URL Rules are used by Traffic Manager to clean the URL from unnecessary parts (i.e. such as ‘user’
              or ‘id’ query parameters).
            </div>
            <div>
              Default Rule is applied to all URLs except those, which are specified for the domains in Custom Rules.
            </div>
            <div>
              <a href={infoUrl} target="_blank" rel="noreferrer">
                https://anyclip.atlassian.net/wiki/spaces/RD/pages/243499011/Augmentor+DMPs+-+support+unique+URLs
              </a>
            </div>
          </>
        }
      >
        <Select
          size={size}
          value={defaultRule.cleanUrlRuleType}
          onChange={(e) => {
            dispatch(removeErrorByPropAction(['defaultRule.cleanUrlRuleValue']));

            handleSetState({
              defaultRule: {
                ...defaultRule,
                cleanUrlRuleType: e.target.value,
                cleanUrlRuleValue: '',
              },
            });
          }}
        >
          {CLEAN_RULE_OPTIONS.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </Select>
        {[CLEAN_RULE_TYPE_CUSTOM, CLEAN_RULE_TYPE_REGEXP].includes(defaultRule.cleanUrlRuleType) && (
          <TextField
            placeholder={ruleValuePlaceholderMapper[defaultRule.cleanUrlRuleType] ?? ''}
            label=""
            size={size}
            value={defaultRule.cleanUrlRuleValue}
            inputProps={{ maxLength: 255 }}
            onChange={(e) =>
              handleSetState({
                defaultRule: {
                  ...defaultRule,
                  cleanUrlRuleValue: e.target.value,
                },
              })
            }
            {...getInputPropsByName(scheme, ['defaultRule.cleanUrlRuleValue'])}
            onFocus={() => dispatch(removeErrorByPropAction(['defaultRule.cleanUrlRuleValue']))}
          />
        )}
      </FormRow>
      <FormRow label="Custom Rule">
        <TextField
          size={size}
          placeholder="Enter URL to add to list"
          value={customRule.cleanUrl}
          inputProps={{ maxLength: 255 }}
          error={customRuleValidationDomain.error}
          helperText={customRuleValidationDomain.error}
          onChange={(e) => handleSetCustomRule({ cleanUrl: e.target.value })}
        />
      </FormRow>
      <FormRow label>
        <Select
          size={size}
          value={customRule.cleanUrlRuleType}
          onChange={(e) =>
            handleSetCustomRule({
              cleanUrlRuleType: e.target.value,
              cleanUrlRuleValue: '',
            })
          }
        >
          {CLEAN_RULE_OPTIONS.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </Select>
        {[CLEAN_RULE_TYPE_CUSTOM, CLEAN_RULE_TYPE_REGEXP].includes(customRule.cleanUrlRuleType) && (
          <TextField
            size={size}
            fullWidth
            placeholder={ruleValuePlaceholderMapper[customRule.cleanUrlRuleType] ?? ''}
            label=""
            value={customRule.cleanUrlRuleValue}
            inputProps={{ maxLength: 255 }}
            onChange={(e) =>
              handleSetCustomRule({
                cleanUrlRuleValue: e.target.value,
              })
            }
          />
        )}
        <Button
          variant="outlined"
          size={size}
          color="primary"
          shape="rounded"
          disabled={
            !customRule.cleanUrl ||
            ([CLEAN_RULE_TYPE_CUSTOM, CLEAN_RULE_TYPE_REGEXP].includes(customRule.cleanUrlRuleType) &&
              !customRule.cleanUrlRuleValue)
          }
          onClick={handleAddCustomRule}
        >
          Add
        </Button>
      </FormRow>
      <FormRow label>
        <RuleList
          items={cleanUrl}
          onChangeSort={(cleanUrlRules) =>
            handleSetState({
              cleanUrl: cleanUrlRules,
            })
          }
          onDelete={(orderIndex) =>
            handleSetState({
              cleanUrl: cleanUrl.filter((o) => o.cleanOrder !== parseInt(orderIndex, 10)),
            })
          }
        />
      </FormRow>
    </>
  );
}

export default AdvancedTab;
