// Extracted from src/db/repository.ts (mechanical split — bodies unchanged).
// app-shares repository domain. Facade: src/db/repository.ts (Repository class).
import Database from 'better-sqlite3';
import { randomUUID } from 'crypto';

  // ─── 公開アプリ共有リンク（read-only） ───────────────────────────────
  //
  // スペース内の 1 ワークスペースアプリ（apps/{appName}/）を、ログイン不要の
  // 公開 URL で read-only 共有するためのトークン。失効後の再発行は新トークンを
  // 作る（失効済みトークンは再利用しない）ため、未失効リンクが既にある場合のみ
  // 再利用する。

  /** (spaceId, appName) の未失効リンクがあれば再利用、無ければ新規発行して token を返す。 */
  export function createAppShareLink(db: Database.Database, spaceId: string, appName: string, createdBy: string | null): { token: string } {
    const existing = db
      .prepare(
        `SELECT token FROM app_share_links
         WHERE space_id = ? AND app_name = ? AND revoked_at IS NULL
         ORDER BY created_at DESC LIMIT 1`,
      )
      .get(spaceId, appName) as { token: string } | undefined;
    if (existing) return { token: existing.token };
    const token = randomUUID();
    db
      .prepare(
        `INSERT INTO app_share_links (token, space_id, app_name, created_by)
         VALUES (?, ?, ?, ?)`,
      )
      .run(token, spaceId, appName, createdBy ?? null);
    return { token };
  }


  /** (spaceId, appName) の最新リンク（有効・無効問わず）を返す。無ければ null。 */
  export function getAppShareLink(db: Database.Database, spaceId: string, appName: string): { token: string; revokedAt: string | null } | null {
    const row = db
      .prepare(
        `SELECT token, revoked_at FROM app_share_links
         WHERE space_id = ? AND app_name = ?
         ORDER BY created_at DESC LIMIT 1`,
      )
      .get(spaceId, appName) as { token: string; revoked_at: string | null } | undefined;
    if (!row) return null;
    return { token: row.token, revokedAt: row.revoked_at ?? null };
  }


  /** (spaceId, appName) の未失効リンクを全て失効させる。行が無ければ no-op。 */
  export function revokeAppShareLink(db: Database.Database, spaceId: string, appName: string): void {
    db
      .prepare(
        `UPDATE app_share_links SET revoked_at = datetime('now')
         WHERE space_id = ? AND app_name = ? AND revoked_at IS NULL`,
      )
      .run(spaceId, appName);
  }


  /** トークンを (spaceId, appName) に解決する。失効済み・不正トークンは null。 */
  export function resolveAppShareToken(db: Database.Database, token: string): { spaceId: string; appName: string } | null {
    const row = db
      .prepare(
        `SELECT space_id, app_name FROM app_share_links
         WHERE token = ? AND revoked_at IS NULL`,
      )
      .get(token) as { space_id: string; app_name: string } | undefined;
    if (!row) return null;
    return { spaceId: row.space_id, appName: row.app_name };
  }
