import React, { useRef, useEffect } from 'react';
import { Glyphicon, HelpBlock, Button } from 'react-bootstrap';
import { useHistory, useLocation } from 'react-router';
import { Link } from 'react-router-dom';
import { useQuery } from '../../helpers/hooks';
import ResponsiveTable from '../Table/ResponsiveTable';
import StatusFilterDropdown from './StatusFilterDropdown';
import styles from './ParcelTable.module.css';
import moment from 'moment';
import InvestigationDateFilter from '../Investigation/InvestigationDateFilter';

function getActionColumn(handleView) {
  return {
    text: '',
    dataField: 'actions',
    formatter: (_, parcel) => (
      <Link
        to={`/investigation/${parcel.investigationId}/parcel/${parcel._id}`}
        onClick={(evt) => {
          evt.preventDefault();
          handleView(parcel);
        }}
      >
        <Glyphicon glyph="eye-open" style={{ marginRight: 5 }} />
        <span className={styles.actionLabel}>View</span>
      </Link>
    ),
    responsiveHeaderStyle: {
      xs: { width: 40 },
      sm: { width: 40 },
      md: { width: 70 },
      lg: { width: 70 },
    },
  };
}

function ParcelTable(props) {
  const { parcels, columns, investigations } = props;

  const history = useHistory();
  const query = useQuery();
  const location = useLocation();
  const { state } = location;
  useEffect(() => {
    if (state && state.scrollPosition) {
      window.scrollTo(...state.scrollPosition);
    }
  });

  const latestQuery = useRef(); // work around stale query reference when changing search term
  latestQuery.current = query;

  const dateFilter = query.get('date')
    ? moment(query.get('date'), moment.HTML5_FMT.DATE)
    : undefined;
  const statusFilter = query.get('status');
  const searchFilter = query.get('q');
  const [sortField, sortOrder] = (query.get('sort') || '_id-desc').split('-');

  function handleStartDateChange(date) {
    const newQuery = new URLSearchParams(query);

    if (date) {
      newQuery.set('date', moment(date).format(moment.HTML5_FMT.DATE));
    } else {
      newQuery.delete('date');
    }

    history.replace(`${location.pathname}?${newQuery.toString()}`);
  }

  function handleStatusFilterChange(status) {
    const newQuery = new URLSearchParams(query);

    if (status) {
      newQuery.set('status', status);
    } else {
      newQuery.delete('status');
    }

    history.replace(`${location.pathname}?${newQuery.toString()}`);
  }

  function handleSearchFilterChange(search) {
    const newQuery = new URLSearchParams(query);

    if (search) {
      newQuery.set('q', search);
    } else {
      newQuery.delete('q');
    }

    history.replace(`${location.pathname}?${newQuery.toString()}`);
  }

  function handleView(parcel) {
    history.push(
      `/investigation/${parcel.investigationId}/parcel/${parcel._id}`,
      {
        back: {
          title: 'Back to list',
          pathname: location.pathname,
          search: latestQuery.current.toString(),
          scrollPosition: [window.scrollX, window.scrollY],
        },
      }
    );
  }

  function handleSort(field, order) {
    if (field !== sortField || order !== sortOrder) {
      const newQuery = new URLSearchParams(query);
      newQuery.set('sort', `${field}-${order}`);
      history.replace(`${location.pathname}?${newQuery.toString()}`);
    }
  }

  function handleStatusFilterClear() {
    const newQuery = new URLSearchParams(query);
    newQuery.delete('status');
    history.replace(`${location.pathname}?${newQuery.toString()}`);
  }

  function handleDateFilterClear() {
    const newQuery = new URLSearchParams(query);
    newQuery.delete('date');
    history.replace(`${location.pathname}?${newQuery.toString()}`);
  }

  function isParcelMatching(parcel) {
    const isStatusMatching = !statusFilter || parcel.status === statusFilter;

    const parcelInvestigation =
      investigations &&
      investigations.find(
        (investigation) => investigation.id === parcel.investigationId
      );
    const isDateMatching =
      !dateFilter ||
      !parcelInvestigation ||
      dateFilter.isSame(parcelInvestigation.startDate, 'day');

    return isStatusMatching && isDateMatching;
  }

  const columnsWithHandles = [
    ...columns,
    getActionColumn(handleView),
  ].map((col) => (col.sort ? { ...col, onSort: handleSort } : col));

  return (
    <>
      {parcels.length > 0 ? (
        <div className={styles.wrapper}>
          <div className={styles.filters}>
            <div className={styles.filter}>
              <StatusFilterDropdown
                value={statusFilter}
                onSelect={handleStatusFilterChange}
              />
              <Button
                disabled={!statusFilter}
                onClick={handleStatusFilterClear}
                bsStyle="link"
                className={styles.clearButton}
              >
                <Glyphicon glyph="remove" />
              </Button>
            </div>
            {investigations && (
              <InvestigationDateFilter
                rootClassName={styles.filter}
                value={dateFilter && dateFilter.toDate()}
                onDayChange={handleStartDateChange}
                onClear={handleDateFilterClear}
              />
            )}
          </div>
          <ResponsiveTable
            keyField="_id"
            defaultSorted={[{ dataField: sortField, order: sortOrder }]}
            data={parcels.filter(isParcelMatching)}
            columns={columnsWithHandles}
            search={{ defaultSearch: searchFilter, searchFormatted: true }}
            onSearch={handleSearchFilterChange}
            rowEvents={{ onClick: (_, parcel) => handleView(parcel) }}
            rowClasses={styles.clickable}
            pageOptions={{
              sizePerPageList: [
                { text: '25', value: 25 },
                { text: '50', value: 50 },
                { text: '100', value: 100 },
              ],
            }}
          />
        </div>
      ) : (
        <HelpBlock>No parcels to display.</HelpBlock>
      )}
    </>
  );
}

export default ParcelTable;
