import React, { useState, useReducer, useEffect, createRef } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import { useDispatch, useSelector } from 'react-redux';
import { Container, Button, Spinner } from 'design-react-kit';
import moment from 'moment';
import cx from 'classnames';

import { getQueryStringResults } from '@plone/volto/actions';
import { flattenToAppURL } from '@plone/volto/helpers';
import CardWithImageTemplate from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/CardWithImageTemplate';
import { Pagination } from 'design-comuni-plone-theme/components/ItaliaTheme';
import { resetQuerystringResults } from 'design-comuni-plone-theme/actions';
import FiltersConfig from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/EventSearch/FiltersConfig';

const messages = defineMessages({
  find: {
    id: 'find',
    defaultMessage: 'Cerca',
  },
  insert_filter: {
    id: 'insert_filter',
    defaultMessage:
      'Inserire un filtro dal menù laterale per visualizzare i relativi risultati',
  },
  venues: {
    id: 'venues',
    defaultMessage: 'Luoghi',
  },
  noResult: {
    id: 'noResult',
    defaultMessage: 'Nessun risultato trovato',
  },
});

const Body = ({ data, id, inEditMode, path, onChangeBlock }) => {
  const intl = useIntl();
  const b_size = 6;

  moment.locale(intl.locale);

  const [currentPage, setCurrentPage] = useState(1);
  const subsite = useSelector((state) => state.subsite?.data);

  const dispatch = useDispatch();

  const querystringResults = useSelector((state) => {
    return state.querystringsearch?.subrequests?.[id + '_events_search'];
  });
  const items = useSelector((state) => {
    return (
      state.querystringsearch?.subrequests?.[id + '_events_search']?.items ?? []
    );
  });

  const loading = useSelector((state) => {
    return (
      state.querystringsearch?.subrequests?.[id + '_events_search']?.loading ||
      false
    );
  });

  const firstLoading = useSelector((state) => {
    return (
      !state.querystringsearch?.subrequests?.[id + '_events_search']?.loading &&
      !state.querystringsearch?.subrequests?.[id + '_events_search']?.loaded
    );
  });

  const resultsRef = createRef();

  const doRequest = (page = currentPage) => {
    let query = [
      {
        i: 'portal_type',
        o: 'plone.app.querystring.operation.selection.any',
        v: ['Event'],
      },
      {
        i: 'rassegna',
        o: 'plone.app.querystring.operation.boolean.isFalse',
        v: '',
      },
    ];

    [filterOne, filterTwo, filterThree].forEach((f) => {
      if (f?.widget) {
        const value = f.widget.props.value;
        if (f.query) {
          f.query(value, query);
        }
      }
    });

    if (data.location && data.location[0]) {
      query.push({
        i: 'path',
        o: 'plone.app.querystring.operation.string.absolutePath',
        v: flattenToAppURL(data.location[0]['@id']),
      });
    }

    dispatch(
      getQueryStringResults(
        subsite ? flattenToAppURL(subsite['@id']) : '',
        {
          query: query,
          metadata_fields: '_all',
          b_size: b_size,
          sort_order: 'ascending',
          sort_on: 'start',
        },
        id + '_events_search',
        page,
      ),
    );
  };

  // Se cambia uno dei tre filtri resetto lo stato dei filtri
  useEffect(() => {
    dispatchFilter({ type: 'reset' });
    if (data.show_default_results && firstLoading) {
      doRequest();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  const filtersReducer = (state = getInitialState(), action) => {
    let newState = {
      ...state,
    };

    if (action.type === 'reset') {
      newState = {
        ...getInitialState(),
      };
      dispatch(resetQuerystringResults(id + '_events_search'));
    } else {
      const f = newState[action.filter];
      const defaultReducer = (value, state) => value;
      const reducer = f.reducer || defaultReducer;
      f.widget.props.value = reducer(action.value, state[action.filter]);
    }
    return newState;
  };

  const filtersConfig = FiltersConfig(null);
  const getInitialState = () => {
    return {
      filterOne: filtersConfig[data?.filter_one],
      filterTwo: filtersConfig[data?.filter_two],
      filterThree: filtersConfig[data?.filter_three],
    };
  };
  const [{ filterOne, filterTwo, filterThree }, dispatchFilter] = useReducer(
    filtersReducer,
    getInitialState(),
  );

  function handleQueryPaginationChange(e, { activePage }) {
    resultsRef.current.scrollIntoView({ behavior: 'smooth' });
    const current = activePage?.children ?? 1;
    setCurrentPage(current);
    doRequest(current);
  }

  return filterOne || filterTwo || filterThree ? (
    <Container>
      <div
        className={cx('rounded bg-' + (data.bg_color || 'primary'), {
          'public-ui': inEditMode,
        })}
      >
        <form
          onSubmit={(event) => {
            event.preventDefault();
            doRequest(1);
          }}
        >
          <div className="d-flex justify-content-center">
            <div className="d-flex search-container align-items-center justify-content-center flex-wrap">
              {filterOne && (
                <>
                  {React.createElement(filterOne.widget.component, {
                    ...filterOne.widget?.props,
                    blockID: id,
                    id: 'filterOne',
                    onChange: (filter, value) => {
                      dispatchFilter({
                        filter: filter,
                        value: value,
                      });
                    },
                  })}
                </>
              )}
              {filterTwo &&
                React.createElement(filterTwo.widget?.component, {
                  ...filterTwo.widget?.props,
                  blockID: id,
                  id: 'filterTwo',
                  onChange: (filter, value) =>
                    dispatchFilter({
                      filter: filter,
                      value: value,
                    }),
                })}
              {filterThree &&
                React.createElement(filterThree.widget?.component, {
                  ...filterThree.widget?.props,
                  blockID: id,
                  id: 'filterThree',
                  onChange: (filter, value) =>
                    dispatchFilter({
                      filter: filter,
                      value: value,
                    }),
                })}

              <Button
                color={data.button_color || 'tertiary'}
                icon={false}
                tag="button"
                className="my-2 my-lg-1"
                type="submit"
              >
                {intl.formatMessage(messages.find)}
              </Button>
            </div>
          </div>
        </form>
      </div>

      {!loading ? (
        items?.length > 0 ? (
          <div className="mt-4" ref={resultsRef} aria-live="polite">
            <div className="block listing">
              <CardWithImageTemplate
                items={items}
                full_width={false}
                always_show_image={data.always_show_image}
              />
            </div>
            {querystringResults.total > b_size && (
              <Pagination
                activePage={currentPage}
                totalPages={Math.ceil(querystringResults.total / b_size)}
                onPageChange={handleQueryPaginationChange}
              />
            )}
          </div>
        ) : querystringResults ? (
          <>
            <div className="mt-4" aria-live="polite">
              <p className="text-center">
                {intl.formatMessage(messages.noResult)}
              </p>
            </div>
          </>
        ) : null
      ) : (
        <div className="d-flex justify-content-center mt-3">
          <Spinner active />
        </div>
      )}
    </Container>
  ) : null;
};

export default Body;
