import { useCallback, useEffect, useState } from 'react';
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';

import { useModal } from 'components/layers';

import { Header } from 'components/Header';
import { Button, Text } from 'components/common';
import { HorizontalScroll } from 'components/helpers/HorizontalScroll';
import { ConfirmLabelsModal } from 'components/import/modals';
import { DataTable, DataLabel } from 'components/import/DataTable';
import { HelperText } from 'components/import/HelperText';

import { PATHS as HOMEPAGE } from 'pages/root/HomePage';
import { PATHS as WORKSPACE } from '../index';

const CONTENT = [
  `The FanSifter label guesser will try to guess the content of the column automagically. Those guessed ´system labels´ appear in the boxes above. If you disagree, you can overrule the choice and pick a better matching label from the dropdown menu.`,
  `In case the guesser did not find a match and you do not select any label for that column manually, the data in the column will not be used in the data processing for analytics and segmenting. We will still save the column to your FanSifter database, so you can access and use that data later (like when exporting data).`,
  `For your convenience and speeding up manual labeling, you do not have to choose labels for those columns which are not relevant. Only label the ones useful for FanSifter model. See the guidelines.`,
];

function findDuplicates(data: string[]) {
  const result: string[] = [];

  data.forEach((element, index) => {
    // Find if there is a duplicate or not
    if (data.indexOf(element, index + 1) > -1) {
      // Find if the element is already in the result array or not
      if (result.indexOf(element) === -1) {
        result.push(element);
      }
    }
  });

  return result;
}

const IGNORE = [null, undefined, '', 'skip'];

function useFindDuplicates(data: string[], ignore = IGNORE) {
  const [state, setState] = useState<string>();

  useEffect(() => {
    const values = data.filter((item) => ignore.indexOf(item) === -1);
    const [duplicate] = findDuplicates(values);
    setState(duplicate);
  }, [data, ignore]);

  return [state, setState] as const;
}

interface MapDataProps {
  fileName: string;
  fileKeys: string[];
  fileData: string[][];
  dataLabels: DataLabel[];
  initialState: string[];
}

export const MapData = ({
  fileName,
  fileKeys,
  fileData,
  dataLabels,
  initialState,
}: MapDataProps) => {
  const { workspaceId, collectionId } = useParams();
  const navigate = useNavigate();
  const location = useLocation();

  const [values, setValues] = useState(initialState);
  const [duplicate] = useFindDuplicates(values);
  const [confirmed, setConfirmed] = useState(false);

  const handleSelect = useCallback((ev) => {
    const { name, value } = ev.target;
    setValues((state) => {
      const newState = [...state];
      newState[name] = value;
      return newState;
    });
  }, []);

  const confirmLabelsModal = useModal(ConfirmLabelsModal, {
    defaultProps: {
      collectionId: collectionId!,
      fileName: fileName,
      placeholder: 'Dataset name',
      values: values,
      onComplete: () => navigate(`/${HOMEPAGE.workspace}/${workspaceId}`),
    },
  });

  const confirm: React.MouseEventHandler<HTMLButtonElement> = (ev) => {
    if (!confirmed && values.indexOf('') !== -1) {
      setConfirmed(true);
    } else {
      confirmLabelsModal.show();
    }
  };

  function renderBackButton() {
    const workspacePath = `/${HOMEPAGE.workspace}/${workspaceId}`;
    const path =
      location.pathname.indexOf(WORKSPACE.import) !== -1
        ? `${workspacePath}/${WORKSPACE.import}`
        : workspacePath;

    return (
      <Link className="header-link cup" to={path}>
        Back
      </Link>
    );
  }

  return (
    <div className="flex flexColumn">
      <Header
        left={renderBackButton()}
        title="Label your dataset"
        right={
          <Button onClick={confirm} disabled={Boolean(duplicate)}>
            {confirmed ? 'Confirm anyway' : 'Confirm'}
          </Button>
        }
      />

      <Text className="padding4" align="center">
        {duplicate
          ? "You can't select the same option twice"
          : !confirmed
          ? 'Please tell us what type of data is in each column of the file'
          : "Make sure you don't forget anything important"}
      </Text>

      <HorizontalScroll>
        <DataTable
          values={values}
          labels={dataLabels}
          fileKeys={fileKeys}
          fileData={fileData}
          handleTypeChange={handleSelect}
          duplicate={duplicate}
          confirmed={confirmed}
        />
      </HorizontalScroll>
      <div className="flex justifyAround padding4 spacing4">
        {CONTENT.map((text, i) => (
          <HelperText key={i}>{text}</HelperText>
        ))}
      </div>
    </div>
  );
};
