/**
 * Thin PostgREST client using fetch — no Supabase SDK dependency.
 * Used by both the Worker (history queries) and the Durable Object (message persistence).
 */
export class PostgREST {
  private baseUrl: string;
  private serviceRoleKey: string;

  constructor(supabaseUrl: string, serviceRoleKey: string) {
    this.baseUrl = `${supabaseUrl}/rest/v1`;
    this.serviceRoleKey = serviceRoleKey;
  }

  private headers(): Record<string, string> {
    return {
      "apikey": this.serviceRoleKey,
      "Authorization": `Bearer ${this.serviceRoleKey}`,
      "Content-Type": "application/json",
      "Prefer": "return=representation",
    };
  }

  /** Insert a row and return the inserted data. */
  async insert<T>(table: string, data: Record<string, unknown>): Promise<T[]> {
    const res = await fetch(`${this.baseUrl}/${table}`, {
      method: "POST",
      headers: this.headers(),
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const body = await res.text();
      throw new Error(`PostgREST insert failed (${res.status}): ${body}`);
    }
    return res.json() as Promise<T[]>;
  }

  /** Upsert a row (requires Prefer: resolution=merge-duplicates). */
  async upsert<T>(table: string, data: Record<string, unknown>, onConflict: string): Promise<T[]> {
    const headers = this.headers();
    headers["Prefer"] = "return=representation,resolution=merge-duplicates";
    const res = await fetch(`${this.baseUrl}/${table}?on_conflict=${onConflict}`, {
      method: "POST",
      headers,
      body: JSON.stringify(data),
    });
    if (!res.ok) {
      const body = await res.text();
      throw new Error(`PostgREST upsert failed (${res.status}): ${body}`);
    }
    return res.json() as Promise<T[]>;
  }

  /** Select rows with PostgREST query string. */
  async select<T>(table: string, query: string): Promise<T[]> {
    const res = await fetch(`${this.baseUrl}/${table}?${query}`, {
      method: "GET",
      headers: this.headers(),
    });
    if (!res.ok) {
      const body = await res.text();
      throw new Error(`PostgREST select failed (${res.status}): ${body}`);
    }
    return res.json() as Promise<T[]>;
  }

  /** Select with exact count header for unread queries. */
  async count(table: string, query: string): Promise<number> {
    const headers = this.headers();
    headers["Prefer"] = "count=exact";
    headers["Range-Unit"] = "items";
    headers["Range"] = "0-0";
    const res = await fetch(`${this.baseUrl}/${table}?${query}`, {
      method: "HEAD",
      headers,
    });
    const contentRange = res.headers.get("Content-Range");
    if (!contentRange) return 0;
    // Content-Range format: "0-0/42" or "*/0"
    const total = contentRange.split("/")[1];
    return total === "*" ? 0 : parseInt(total, 10);
  }
}
