import React from "react";
import { useSelector } from "react-redux";
import {
  DataList,
  Stack,
  StackItem,
  ToolbarItem,
} from "@patternfly/react-core";

import { selectors } from "app/store";
import {
  EmptyStateNoItem,
  ToolbarFilterAction,
  ToolbarFilterGroups,
} from "app/view/share";

import {
  ConstraintRowLocationNode,
  ConstraintRowLocationRule,
} from "./location";
import {
  ConstraintRowColocationPair,
  ConstraintRowColocationSet,
} from "./colocation";
import { ConstraintRowOrderPair, ConstraintRowOrderSet } from "./order";
import { ConstraintRowTicketResource, ConstraintRowTicketSet } from "./ticket";

type ConstraintPackList = selectors.ExtractClusterSelector<
  typeof selectors.getConstraints
>;

const filterGroups = {
  Location: false,
  "Location (rule)": false,
  Colocation: false,
  "Colocation (set)": false,
  Order: false,
  "Order (set)": false,
  Ticket: false,
  "Ticket (set)": false,
};
const useState = () => {
  const groupState = ToolbarFilterGroups.useState(filterGroups);
  const [groupInclusionMap] = groupState;

  const filterConstraintTypes = React.useCallback(
    (constraintPacks: ConstraintPackList): ConstraintPackList =>
      constraintPacks.filter(cp =>
        ToolbarFilterGroups.allOrIncludedGroupMembers({
          groupInclusionMap,
          groupMembershipMap: { ...filterGroups, [cp.type]: true },
        }),
      ),
    [groupInclusionMap],
  );
  return {
    filterState: {
      groupState,
    },
    filterConstraintTypes,
  };
};

export const ConstraintFilteredList: React.FC<{ clusterName: string }> = ({
  clusterName,
}) => {
  const constraintPacks = useSelector(selectors.getConstraints(clusterName));
  const { filterState, filterConstraintTypes } = useState();
  const clearAllFilters = () => {
    const [groupInclusionMap, setGroupInclusionMap] = filterState.groupState;
    setGroupInclusionMap(
      ToolbarFilterGroups.unselectAllOptions(groupInclusionMap),
    );
  };
  if (constraintPacks.length === 0) {
    return (
      <EmptyStateNoItem
        title="No constraint is configured."
        message="You don't have any configured constraint here."
      />
    );
  }
  return (
    <Stack hasGutter>
      <StackItem>
        <ToolbarFilterAction clearAllFilters={clearAllFilters}>
          <ToolbarItem>
            <ToolbarFilterGroups
              name="Constraint type"
              filterState={filterState.groupState}
            />
          </ToolbarItem>
        </ToolbarFilterAction>
      </StackItem>
      <StackItem>
        <DataList aria-label="Constraints">
          {filterConstraintTypes(constraintPacks).map((pack, i) => {
            switch (pack.type) {
              case "Location":
                return (
                  <ConstraintRowLocationNode
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Location (rule)": {
                return (
                  <ConstraintRowLocationRule
                    constraint={pack.constraint}
                    key={i}
                    uniqeId={i}
                  />
                );
              }

              case "Colocation":
                return (
                  <ConstraintRowColocationPair
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Colocation (set)":
                return (
                  <ConstraintRowColocationSet
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Ticket":
                return (
                  <ConstraintRowTicketResource
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Ticket (set)":
                return (
                  <ConstraintRowTicketSet
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Order":
                return (
                  <ConstraintRowOrderPair
                    constraint={pack.constraint}
                    key={i}
                  />
                );

              case "Order (set)":
              default:
                return (
                  <ConstraintRowOrderSet constraint={pack.constraint} key={i} />
                );
            }
          })}
        </DataList>
      </StackItem>
    </Stack>
  );
};
