import React, { useEffect, useState } from 'react';
import capitalize from 'lodash/capitalize';
import find from 'lodash/find';
import { compose } from 'redux';
import { useSelector, useDispatch } from 'react-redux';
import { FormattedMessage, useIntl } from 'react-intl';
import { toast } from 'react-toastify';
import {
  Button,
  Divider,
  Dropdown,
  Form,
  Header,
  Input,
  Popup,
  Tab,
} from 'semantic-ui-react';
import withObjectBrowser from '@plone/volto/components/manage/Sidebar/ObjectBrowser';
import { messages } from '@plone/volto/helpers/MessageLabels/MessageLabels';
import Icon from '@plone/volto/components/theme/Icon/Icon';
import Toast from '@plone/volto/components/manage/Toast/Toast';
import {
  getRelationStats,
  queryRelations,
} from '@plone/volto/actions/relations/relations';
import { rebuildRelations } from '@plone/volto/actions/relations/rebuild';
import RelationsListing from '@plone/volto/components/manage/Controlpanels/Relations/RelationsListing';
import BrokenRelations from '@plone/volto/components/manage/Controlpanels/Relations/BrokenRelations';
import helpSVG from '@plone/volto/icons/help.svg';
import clearSVG from '@plone/volto/icons/clear.svg';
import navTreeSVG from '@plone/volto/icons/nav.svg';

const RelationsMatrix = (props) => {
  const intl = useIntl();
  const dispatch = useDispatch();

  const [query_source, setQuery_source] = useState('');
  const [query_target, setQuery_target] = useState('');
  const [potential_targets_path, setPotential_targets_path] = useState('');
  const [potential_sources_path, setPotential_sources_path] = useState('');
  const [relationtype, setRelationtype] = useState(undefined);

  const actions = useSelector((state) => state.actions?.actions ?? {});
  const can_fix_relations = find(actions.user, {
    id: 'plone_setup',
  });

  const relationtypes = useSelector(
    (state) => state.relations?.stats?.data?.stats,
  );
  const relationsListError = useSelector(
    (state) => state.relations?.stats?.error?.response?.body?.error,
  );
  const brokenRelations = useSelector(
    (state) => state.relations?.stats?.data?.broken,
  );

  let filter_options = useSelector((state) => state.groups.filter_groups);
  if (filter_options) {
    filter_options = filter_options.map((group) => ({
      value: group.id,
      label: group.title || group.id,
    }));
    filter_options.sort(function (a, b) {
      var labelA = a.label.toUpperCase();
      var labelB = b.label.toUpperCase();
      if (labelA < labelB) {
        return -1;
      }
      if (labelA > labelB) {
        return 1;
      }
      return 0;
    });
  }

  useEffect(() => {
    dispatch(getRelationStats());
  }, [dispatch]);

  const onReset = (event) => {
    let element = event.target.querySelector('input');
    element.value = '';
    element.focus();
    let searchtype = element.name;
    switch (searchtype) {
      case 'SearchY':
        setQuery_source('');
        break;
      case 'SearchX':
        setQuery_target('');
        break;
      case 'showPotentialTargets':
        setPotential_targets_path('/');
        break;
      case 'showPotentialSources':
        setPotential_sources_path('/');
        break;
      default:
        break;
    }
  };

  // search for sources
  const onChangeSearchYs = (event) => {
    if (event.target.value.length > 1) {
      setQuery_source(event.target.value);
    } else {
      setQuery_source('');
    }
  };

  // search for targets
  const onChangeSearchXs = (event) => {
    if (event.target.value.length > 1) {
      setQuery_target(event.target.value);
    } else {
      setQuery_source('');
    }
  };

  const onChangeRelation = (event, { value }) => {
    setRelationtype(value);
  };

  const onChangeShowPotentialSources = (_value) => {
    let newValue = _value;
    setPotential_sources_path(newValue);
  };

  const onChangeShowPotentialTargets = (_value) => {
    let newValue = _value;
    setPotential_targets_path(newValue);
  };

  const rebuildRelationsHandler = (flush = false) => {
    dispatch(rebuildRelations(flush))
      .then(() => {
        dispatch(getRelationStats());
        dispatch(queryRelations(null, true, 'broken'));
      })
      .then(() => {
        toast.success(
          <Toast
            success
            title={intl.formatMessage(messages.success)}
            content="Relations updated"
          />,
        );
      })
      .catch((error) => {
        // TODO: The true error sent by the API is shadowed by the superagent one
        // Update this when this issue is fixed.
        const shadowedError = JSON.parse(error.response.text);
        toast.error(
          <Toast
            error
            title={shadowedError.error.type}
            content={shadowedError.error.message}
          />,
        );
      });
  };

  const clear_potential_sources_path = () => {
    setPotential_sources_path('');
    // onChange(id, undefined);
  };

  const clear_potential_targets_path = () => {
    setPotential_targets_path('');
    // onChange(id, undefined);
  };

  const panes = [
    {
      menuItem: intl.formatMessage(messages.inspectRelations),
      pane: (
        <Tab.Pane attached={true} key="fix">
          {relationtypes ? (
            <div className="controlpanel_matrix">
              <div className="controlpanel_select_relation">
                <Divider hidden />
                <Form className="select_relation">
                  <Form.Field>
                    <Header as="h3">
                      <Header.Content>
                        <FormattedMessage
                          id="Relation name"
                          defaultMessage="Relation"
                        />{' '}
                        <Dropdown
                          placeholder={
                            relationtype ||
                            intl.formatMessage(messages.selectRelation)
                          }
                        >
                          <Dropdown.Menu>
                            {Object.keys(relationtypes).map((relationtype) => (
                              <Dropdown.Item
                                onClick={onChangeRelation}
                                value={relationtype}
                                className={`select-relation-${relationtype}`}
                                key={relationtype}
                              >
                                {`${relationtype} (${relationtypes[relationtype]})`}
                              </Dropdown.Item>
                            ))}
                          </Dropdown.Menu>
                        </Dropdown>
                      </Header.Content>
                    </Header>
                  </Form.Field>
                </Form>
              </div>
              {relationtype ? (
                <>
                  <div className="controlpanel_search_wrapper">
                    <div className="controlpanel_search_y">
                      <Header as="h4">
                        <Header.Content>
                          <FormattedMessage
                            id="Source"
                            defaultMessage="Source"
                          />
                        </Header.Content>
                      </Header>
                      <Form className="search_y" onSubmit={onReset}>
                        <Form.Field>
                          <Input
                            name="SearchY"
                            placeholder={intl.formatMessage(
                              messages.searchRelationSource,
                            )}
                            onChange={onChangeSearchYs}
                            id="y-search-input"
                          />
                          <Button.Group>
                            <Button
                              basic
                              className="cancel"
                              aria-label="cancel"
                              onClick={(e) => {
                                e.preventDefault();
                                e.stopPropagation();
                                document.querySelector(
                                  'input[name="SearchY"]',
                                ).value = '';
                                setQuery_source('');
                              }}
                            >
                              <Icon name={clearSVG} size="24px" />
                            </Button>
                          </Button.Group>
                        </Form.Field>
                      </Form>
                      <Form
                        className="add_potential_sources"
                        onSubmit={onReset}
                      >
                        <Form.Field>
                          <Input
                            name="showPotentialSources"
                            type="url"
                            value={potential_sources_path}
                            placeholder={intl.formatMessage(
                              messages.addPotentialSourcesPath,
                            )}
                            onChange={({ target }) =>
                              onChangeShowPotentialSources(target.value)
                            }
                            id="potential-sources-path-input"
                          />
                          {potential_sources_path?.length > 0 ? (
                            <Button.Group>
                              <Button
                                basic
                                className="cancel"
                                aria-label="clearUrlBrowser"
                                onClick={(e) => {
                                  e.preventDefault();
                                  e.stopPropagation();
                                  clear_potential_sources_path();
                                }}
                              >
                                <Icon name={clearSVG} size="24px" />
                              </Button>
                            </Button.Group>
                          ) : (
                            <Button.Group>
                              <Button
                                basic
                                icon
                                aria-label="openUrlBrowser"
                                onClick={(e) => {
                                  e.preventDefault();
                                  e.stopPropagation();
                                  props.openObjectBrowser({
                                    mode: 'link',
                                    overlay: true,
                                    onSelectItem: (url) => {
                                      onChangeShowPotentialSources(url);
                                    },
                                  });
                                }}
                              >
                                <Icon name={navTreeSVG} size="24px" />
                              </Button>
                            </Button.Group>
                          )}
                        </Form.Field>
                        <FormattedMessage
                          id="Show potential sources. Not only objects that are source of some relation."
                          defaultMessage="Show potential sources. Not only objects that are source of some relation."
                        />
                      </Form>
                    </div>
                    <div className="controlpanel_search_x">
                      <Form className="search_x" onSubmit={onReset}>
                        <Header as="h4">
                          <Header.Content>
                            <FormattedMessage
                              id="Target"
                              defaultMessage="Target"
                            />
                          </Header.Content>
                        </Header>
                        <Form.Field>
                          <Input
                            name="SearchX"
                            placeholder={intl.formatMessage(
                              messages.searchRelationTarget,
                            )}
                            onChange={onChangeSearchXs}
                            id="x-search-input"
                          />
                          <Button.Group>
                            <Button
                              basic
                              className="cancel"
                              aria-label="cancel"
                              onClick={(e) => {
                                e.preventDefault();
                                e.stopPropagation();
                                document.querySelector(
                                  'input[name="SearchX"]',
                                ).value = '';
                                setQuery_target('');
                              }}
                            >
                              <Icon name={clearSVG} size="24px" />
                            </Button>
                          </Button.Group>
                        </Form.Field>
                      </Form>
                      <Form
                        className="add_potential_targets"
                        onSubmit={onReset}
                      >
                        <Form.Field>
                          <Input
                            name="showPotentialTargets"
                            type="url"
                            value={potential_targets_path}
                            placeholder={intl.formatMessage(
                              messages.addPotentialTargetsPath,
                            )}
                            onChange={({ target }) =>
                              onChangeShowPotentialTargets(target.value)
                            }
                            id="potential-targets-path-input"
                          />
                          {potential_targets_path?.length > 0 ? (
                            <Button.Group>
                              <Button
                                basic
                                className="cancel"
                                aria-label="clearUrlBrowser"
                                onClick={(e) => {
                                  e.preventDefault();
                                  e.stopPropagation();
                                  clear_potential_targets_path();
                                }}
                              >
                                <Icon name={clearSVG} size="24px" />
                              </Button>
                            </Button.Group>
                          ) : (
                            <Button.Group>
                              <Button
                                basic
                                icon
                                aria-label="openUrlBrowser"
                                onClick={(e) => {
                                  e.preventDefault();
                                  e.stopPropagation();
                                  props.openObjectBrowser({
                                    mode: 'link',
                                    overlay: true,
                                    onSelectItem: (url) => {
                                      onChangeShowPotentialTargets(url);
                                    },
                                  });
                                }}
                              >
                                <Icon name={navTreeSVG} size="24px" />
                              </Button>
                            </Button.Group>
                          )}
                        </Form.Field>
                        <div className="foo">
                          <FormattedMessage
                            id="Show potential targets. Not only objects that are target of some relation."
                            defaultMessage="Show potential targets. Not only objects that are target of some relation."
                          />{' '}
                          <Popup
                            trigger={
                              <a
                                href="https://6.docs.plone.org/volto/development/widget.html#widget-relation-field-label"
                                target="_blank"
                                rel="noopener noreferrer"
                              >
                                <Icon name={helpSVG} size="16px" />
                              </a>
                            }
                          >
                            <Popup.Header>Respect constraints</Popup.Header>
                            <Popup.Content>
                              <div>
                                See docs.plone.org on how to respect
                                constraints.
                              </div>
                            </Popup.Content>
                          </Popup>
                        </div>
                      </Form>
                    </div>
                  </div>
                  <div className="controlpanel_listing_wrapper">
                    <RelationsListing
                      relationtype={relationtype}
                      query_source={query_source}
                      query_target={query_target}
                      potential_targets_path={potential_targets_path}
                      potential_sources_path={potential_sources_path}
                    />
                  </div>
                </>
              ) : null}
            </div>
          ) : (
            <p>
              <b>{relationsListError?.type}</b> {relationsListError?.message}
            </p>
          )}
        </Tab.Pane>
      ),
    },
    {
      menuItem: intl.formatMessage(messages.fixRelations),
      pane: (
        <Tab.Pane attached={true} key="rebuild">
          <div>
            {!(brokenRelations && Object.keys(brokenRelations).length > 0) && (
              <div>
                <FormattedMessage
                  id="No broken relations found."
                  defaultMessage="No broken relations found."
                />
              </div>
            )}
            {can_fix_relations ? (
              <React.Fragment>
                <Divider hidden />
                <h2>
                  {capitalize(intl.formatMessage(messages.rebuildRelations))}
                </h2>

                <Button.Group>
                  <Button
                    primary
                    onClick={() => rebuildRelationsHandler(false)}
                    content={intl.formatMessage(messages.rebuildRelations)}
                    aria-label={intl.formatMessage(messages.rebuildRelations)}
                  />
                </Button.Group>

                <Divider hidden />
                <h2>
                  {capitalize(
                    intl.formatMessage(messages.flushAndRebuildRelations),
                  )}
                </h2>
                <div
                  dangerouslySetInnerHTML={{
                    __html: intl.formatMessage(
                      messages.flushAndRebuildRelationsHints,
                    ),
                  }}
                />
                <Divider hidden />
                <Button.Group>
                  <Button
                    secondary
                    color="red"
                    onClick={() => rebuildRelationsHandler(true)}
                    content={intl.formatMessage(
                      messages.flushAndRebuildRelations,
                    )}
                    aria-label={intl.formatMessage(
                      messages.flushAndRebuildRelations,
                    )}
                  />
                </Button.Group>
              </React.Fragment>
            ) : null}
            <BrokenRelations />
          </div>
        </Tab.Pane>
      ),
    },
  ];

  return (
    <Tab
      panes={panes}
      renderActiveOnly={false}
      menu={{ secondary: true, pointing: true, attached: true, tabular: true }}
    />
  );
};

export default compose(withObjectBrowser)(RelationsMatrix);
