import { UseListQueryResult, useCustom, useList, useOne, useSave } from "@/lib/hooks/useDataSource";
import {
  IFilterItemDataProviderParam,
  IGetListDataProviderParams,
} from "@/lib/hooks/useDataSource/DataSource";
import { TDataSourceError } from "@/lib/hooks/useDataSource/types";
import { useDataSource } from "@/lib/hooks/useDataSource/useDataSource";
import { useQueryKey } from "@/lib/hooks/useQueryKey";
import {
  ICreateQuote_Request_DTO,
  ICreateQuote_Response_DTO,
  IGetQuote_Response_DTO,
  IListQuotes_Response_DTO,
  IListResponse_DTO,
  IReportQuote_Response_DTO,
  IUpdateQuote_Request_DTO,
  IUpdateQuote_Response_DTO,
  UniqueID,
} from "@shared/contexts";
import { useCallback } from "react";

export type UseQuotesListParams = Omit<IGetListDataProviderParams, "filters" | "resource"> & {
  status?: string;
  enabled?: boolean;
  queryOptions?: Record<string, unknown>;
};

export type UseQuotesListResponse = UseListQueryResult<
  IListResponse_DTO<IListQuotes_Response_DTO>,
  unknown
>;

export type UseQuotesGetParamsType = {
  enabled?: boolean;
  queryOptions?: Record<string, unknown>;
};

export type UseQuotesReportParamsType = {
  enabled?: boolean;
  queryOptions?: Record<string, unknown>;
};

const quoteStatusFilter: Record<string, IFilterItemDataProviderParam> = {
  draft: {
    field: "status",
    operator: "eq",
    value: "draft",
  },
  archived: {
    field: "status",
    operator: "eq",
    value: "archived",
  },
  active: {
    field: "status",
    operator: "eq",
    value: "active",
  },
};

export const useQuotes = () => {
  const dataSource = useDataSource();
  const keys = useQueryKey();

  return {
    useList: (params: UseQuotesListParams): UseQuotesListResponse => {
      const dataSource = useDataSource();
      const keys = useQueryKey();

      const {
        pagination,
        status = "draft",
        quickSearchTerm = undefined,
        enabled = true,
        queryOptions,
      } = params;

      return useList({
        queryKey: keys().data().resource("quotes").action("list").params(params).get(),
        queryFn: () => {
          return dataSource.getList({
            resource: "quotes",
            quickSearchTerm,
            filters: status !== "all" ? Array.of(quoteStatusFilter[status]) : undefined,
            pagination,
          });
        },
        enabled,
        queryOptions,
      });
    },

    useCreate: () =>
      useSave<ICreateQuote_Response_DTO, TDataSourceError, ICreateQuote_Request_DTO>({
        //mutationKey: keys().data().resource("quotes").action("one").id("").params().get(),
        mutationFn: (data) => {
          const { date } = data;

          const id = UniqueID.generateNewID().object.toString();
          const status = "draft";

          return dataSource.createOne({
            resource: "quotes",
            data: {
              ...data,
              date: new Date(date).toISOString().slice(0, 10),
              status,
              id,
            },
          });
        },
      }),

    useUpdate: (id: string) =>
      useSave<IUpdateQuote_Response_DTO, TDataSourceError, IUpdateQuote_Request_DTO>({
        mutationKey: keys().data().resource("quotes").action("one").id(id).params().get(),
        mutationFn: (data) => {
          const { date } = data;

          return dataSource.updateOne({
            resource: "quotes",
            id,
            data: {
              ...data,
              date: new Date(date).toISOString().slice(0, 10),
            },
          });
        },
      }),

    useOne: (id?: string, params?: UseQuotesGetParamsType) =>
      useOne<IGetQuote_Response_DTO>({
        queryKey: keys().data().resource("quotes").action("one").id(id).params().get(),
        queryFn: () =>
          dataSource.getOne({
            resource: "quotes",
            id: String(id),
          }),
        enabled: !!id,
        ...params,
      }),

    useReport: (id?: string, params?: UseQuotesReportParamsType) =>
      useCustom<ArrayBuffer, TDataSourceError, IReportQuote_Response_DTO>({
        queryKey: keys().data().resource("quotes").action("report").id(id).params().get(),
        queryFn: () =>
          dataSource.custom({
            url: `${dataSource.getApiUrl()}/quotes/${id}/report`,
            method: "get",
            responseType: "arraybuffer",
          }),
        enabled: !!id,
        select: useCallback((data: ArrayBuffer) => new Uint8Array(data), []),
        ...params,
      }),
  };
};
