import { useState, useCallback } from 'react';
import { useMutation, useQuery, gql } from '@apollo/client';

import {
  WorkspacesCollectionsQuery,
  WorkspacesCollectionsQueryVariables,
} from 'types/graphql';
import { call } from 'utils/call';

import { Box, Button, Heading, Spinner } from 'components/common';
import { Select } from 'components/inputs';

export const ADD_PROFILES = gql`
  mutation ADD_PROFILES($allianceId: ID!, $input: [ID!]!) {
    collection: mergeProfilesIntoAlliance(
      allianceId: $allianceId
      input: $input
    ) {
      id
    }
  }
`;

export const WORKSPACES_COLLECTIONS = gql`
  query WORKSPACES_COLLECTIONS($workspaceId: ID) {
    workspaces: allWorkspaces {
      id
      name
    }
    collections: getCollections(workspaceId: $workspaceId) {
      id
      parentId
      name
      type
      status
      totalProfiles
      dateCreated
    }
  }
`;

export function useCheckbox(initialState: string[] = []) {
  const [selected, setSelected] = useState(initialState);

  const handleSelect = useCallback(
    (item: string) => {
      if (item) {
        const set = new Set(selected);
        if (set.has(item)) {
          set.delete(item);
        } else {
          set.add(item);
        }
        setSelected(Array.from(set));
      }
    },
    [selected]
  );

  const clearSelection = useCallback(() => {
    setSelected([]);
  }, []);

  return [selected, handleSelect, clearSelection] as const;
}

interface CollectionsListProps {
  data: {
    id: string;
    name: string;
    totalProfiles: number;
    type: string;
    status: string;
  }[];
  select: (item: string) => void;
  selected: string[];
}

const CollectionsList = ({
  data = [],
  select,
  selected,
}: CollectionsListProps) => {
  return (
    <>
      {data
        .filter((c) => c.type === 'source')
        .filter((c) => c.status === 'finished')
        .map((collection) => {
          return (
            <label
              className="flex alignCenter paddingX4 paddingY2 spacing2 hover1 cup fz14"
              key={collection.id}
            >
              <input
                type="checkbox"
                checked={selected.indexOf(collection.id) !== -1}
                onChange={() => select(collection.id)}
              />
              <div className="flexGrow flex alignCenter justifyBetween">
                <span>{collection.name}</span>
                <span>{collection.totalProfiles}</span>
              </div>
            </label>
          );
        })}
    </>
  );
};

interface AddCollectionsModalProps {
  allianceId: string;
  onDismiss?: () => void;
}

export const AddCollectionsModal = ({
  allianceId,
  onDismiss,
}: AddCollectionsModalProps) => {
  const [workspace, setWorkspace] = useState<string>('');
  const { data, ...query } = useQuery<
    WorkspacesCollectionsQuery,
    WorkspacesCollectionsQueryVariables
  >(WORKSPACES_COLLECTIONS, {
    variables: {
      workspaceId: workspace || null,
    },
  });
  const [submit, mutation] = useMutation(ADD_PROFILES);
  const [selected, select, clearSelection] = useCheckbox();

  const changeWorkspace: React.ChangeEventHandler<HTMLSelectElement> = (ev) => {
    if (ev.target.value !== workspace) {
      clearSelection();
    }

    if (ev.target.value) {
      setWorkspace(ev.target.value);
    } else {
      setWorkspace('');
    }
  };

  const handleSubmit = async () => {
    try {
      await submit({
        variables: {
          allianceId: allianceId,
          input: selected,
        },
      });
      call(onDismiss);
    } catch (error) {
      console.log(error);
    }
  };

  const loading = query.loading || mutation.loading;

  return (
    <Box className="bg-white rounded4 shadow" width={400}>
      <Heading
        align="center"
        className="padding4"
        style={{ borderBottom: '1px solid var(--borderColor)' }}
      >
        Add data
      </Heading>
      <Box padding={4}>
        <Select
          placeholder="Select workspace"
          options={data?.workspaces.map((w) => ({
            label: w.name,
            value: w.id,
          }))}
          value={workspace}
          onChange={changeWorkspace}
        />
      </Box>
      <Box
        className="customScroll"
        style={{ minHeight: 38, maxHeight: 38 * 5 + 38 / 2 }}
        position="relative"
        overflow="auto"
      >
        {workspace &&
          !loading &&
          (data?.collections?.length ? (
            <CollectionsList
              data={data.collections}
              select={select}
              selected={selected}
            />
          ) : (
            <div className="paddingX4 paddingY2 c-gray tac fz14">Empty</div>
          ))}

        <Spinner show={loading} />
      </Box>
      <Box padding={4} spacingY={2}>
        <Button onClick={handleSubmit} block disabled={loading}>
          Add
        </Button>
        <Button onClick={onDismiss} color="gray" block>
          Cancel
        </Button>
      </Box>
    </Box>
  );
};
