import type {
  GeneratorOutput,
  PromptVariation,
} from "@/lib/schemas/universal-prompt.schema";
import type { Platform } from "@/types";

export interface AdapterValidationResult {
  success: boolean;
  errors?: string[];
}

/** Type-safe helper: extract variations array from a parsed AI JSON response */
export function extractVariations(parsed: unknown): PromptVariation[] | null {
  if (
    parsed !== null &&
    typeof parsed === "object" &&
    "variations" in parsed &&
    Array.isArray((parsed as { variations: unknown }).variations)
  ) {
    return (parsed as { variations: PromptVariation[] }).variations;
  }
  return null;
}

export abstract class BasePromptAdapter<TInput> {
  abstract platform: Platform;

  abstract validateInput(input: unknown): AdapterValidationResult;
  abstract constructSystemPrompt(input: TInput, variationCount: number): string;
  // Fix #2: variationIndex dihapus — satu AI call menghasilkan semua variasi sekaligus.
  // Jumlah variasi sudah ada di input.variations dan di-pass ke constructSystemPrompt.
  abstract constructUserPrompt(input: TInput): string;
  abstract transformOutput(rawOutput: string, input: TInput): PromptVariation;
  abstract generateTextPrompt(input: TInput): string;
  abstract generateJsonOutput(input: TInput): Record<string, unknown>;

  protected parseJsonSafe(text: string): Record<string, unknown> | null {
    try {
      // Extract JSON from code block if present
      const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
      const jsonStr = jsonMatch ? jsonMatch[1] : text;
      return JSON.parse(jsonStr.trim()) as Record<string, unknown>;
    } catch {
      return null;
    }
  }

  protected buildNegativePrompt(input: TInput & { negativePrompt?: string }): string {
    const defaults = this.getDefaultNegativePrompts();
    const custom = input.negativePrompt ?? "";
    return [custom, ...defaults].filter(Boolean).join(", ");
  }

  protected getDefaultNegativePrompts(): string[] {
    return [
      "low quality",
      "blurry",
      "pixelated",
      "distorted",
      "deformed",
      "watermark",
      "text overlay",
    ];
  }

  protected formatOutput(variations: PromptVariation[], model: string, language: string): GeneratorOutput {
    return {
      platform: this.platform,
      variations,
      metadata: {
        generatedAt: new Date().toISOString(),
        model,
        inputLanguage: language,
      },
    };
  }
}
