/**
 * Upload base64-encoded file content to Convex storage (no documents row).
 *
 * This is the model-layer helper; Convex actions should call this via a thin
 * wrapper in `convex/documents.ts`.
 */

import { fetchJson } from '../../lib/utils/type-cast-helpers';
import { internal } from '../_generated/api';
import type { Id } from '../_generated/dataModel';
import type { ActionCtx } from '../_generated/server';
import { base64ToBytes } from '../lib/crypto/base64_to_bytes';
import { createDebugLog } from '../lib/debug_log';
import { buildDownloadUrl } from './generate_document_helpers';

const debugLog = createDebugLog('DEBUG_DOCUMENTS', '[Documents]');

export interface UploadBase64Args {
  organizationId: string;
  fileName: string;
  contentType: string;
  dataBase64: string;
}

export interface UploadBase64Result {
  success: boolean;
  fileStorageId: Id<'_storage'>;
  downloadUrl: string;
  fileName: string;
  size: number;
  contentType: string;
}

export async function uploadBase64ToStorage(
  ctx: ActionCtx,
  args: UploadBase64Args,
): Promise<UploadBase64Result> {
  const { organizationId, fileName, contentType, dataBase64 } = args;

  debugLog('documents.uploadBase64ToStorage start', {
    fileName,
    contentType,
    dataLength: dataBase64.length,
  });

  const bytes = base64ToBytes(dataBase64);
  const size = bytes.byteLength;

  const uploadUrl = await ctx.storage.generateUploadUrl();
  const uploadResponse = await fetch(uploadUrl, {
    method: 'POST',
    headers: { 'Content-Type': contentType },
    body: new Blob([new Uint8Array(bytes)], { type: contentType }),
  });

  if (!uploadResponse.ok) {
    const text = await uploadResponse.text().catch(() => '');
    console.error('[documents.uploadBase64ToStorage] upload failed', {
      status: uploadResponse.status,
      statusText: uploadResponse.statusText,
      body: text,
    });
    throw new Error(
      `Failed to upload file to Convex storage: ${uploadResponse.status} ${uploadResponse.statusText}`,
    );
  }

  const { storageId } = await fetchJson<{ storageId: Id<'_storage'> }>(
    uploadResponse,
  );

  await ctx.runMutation(
    internal.file_metadata.internal_mutations.saveFileMetadata,
    { organizationId, storageId, fileName, contentType, size, source: 'agent' },
  );

  // Build download URL using our custom HTTP endpoint that sets Content-Disposition
  // This ensures the downloaded file has the correct filename instead of the storage ID
  const downloadUrl = buildDownloadUrl(storageId, fileName);

  debugLog('documents.uploadBase64ToStorage success', {
    fileName,
    storageId,
    size,
  });

  return {
    success: true,
    fileStorageId: storageId,
    downloadUrl,
    fileName,
    size,
    contentType,
  };
}
