import { baseApi } from "@/store/api/baseApi";
import { Todo } from "@/store/models/Todo.model";
import { TodoStatus } from "@/constants/todoStatusEnum";
import { PriorityStatus } from "@/constants/priorityStatusEnum";
import { TableSortDirection } from "@/constants/tableSortDirectionEnum";

interface CreateTodoPayload {
  title: string;
  task: string;
  status: TodoStatus;
  priority: PriorityStatus;
  dueDate: Date;
  createdById: string;
  assigneeIds: string[];
}

export interface TodosQueryParams {
  page?: number;
  limit?: number;
  search?: string;
  statuses?: TodoStatus[];
  priorities?: PriorityStatus[];
  sortBy?: "title" | "dueDate" | "status" | "priority" | "createdAt";
  sortDir?: TableSortDirection;
  assigneeUserId?: string;
  teamOfManagerId?: string;
}

export interface PaginatedTodos {
  items: Todo[];
  total: number;
  page: number;
  limit: number;
}

const normalizeSortDir = (dir?: TableSortDirection) => {
  return dir
    ? dir === TableSortDirection.DESCENDING
      ? "desc"
      : "asc"
    : undefined;
};

const buildTodoParams = (params?: TodosQueryParams) => {
  if (!params) return {};

  const {
    page,
    limit,
    search,
    statuses,
    priorities,
    sortBy,
    sortDir,
    assigneeUserId,
    teamOfManagerId,
  } = params;

  return {
    ...(page !== undefined && { page }),
    ...(limit !== undefined && { limit }),
    ...(search && { search }),
    ...(Array.isArray(statuses) &&
      statuses.length && {
        statuses: statuses.join(","),
      }),
    ...(Array.isArray(priorities) &&
      priorities.length && {
        priorities: priorities.join(","),
      }),
    ...(sortBy && { sortBy }),
    ...(sortDir && { sortDir: normalizeSortDir(sortDir) }),
    ...(assigneeUserId && { assigneeUserId }),
    ...(teamOfManagerId && { teamOfManagerId }),
  };
};

export const todosApi = baseApi.injectEndpoints({
  overrideExisting: false,
  endpoints: (builder) => ({
    getTodosByUser: builder.query<Todo[], string>({
      query: (userId) => ({ url: `/todos/user/${userId}` }),
      providesTags: (result) => [
        "Todos",
        ...(result ?? []).map(({ id }) => ({ type: "Todos", id } as const)),
      ],
    }),

    getTodos: builder.query<PaginatedTodos, TodosQueryParams | undefined>({
      query: (params) => ({ url: "/todos", params: buildTodoParams(params) }),
      providesTags: (result, _error, _arg) => [
        "Todos",
        ...(result?.items ?? []).map(
          ({ id }) => ({ type: "Todos", id } as const)
        ),
      ],
    }),

    createTodo: builder.mutation<Todo, CreateTodoPayload>({
      query: (data) => ({
        url: "/todos",
        method: "POST",
        body: data,
      }),
      invalidatesTags: ["Todos"],
    }),

    updateTodo: builder.mutation<Todo, Partial<Todo>>({
      query: (todo) => ({
        url: `/todos/${todo.id}`,
        method: "PUT",
        body: todo,
      }),
      invalidatesTags: ["Todos"],
    }),

    deleteTodo: builder.mutation<void, string>({
      query: (id) => ({
        url: `/todos/${id}`,
        method: "DELETE",
      }),
      invalidatesTags: ["Todos"],
    }),
  }),
});

export const {
  useGetTodosByUserQuery,
  useGetTodosQuery,
  useCreateTodoMutation,
  useUpdateTodoMutation,
  useDeleteTodoMutation,
} = todosApi;
