import { useDownloader } from "@/lib/hooks";
import { useList, UseListQueryResult, useOne, useSave } from "@/lib/hooks/useDataSource";
import { 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,
  ISendQuote_Request_DTO,
  ISetStatusQuote_Request_DTO,
  IUpdateQuote_Request_DTO,
  IUpdateQuote_Response_DTO,
  UniqueID,
} from "@shared/contexts";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useCallback, useState } from "react";
import slugify from "slugify";

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>;
};

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

  const getQuotePDFDownloadURL = useCallback(
    (id: string) => `${dataSource.getApiUrl()}/quotes/${id}/report`,
    [dataSource]
  );

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const getQuotePDFFilename = useCallback(
    (quote: IListQuotes_Response_DTO | IGetQuote_Response_DTO) =>
      `quote-${slugify(quote.reference, {
        lower: true, // Convierte a minúsculas
        strict: true, // Elimina caracteres que no son letras o números
        locale: "en", // Establece la localización para la conversión
        trim: true, // Elimina espacios en blanco al principio y al final
      })}.pdf`,
    []
  );

  const actions = {
    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"
                ? [
                    {
                      field: "status",
                      operator: "eq",
                      value: status,
                    },
                  ]
                : undefined,
            pagination,
          });
        },
        enabled,
        queryOptions,
      });
    },

    useCreate: () => {
      const queryClient = useQueryClient();
      return 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,
            },
          });
        },
        onSuccess: () => {
          queryClient.invalidateQueries({
            queryKey: ["data", "default", "quotes"],
          });
        },
      });
    },

    useUpdate: (id: string) => {
      const queryClient = useQueryClient();

      return useMutation<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),
            },
          });
        },
        onSuccess: () => {
          queryClient.invalidateQueries({
            queryKey: ["data", "default", "quotes"],
          });
        },
      });
    },

    useSetStatus: (id?: string) => {
      const queryClient = useQueryClient();

      return useMutation<void, TDataSourceError, ISetStatusQuote_Request_DTO>({
        mutationKey: keys().data().resource("quotes").action("one").id(id).params().get(),
        mutationFn: (data) => {
          const { newStatus } = data;

          return dataSource.custom({
            url: `${dataSource.getApiUrl()}/quotes/${id}/setStatus`,
            method: "put",
            data: {
              newStatus,
            },
          });
        },
        onSuccess: () => {
          queryClient.invalidateQueries({
            queryKey: ["data", "default", "quotes"],
          });
        },
      });
    },

    useSentTo: (id?: string) => {
      const queryClient = useQueryClient();

      return useMutation<void, TDataSourceError, ISendQuote_Request_DTO>({
        mutationKey: keys().data().resource("quotes").action("one").id(id).params().get(),
        mutationFn: (data) => {
          const { sent_date } = data;

          return dataSource.custom({
            url: `${dataSource.getApiUrl()}/quotes/${id}/send`,
            method: "put",
            data: {
              sent_date,
            },
          });
        },
        onSuccess: () => {
          queryClient.invalidateQueries({
            queryKey: ["data", "default", "quotes"],
          });
        },
      });
    },

    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,
      }),

    /*useReport2: (id?: string, params?: UseQuotesReportParamsType) => {
      const queryClient = useQueryClient();
      const queryKey = useMemo(
        () => keys().data().resource("quotes").action("report").id(id).params().get(),
        [id]
      );

      return {
        ...useCustom<ArrayBuffer, TDataSourceError, IReportQuote_Response_DTO>({
          queryKey,
          queryFn: ({ signal }) =>
            dataSource.custom({
              url: `${dataSource.getApiUrl()}/quotes/${id}/report`,
              method: "get",
              responseType: "arraybuffer",
              signal,
            }),

          enabled: !!id,
          select: useCallback(
            (data: ArrayBuffer) => ({
              original: data,
              data: new Uint8Array(data),
            }),
            []
          ),
          ...params,
        }),
        cancelQuery: () => queryClient.cancelQueries({ queryKey }),
      };
    },*/

    getQuotePDFDownloadURL,

    getQuotePDFFilename,

    /*useDownload2: (id?: string, params?: UseQuotesReportParamsType) => {
      const queryKey = useMemo(
        () => keys().data().resource("quotes").action("report").id(id).params().get(),
        [id]
      );

      const { data, error, refetch, isFetching, isError } = useCustom<
        IDownloadPDFDataProviderResponse,
        TDataSourceError
      >({
        queryKey,
        queryFn: () =>
          dataSource.downloadPDF({
            url: `${dataSource.getApiUrl()}/quotes/${id}/report`,
          }),

        enabled: false,
        refetchInterval: false,
        ...params,
      });

      const download = () => {
        console.log("pido");
        refetch().then((result) => {
          console.log("termino");
          if (result.isSuccess) {
            const blob = data!.filedata;
            const link = document.createElement("a");
            const url = window.URL.createObjectURL(blob);
            link.href = url;
            link.setAttribute("download", data!.filename); // Nombre del archivo
            document.body.appendChild(link);
            link.click();
            link.remove();
            window.URL.revokeObjectURL(url);
          }
        });
      };

      return { download, error, isFetching, isError };
    },*/

    useReport: () => {
      const auth = dataSource.getApiAuthorization();
      const [report, setReport] = useState<Blob | undefined>(undefined);

      const { download, ...rest } = useDownloader({
        headers: {
          Authorization: auth,
        },
        customHandleDownload: useCallback(
          (data: Blob) => {
            const blobData = [data];
            const blob = new Blob(blobData, {
              type: "application/octet-stream",
            });
            setReport(blob);
            return true;
          },
          [setReport]
        ),
      });

      const preview = useCallback(
        (id: string) => {
          return download(actions.getQuotePDFDownloadURL(id), "");
        },
        [download]
      );

      return {
        ...rest,
        preview,
        report,
      };
    },

    useDownloader: () => {
      const auth = dataSource.getApiAuthorization();
      const downloader = useDownloader({
        headers: {
          Authorization: auth,
        },
      });

      const download = (id: string, filename: string) => {
        const url = actions.getQuotePDFDownloadURL(id);
        return downloader.download(url, filename);
      };

      return {
        ...downloader,
        download,
      };
    },
  };
  return actions;
};
