import {
  CreatePurchaseRequestPayload,
  Purchase,
  UpdatePurchaseRequestPayload,
  CreateStaffApprovalRequestPayload,
  UpdateStaffApprovalRequestPayload,
  CreateManagerApprovalRequestPayload,
  CreateAcceptApprovalRequestPayload,
  DeletePurchaseRequestItemPayload,
} from '@/types/api/purchase/purchase';
import { BaseApiService } from '@/services/api/base';
import { BaseApiResponse } from '@/types/api/api-general';
import { formatDate } from '@/lib/helper';
import { httpClient } from '../http/client';

const basePurchaseApi = new BaseApiService<
  Purchase,
  CreatePurchaseRequestPayload,
  UpdatePurchaseRequestPayload
>('/purchases');

export const PurchaseApi = {
  basePath: basePurchaseApi.basePath,
  header: basePurchaseApi.header,
  getAllFetcher: basePurchaseApi.getAllFetcher.bind(basePurchaseApi),
  getSingle: basePurchaseApi.getSingle.bind(basePurchaseApi),
  create: basePurchaseApi.create.bind(basePurchaseApi),
  update: basePurchaseApi.update.bind(basePurchaseApi),
  delete: basePurchaseApi.delete.bind(basePurchaseApi),
  customRequest: basePurchaseApi.customRequest.bind(basePurchaseApi),

  staffApproval: {
    create: async (
      purchaseRequestId: number,
      payload: CreateStaffApprovalRequestPayload
    ): Promise<BaseApiResponse<{ message: string }> | undefined> => {
      return await basePurchaseApi.customRequest<
        BaseApiResponse<{ message: string }>
      >(`${purchaseRequestId}/approvals/staff`, {
        method: 'POST',
        payload,
      });
    },

    update: async (
      purchaseRequestId: number,
      payload: UpdateStaffApprovalRequestPayload
    ): Promise<BaseApiResponse<{ message: string }> | undefined> => {
      return await basePurchaseApi.customRequest<
        BaseApiResponse<{ message: string }>
      >(`${purchaseRequestId}/approvals/staff`, {
        method: 'POST',
        payload,
      });
    },
  },

  managerApproval: {
    create: async (
      purchaseRequestId: number,
      payload: CreateManagerApprovalRequestPayload
    ): Promise<BaseApiResponse<{ message: string }> | undefined> => {
      return await basePurchaseApi.customRequest<
        BaseApiResponse<{ message: string }>
      >(`${purchaseRequestId}/approvals/manager`, {
        method: 'POST',
        payload,
      });
    },
  },

  acceptApproval: {
    create: async (
      purchaseRequestId: number,
      payload: CreateAcceptApprovalRequestPayload
    ): Promise<BaseApiResponse<{ message: string }> | undefined> => {
      const formData = new FormData();

      formData.append('action', payload.action);

      if (payload.notes) {
        formData.append('notes', payload.notes);
      }

      if (payload.items) {
        formData.append('items', JSON.stringify(payload.items));
      }

      if (payload.travel_documents) {
        payload.travel_documents.forEach((file) => {
          formData.append('travel_documents', file);
        });
      }

      return await basePurchaseApi.customRequest<
        BaseApiResponse<{ message: string }>
      >(`${purchaseRequestId}/receipts`, {
        method: 'POST',
        payload: formData as unknown as Record<string, unknown>,
      });
    },
  },

  items: {
    delete: async (
      purchaseRequestId: number,
      payload: DeletePurchaseRequestItemPayload
    ): Promise<BaseApiResponse<{ message: string }> | undefined> => {
      return await basePurchaseApi.customRequest<
        BaseApiResponse<{ message: string }>
      >(`${purchaseRequestId}/items`, {
        method: 'DELETE',
        payload,
      });
    },
  },

  updatePoDate: async (
    purchaseRequestId: number,
    payload: { po_date: string }
  ): Promise<BaseApiResponse<Purchase> | undefined> => {
    return await basePurchaseApi.customRequest<BaseApiResponse<Purchase>>(
      `${purchaseRequestId}/po-date`,
      {
        method: 'PATCH',
        payload,
      }
    );
  },

  async exportToExcel(initialQueryString: string) {
    const params = new URLSearchParams(initialQueryString);

    params.set('export', 'excel');
    params.set('type', 'all');
    params.set('page', '1');
    params.set('limit', '99999999999');

    const queryString = `?${params.toString()}`;

    const res = await httpClient<Blob>(`${this.basePath}${queryString}`, {
      method: 'GET',
      responseType: 'blob',
    });

    const url = window.URL.createObjectURL(new Blob([res]));
    const link = document.createElement('a');
    link.href = url;

    const fileName = `pembelian-${formatDate(Date.now(), 'DD-MM-YYYY')}.xlsx`;
    link.setAttribute('download', fileName);

    document.body.appendChild(link);
    link.click();
    link.remove();
  },

  async exportInputProgressToExcel(startDate: string, endDate: string) {
    const params = new URLSearchParams();

    params.set('export', 'excel');
    params.set('type', 'progress');
    params.set('start_date', formatDate(startDate, 'YYYY-MM-DD'));
    params.set('end_date', formatDate(endDate, 'YYYY-MM-DD'));

    const queryString = `?${params.toString()}`;

    const res = await httpClient<Blob>(
      `${basePurchaseApi.basePath}${queryString}`,
      {
        method: 'GET',
        responseType: 'blob',
      }
    );

    const url = window.URL.createObjectURL(new Blob([res]));
    const link = document.createElement('a');
    link.href = url;

    const fileName = `input-progres-pembelian-${formatDate(startDate, 'DD-MM-YYYY')}-ke-${formatDate(endDate, 'DD-MM-YYYY')}.xlsx`;
    link.setAttribute('download', fileName);

    document.body.appendChild(link);
    link.click();
    link.remove();
  },
};
