import { isResponseError } from '@/lib/api-helper';
import { BaseApiService } from '@/services/api/base';
import { httpClient, httpClientFetcher } from '@/services/http/client';
import { BaseApiResponse } from '@/types/api/api-general';
import {
  Marketing,
  CreateSalesOrderPayload,
  UpdateSalesOrderPayload,
  CreateDeliveryOrderPayload,
  UpdateDeliveryOrderPayload,
} from '@/types/api/marketing/marketing';
import toast from 'react-hot-toast';
import * as XLSX from 'xlsx';
import { formatCurrency, formatDate, formatTitleCase } from '@/lib/helper';

/**
 * 💡 Helper untuk membuat respons dummy
 * @param data Data yang akan dimasukkan ke dalam body respons
 */
const createDummyResponse = <T>(data: T): BaseApiResponse<T> => ({
  code: 200,
  status: 'success',
  message: 'Data retrieved successfully (MOCK)',
  data: data,
});

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) {
      throw error;
    }
  }

  /**
   * 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) {
      throw error;
    }
  }

  /**
   * 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) {
      throw error;
    }
  }
}
class MarketingExportService extends BaseApiService<
  Marketing,
  unknown,
  unknown
> {
  constructor(basePath: string = '/marketing') {
    super(basePath);
  }

  /**
   * Export to Excel
   */
  async exportToExcel(initialQueryString: string) {
    const params = new URLSearchParams(initialQueryString);
    const queryString = `?${params.toString()}`;

    try {
      const marketingData = await httpClientFetcher<
        BaseApiResponse<Marketing[]>
      >(`${this.basePath}${queryString}`);

      if (isResponseError(marketingData)) {
        toast.error('Gagal melakukan export marketing! Coba lagi.');
        return;
      }

      const rows = marketingData.data;

      const formattedRows = [];

      for (let i = 0; i < rows.length; i++) {
        const row = rows[i];
        const approval = row.latest_approval;
        const isRejected = approval?.action === 'REJECTED';

        // Calculate grand total from sales_order products
        const grandTotal =
          row.sales_order
            ?.map((product) => product.total_price)
            .reduce((a, b) => a + b, 0) ?? 0;

        // Get product names
        const products =
          row.sales_order
            ?.map((product) => product.product_warehouse?.product?.name)
            .filter(Boolean)
            .join(', ') ?? '';

        formattedRows.push({
          'No. Order': row.so_number,
          Tanggal: formatDate(row.so_date, 'DD-MM-YYYY'),
          Status: isRejected
            ? 'Ditolak'
            : formatTitleCase(approval?.step_name || ''),
          Customer: row.customer?.name || '',
          'Grand Total': formatCurrency(grandTotal),
          Products: products,
          Notes: row.notes || '',
        });
      }

      const ws = XLSX.utils.json_to_sheet(formattedRows);
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'marketing');

      // triggers download in browser
      XLSX.writeFile(wb, 'marketing.xlsx');
    } catch (error) {
      toast.error('Gagal melakukan export marketing! Coba lagi.');
    }
  }
}

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');
