import type { ConfirmedFactCard, OptimizedArticle, QaReport } from "../domain/types";
import type {
  ArticleJob,
  BrandTemplate,
  NewArticleJob,
  NewBrandTemplate,
} from "./repositories";
import { getAppCloudflareEnv, type AppCloudflareEnv } from "../runtime/cloudflare";
import { createD1Repository } from "./d1-repository";
import { createSqliteRepository } from "./sqlite-repository";

export interface AppRepository {
  createBrandTemplate(input: NewBrandTemplate): Promise<BrandTemplate>;
  listBrandTemplates(): Promise<BrandTemplate[]>;
  getBrandTemplate(id: string): Promise<BrandTemplate | null>;
  createArticleJob(input: NewArticleJob): Promise<ArticleJob>;
  getArticleJob(id: string): Promise<ArticleJob | null>;
  updateArticleJob(
    id: string,
    changes: Partial<Pick<ArticleJob, "brand_template_id" | "status" | "export_paths">>,
  ): Promise<ArticleJob | null>;
  saveFactCard(
    jobId: string,
    factCard: ConfirmedFactCard,
  ): Promise<{ job_id: string } & ConfirmedFactCard>;
  getFactCard(jobId: string): Promise<({ job_id: string } & ConfirmedFactCard) | null>;
  saveOptimizedArticle(jobId: string, article: OptimizedArticle): Promise<OptimizedArticle>;
  getLatestOptimizedArticle(jobId: string): Promise<OptimizedArticle | null>;
  saveQaReport(jobId: string, revision: number, report: QaReport): Promise<QaReport>;
  getLatestQaReport(jobId: string): Promise<QaReport | null>;
}

interface RuntimeRepositoryOptions {
  appRuntime?: string;
  dbPath?: string;
  cloudflareEnv?: AppCloudflareEnv;
}

export function getRepositoryFromRuntime(
  options: RuntimeRepositoryOptions = {},
): AppRepository {
  const appRuntime = options.appRuntime ?? process.env.APP_RUNTIME;
  if (appRuntime === "cloudflare") {
    const env = options.cloudflareEnv ?? getAppCloudflareEnv();
    if (!env?.DB) {
      throw new Error("Cloudflare D1 binding DB is required");
    }
    return createD1Repository(env.DB);
  }

  return createSqliteRepository(options.dbPath);
}
