import { cacheDirectory, EncodingType, writeAsStringAsync } from 'expo-file-system/legacy';
import * as Sharing from 'expo-sharing';
import api from '../core/api';

type ExportPayload = {
  columns: string[];
  format: 'csv' | 'xls';
  search?: string;
  type?: string;
  staff_id?: string | number;
  low_stock?: number | boolean;
};

function arrayBufferToBase64(buffer: ArrayBuffer): string {
  const bytes = new Uint8Array(buffer);
  let binary = '';
  const chunkSize = 0x8000;
  for (let index = 0; index < bytes.length; index += chunkSize) {
    binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
  }
  if (typeof globalThis.btoa === 'function') {
    return globalThis.btoa(binary);
  }
  throw new Error('Unable to encode export file on this device.');
}

export async function downloadResourceExport(resource: string, payload: ExportPayload) {
  const response = await api.post(`/${resource}/export`, payload, {
    responseType: 'arraybuffer',
  });

  const extension = payload.format === 'csv' ? 'csv' : 'xlsx';
  const mimeType = payload.format === 'csv'
    ? 'text/csv'
    : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  const filename = `${resource}-export-${new Date().toISOString().slice(0, 10)}.${extension}`;
  const uri = `${cacheDirectory || ''}${filename}`;
  const base64 = arrayBufferToBase64(response.data as ArrayBuffer);

  await writeAsStringAsync(uri, base64, {
    encoding: EncodingType.Base64,
  });

  if (await Sharing.isAvailableAsync()) {
    await Sharing.shareAsync(uri, { mimeType, dialogTitle: filename });
    return;
  }

  throw new Error('Sharing is not available on this device.');
}

export const defaultServiceExportColumns = [
  'type',
  'name',
  'sku',
  'assigned_staff',
  'status',
  'price',
  'cost_price',
  'quantity_on_hand',
  'reorder_level',
  'low_stock',
  'duration_minutes',
];
