// Data-import APPLICATION — the Direct Upload use-case. Framework-agnostic: it depends only on the
// domain + the DirectUploadGateway port (no React, no axios). The presentation hook injects the
// gateway + the machine's `dispatch`, and this orchestrates: validate (pure) -> upload -> fold the
// result back into the machine via events.
//
// Converged-upload note: the existing content-addressed endpoint stores AND processes in one call,
// so on success UPLOAD_OK and PROCESS_OK are dispatched together (the §3 Uploading/Processing split
// is preserved in the machine for fidelity, but collapses against this backend).

import { importError, validateDirectStaging, type DirectContext, type DirectEvent } from '../domain';
import type { DirectUploadGateway } from './ports';

export interface RunDirectUploadDeps {
  gateway: DirectUploadGateway;
  datasetId: string;
  /** The machine context at START_UPLOAD (dataType, groupByStudy, files). */
  context: DirectContext;
  /** The actual browser Files to stream (kept alongside the domain StagedFiles). */
  files: File[];
  dispatch: (event: DirectEvent) => void;
}

export async function runDirectUpload(deps: RunDirectUploadDeps): Promise<void> {
  const { gateway, datasetId, context, files, dispatch } = deps;

  // Pure validation (D3/D4/D6). On failure, return to Staging with located errors.
  const errors = validateDirectStaging(context);
  if (errors.length > 0) {
    dispatch({ type: 'VALIDATE_FAIL', errors });
    return;
  }
  dispatch({ type: 'VALIDATE_OK' });

  try {
    const result = await gateway.upload({
      datasetId,
      files,
      onProgress: (pct) => dispatch({ type: 'UPLOAD_PROGRESS', progress: pct }),
    });
    dispatch({ type: 'UPLOAD_OK' });
    dispatch({ type: 'PROCESS_OK', taskIds: result.paths });
  } catch (err) {
    const message = err instanceof Error ? err.message : 'Tải lên thất bại.';
    dispatch({ type: 'UPLOAD_FAIL', errors: [importError('GATEWAY_ERROR', message)] });
  }
}
