import { BaseApiService } from '@/services/api/base';
import { httpClient } from '@/services/http/client';
import { BaseApiResponse } from '@/types/api/api-general';
import axios from 'axios';
import {
  BulkApproveMarketingPayload,
  Marketing,
  CreateSalesOrderPayload,
  UpdateSalesOrderPayload,
  CreateDeliveryOrderPayload,
  UpdateDeliveryOrderPayload,
} from '@/types/api/marketing/marketing';

import { formatDate } from '@/lib/helper';

/**
 * 💡 Helper untuk membuat respons dummy
 * @param data Data yang akan dimasukkan ke dalam body respons
 */

export class SalesOrderService extends BaseApiService<
  Marketing,
  CreateSalesOrderPayload,
  UpdateSalesOrderPayload
> {
  constructor(basePath: string = '/marketing') {
    super(basePath);
  }

  /**
   * Approve single marketing data
   */
  async singleApproval(
    id: number,
    action: 'APPROVED' | 'REJECTED',
    notes?: string
  ): Promise<BaseApiResponse<{ message: string }> | undefined> {
    try {
      const path = `${this.basePath}/approvals`;
      return await httpClient<BaseApiResponse<{ message: string }>>(path, {
        method: 'POST',
        body: {
          action: action,
          approvable_ids: [id],
          notes: notes || `${action} marketing ${id}`,
        },
      });
    } catch (error: unknown) {
      if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
        return error.response?.data;
      }
      return undefined;
    }
  }

  /**
   * Bulk approve
   */
  async bulkApprovals(
    ids: number[],
    action: 'APPROVED' | 'REJECTED',
    notes?: string
  ): Promise<BaseApiResponse<{ message: string }> | undefined> {
    try {
      const path = `${this.basePath}/approvals`;
      return await httpClient<BaseApiResponse<{ message: string }>>(path, {
        method: 'POST',
        body: {
          action: action,
          approvable_ids: ids,
          notes: notes || `${action} marketing ${ids.join(', ')}`,
        },
      });
    } catch (error: unknown) {
      if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
        return error.response?.data;
      }
      return undefined;
    }
  }

  async bulkApproveToStatus(
    payload: BulkApproveMarketingPayload
  ): Promise<BaseApiResponse<Marketing | Marketing[]> | undefined> {
    try {
      return await httpClient<BaseApiResponse<Marketing | Marketing[]>>(
        '/marketing/approvals/bulk',
        {
          method: 'POST',
          body: payload,
        }
      );
    } catch (error) {
      if (axios.isAxiosError<BaseApiResponse<Marketing | Marketing[]>>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  /**
   * Delivery
   */
  async delivery(
    id: number,
    notes?: string
  ): Promise<BaseApiResponse<{ message: string }> | undefined> {
    try {
      const path = `${this.basePath}/approvals`;
      return await httpClient<BaseApiResponse<{ message: string }>>(path, {
        method: 'POST',
        body: {
          action: 'APPROVED',
          approvable_ids: [id],
          notes: notes || `Delivery marketing ${id}`,
        },
      });
    } catch (error: unknown) {
      if (axios.isAxiosError<BaseApiResponse<{ message: string }>>(error)) {
        return error.response?.data;
      }
      return undefined;
    }
  }
}
class MarketingExportService extends BaseApiService<
  Marketing,
  unknown,
  unknown
> {
  constructor(basePath: string = '/marketing') {
    super(basePath);
  }

  async bulkApprovals(
    ids: number[],
    status: 'SALES_ORDER' | 'DELIVERY_ORDER',
    date: string, // YYYY-MM-DD
    notes: string
  ): Promise<BaseApiResponse<Marketing[] | Marketing> | undefined> {
    try {
      const path = `${this.basePath}/approvals/bulk`;

      return await httpClient<BaseApiResponse<Marketing[] | Marketing>>(path, {
        method: 'POST',
        body: {
          approvable_ids: ids,
          status: status,
          date: date,
          notes: notes,
        },
      });
    } catch (error: unknown) {
      if (axios.isAxiosError<BaseApiResponse<Marketing[] | Marketing>>(error)) {
        return error.response?.data;
      }
      return undefined;
    }
  }

  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 = `penjualan-${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>(`${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 = `input-progres-penjualan-${formatDate(startDate, 'DD-MM-YYYY')}-ke-${formatDate(endDate, 'DD-MM-YYYY')}.xlsx`;
    link.setAttribute('download', fileName);

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

export const SalesOrderApi = new SalesOrderService('/marketing/sales-orders');
export const DeliveryOrderApi = new BaseApiService<
  Marketing,
  CreateDeliveryOrderPayload,
  UpdateDeliveryOrderPayload
>('/marketing/delivery-orders');
export const MarketingApi = new MarketingExportService('/marketing');
