// Recipe success/failure records (SDD section 7.1). Stored as an entry per recipe canonical_id.
// This is the "fuel" for submission-with-proof: real 2xx counts beat self-written tests.
import type { Bindings } from '../types';

interface RecipeStat {
  canonical_id: string;
  success_count: number;
  failure_count: number;
  last_status: string | null;
  last_at: number | null;
}

// One entry per recipe: id = recipestat:{canonical_id}, entry_type='recipe_stat',
// counters live in metadata_json. Atomic upsert via D1.
function statId(canonicalId: string): string {
  return `recipestat:${canonicalId}`;
}

export async function recordRecipeResult(db: D1Database, canonicalId: string, ok: boolean, nowMs: number): Promise<RecipeStat> {
  const id = statId(canonicalId);
  const existing = await db.prepare('SELECT metadata_json FROM entries WHERE id = ?').bind(id).first<{ metadata_json: string | null }>();

  let stat: RecipeStat;
  if (existing) {
    const prev = existing.metadata_json ? (JSON.parse(existing.metadata_json) as RecipeStat) : emptyStat(canonicalId);
    stat = {
      canonical_id: canonicalId,
      success_count: prev.success_count + (ok ? 1 : 0),
      failure_count: prev.failure_count + (ok ? 0 : 1),
      last_status: ok ? 'success' : 'failure',
      last_at: nowMs,
    };
    await db
      .prepare('UPDATE entries SET metadata_json = ?, updated_at = unixepoch() WHERE id = ?')
      .bind(JSON.stringify(stat), id)
      .run();
  } else {
    stat = {
      canonical_id: canonicalId,
      success_count: ok ? 1 : 0,
      failure_count: ok ? 0 : 1,
      last_status: ok ? 'success' : 'failure',
      last_at: nowMs,
    };
    await db
      .prepare('INSERT INTO entries (id, content, entry_type, metadata_json) VALUES (?, ?, ?, ?)')
      .bind(id, canonicalId, 'recipe_stat', JSON.stringify(stat))
      .run();
  }
  return stat;
}

export async function getRecipeStat(db: D1Database, canonicalId: string): Promise<RecipeStat> {
  const row = await db.prepare('SELECT metadata_json FROM entries WHERE id = ?').bind(statId(canonicalId)).first<{ metadata_json: string | null }>();
  if (!row || !row.metadata_json) return emptyStat(canonicalId);
  return JSON.parse(row.metadata_json) as RecipeStat;
}

function emptyStat(canonicalId: string): RecipeStat {
  return { canonical_id: canonicalId, success_count: 0, failure_count: 0, last_status: null, last_at: null };
}

export type { RecipeStat };
