import type { GenerationErrorCategory } from "./generation-error-registry.js";

export interface GenerationAdapterRequest {
  configSnapshot: Readonly<Record<string, unknown>>;
  generationId: string;
  modelId: string;
  prompt: string;
  ratio: "3:4" | "1:1" | "4:3" | "9:16";
  referenceAssetIds: readonly string[];
  referenceImages?: readonly {
    assetId: string;
    bytes: Buffer;
    mimeType: "image/jpeg" | "image/png" | "image/webp";
  }[];
}

export interface NormalizedGenerationOutput {
  bytes: Buffer;
  mimeType: "image/jpeg" | "image/png" | "image/webp";
  pixelHeight: number;
  pixelWidth: number;
}

export type GenerationAdapterResult =
  | { outputs: readonly NormalizedGenerationOutput[]; status: "completed" }
  | { status: "pending"; upstreamJobReference: string }
  | {
      balanceSignal?: { gatewayAccountRef: string; impactScope: "model" | "account" | "unknown" };
      category: GenerationErrorCategory;
      sourceCategory: string;
      status: "failed";
    };

export interface GenerationAdapter {
  dispose?(): void;
  start(request: GenerationAdapterRequest): Promise<GenerationAdapterResult>;
  poll?(upstreamJobReference: string): Promise<GenerationAdapterResult>;
}

type MockResult = GenerationAdapterResult & { unsafeRaw?: string };

export class MockGenerationAdapter implements GenerationAdapter {
  readonly calls: Array<{ generationId: string; modelId: string }> = [];
  private readonly result: MockResult;

  constructor(result: MockResult) {
    this.result = result;
  }

  async start(request: GenerationAdapterRequest): Promise<GenerationAdapterResult> {
    this.calls.push({ generationId: request.generationId, modelId: request.modelId });
    if (this.result.status === "pending") return { status: "pending", upstreamJobReference: this.result.upstreamJobReference };
    if (this.result.status === "completed") {
      return { outputs: this.result.outputs.map((output) => ({ ...output, bytes: Buffer.from(output.bytes) })), status: "completed" };
    }
    return {
      ...(this.result.balanceSignal ? { balanceSignal: { ...this.result.balanceSignal } } : {}),
      category: this.result.category,
      sourceCategory: this.result.sourceCategory,
      status: "failed",
    };
  }
}
