import * as React from "react";
import { maybeReplaceIds } from "./useDynamicFilter";
type SortDirection = "ASC" | "DESC";

type QueryOrder = {
  id: string;
  field: string[];
  direction: SortDirection;
};

export function useDynamicSort(
  initialValue: QueryOrder[] = [],
  onChange?: (state?: QueryOrder[]) => void,
) {
  const [sorts, _setSort] = React.useState(initialValue ?? []);
  const setSort = React.useCallback(
    ((valueOrCallback) => {
      if (typeof valueOrCallback === "function") {
        _setSort((prev) => {
          const value = valueOrCallback(prev);
          onChange?.(value);
          return value;
        });
        return;
      }

      _setSort(valueOrCallback);
      onChange?.(valueOrCallback);
    }) as typeof _setSort,
    [_setSort],
  );

  const clear = React.useCallback(() => setSort([]), []);

  const add = React.useCallback((sort: QueryOrder | QueryOrder[]) => {
    if (!sort) return;
    setSort((sorts) => {
      const list = Array.isArray(sort) ? sort : [sort];
      return [...sorts, ...(list.map(maybeReplaceIds) as QueryOrder[])];
    });
  }, []);

  const remove = React.useCallback((old: QueryOrder) => {
    if (!old) return;
    setSort((sorts) => {
      return sorts.filter((sort) => sort.id !== old.id);
    });
  }, []);

  const setColumn = React.useCallback((old: QueryOrder, field: any) => {
    if (!old) return;
    setSort((sorts) => {
      const index = sorts.findIndex((s) => s.id === old.id);
      if (index === -1) return sorts;
      const value = sorts[index];
      const newSorts = [...sorts];
      newSorts.splice(index, 1, {
        ...value,
        field,
      });
      return newSorts;
    });
  }, []);

  const setAsc = React.useCallback((old: QueryOrder) => {
    if (!old) return;
    setSort((sorts) => {
      const index = sorts.findIndex((s) => s.id === old.id);
      if (index === -1) return sorts;
      const value = sorts[index];
      const newSorts = [...sorts];
      newSorts.splice(index, 1, {
        ...value,
        direction: "ASC",
      });
      return newSorts;
    });
  }, []);

  const setDesc = React.useCallback((old: QueryOrder) => {
    if (!old) return;
    setSort((sorts) => {
      const index = sorts.findIndex((s) => s.id === old.id);
      if (index === -1) return sorts;
      const value = sorts[index];
      const newSorts = [...sorts];
      newSorts.splice(index, 1, {
        ...value,
        direction: "DESC",
      });
      return newSorts;
    });
  }, []);

  const toggleDirection = React.useCallback((old: QueryOrder) => {
    if (!old) return;
    setSort((sorts) => {
      const index = sorts.findIndex((s) => s.id === old.id);
      if (index === -1) return sorts;
      const value = sorts[index];
      const newSorts = [...sorts];
      newSorts.splice(index, 1, {
        ...value,
        direction: value.direction === "DESC" ? "ASC" : "DESC",
      });
      return newSorts;
    });
  }, []);

  const methods = React.useMemo(
    () => ({
      clear,
      add,
      remove,
      setColumn,
      setAsc,
      setDesc,
      toggleDirection,
    }),
    [clear, add, remove, setColumn, setAsc, setDesc, toggleDirection],
  );

  return [sorts, methods] as const;
}
