import { Button, MenuItem } from "@blueprintjs/core";
import { Select } from "@blueprintjs/select";
import React from "react";
import { DateTime } from "luxon";

const itemPredicate = (query, option) =>
  option.value.toLowerCase().indexOf(query.toLowerCase()) >= 0;

function itemRenderer(option, { handleClick, modifiers: { matchesPredicate, active } = {} }) {
  if (!matchesPredicate) {
    return null;
  }

  return <MenuItem key={option.id} active={active} onClick={handleClick} text={option.value} />;
}

function FilterButton({ label }) {
  return (
    <Button minimal icon="caret-down">
      {label}
    </Button>
  );
}

export function Filter({ descriptions, value, setter, label, defaultId }) {
  const items = Object.entries(descriptions).map(([id, { value }]) => ({ id, value }));

  return (
    <Select
      filterable={false}
      items={items}
      itemRenderer={itemRenderer}
      onItemSelect={(option) => setter(option.id)}
      itemPredicate={itemPredicate}
    >
      <FilterButton
        label={defaultId === value ? label : `${label}: ${descriptions[value].value}`}
      />
    </Select>
  );
}

const DATE_FILTERS = {
  ANYTIME: "anytime",
  TODAY: "today",
  YESTERDAY: "yesterday",
  LAST_7_DAYS: "last_7_days",
  LAST_30_DAYS: "last_30_days",
  LAST_90_DAYS: "last_90_days",
};

function computeDate(days) {
  return () => DateTime.local().minus({ days }).toISODate();
}

const DATE_FILTERS_DESCRIPTION = {
  [DATE_FILTERS.ANYTIME]: {
    value: "Anytime",
  },
  [DATE_FILTERS.TODAY]: {
    value: "Today",
    date: computeDate(1),
  },
  [DATE_FILTERS.YESTERDAY]: {
    value: "Yesterday",
    date: computeDate(2),
  },
  [DATE_FILTERS.LAST_7_DAYS]: {
    value: "Last 7 days",
    date: computeDate(7),
  },
  [DATE_FILTERS.LAST_30_DAYS]: {
    value: "Last 30 days",
    date: computeDate(30),
  },
  [DATE_FILTERS.LAST_90_DAYS]: {
    value: "Last 90 days",
    date: computeDate(90),
  },
};

export function DateFilter({ value, setter, label = "Date", defaultId = DATE_FILTERS.ANYTIME }) {
  const items = Object.entries(DATE_FILTERS_DESCRIPTION).map(([id, { value }]) => ({ id, value }));

  return (
    <Select
      filterable={false}
      items={items}
      itemRenderer={itemRenderer}
      onItemSelect={(option) => setter(option.id)}
      itemPredicate={itemPredicate}
    >
      <FilterButton
        label={defaultId === value ? label : `${label}: ${DATE_FILTERS_DESCRIPTION[value].value}`}
      />
    </Select>
  );
}

const OWNERSHIP_FILTERS = {
  ANYONE: "anyone",
  ME: "me",
  OTHERS: "others",
};

const OWNERSHIP_FILTERS_DESCRIPTION = {
  [OWNERSHIP_FILTERS.ANYONE]: { value: "Anyone" },
  [OWNERSHIP_FILTERS.ME]: { value: "me" },
  [OWNERSHIP_FILTERS.OTHERS]: { value: "Others" },
};

export function OwnerFilter({
  value,
  setter,
  label = "Owner",
  defaultId = OWNERSHIP_FILTERS.ANYONE,
}) {
  const items = Object.entries(OWNERSHIP_FILTERS_DESCRIPTION).map(([id, { value }]) => ({
    id,
    value,
  }));

  return (
    <Select
      filterable={false}
      items={items}
      itemRenderer={itemRenderer}
      onItemSelect={(option) => setter(option.id)}
      itemPredicate={itemPredicate}
    >
      <FilterButton
        label={
          defaultId === value ? label : `${label}: ${OWNERSHIP_FILTERS_DESCRIPTION[value].value}`
        }
      />
    </Select>
  );
}

export { DATE_FILTERS, DATE_FILTERS_DESCRIPTION, OWNERSHIP_FILTERS, OWNERSHIP_FILTERS_DESCRIPTION };