// OPFS 기반 WebAssembly SQLite (sql.js) 초기화 및 동기화
// 가벼운 전체 파일 교체 방식. 향후 Supabase 연동 시 증분 동기화로 확장 가능.

const DB = (() => {
  let SQL, db, ready;
  const OPFS_FILE = 'faults.db';
  const STORE_KEY = 'db-version';

  async function ensureSqlJs() {
    if (SQL) return SQL;
    // sql.js CDN
    const module = await window.initSqlJs({ locateFile: f => `https://sql.js.org/dist/${f}` });
    SQL = module;
    return SQL;
  }

  async function readFromOpfs() {
    if (!('storage' in navigator) || !('getDirectory' in navigator.storage)) return null;
    try {
      const root = await navigator.storage.getDirectory();
      const handle = await root.getFileHandle(OPFS_FILE, { create: false }).catch(() => null);
      if (!handle) return null;
      const file = await handle.getFile();
      return new Uint8Array(await file.arrayBuffer());
    } catch { return null; }
  }

  async function writeToOpfs(bytes) {
    if (!('storage' in navigator) || !('getDirectory' in navigator.storage)) return;
    const root = await navigator.storage.getDirectory();
    const handle = await root.getFileHandle(OPFS_FILE, { create: true });
    const w = await handle.createWritable();
    await w.write(bytes);
    await w.close();
  }

  async function init() {
    if (ready) return ready;
    ready = (async () => {
      await ensureSqlJs();
      // 1) OPFS에서 기존 DB 로드
      const bytes = await readFromOpfs();
      if (bytes) {
        db = new SQL.Database(bytes);
      } else {
        // 없으면 서버에서 부트스트랩 DB 다운로드
        const buf = await fetch('/api/db').then(r => r.arrayBuffer());
        db = new SQL.Database(new Uint8Array(buf));
        await persist();
      }
      return true;
    })();
    return ready;
  }

  async function persist() {
    const data = db.export();
    await writeToOpfs(data);
  }

  async function syncIfNeeded() {
    // 서버 버전 확인 후 다르면 교체
    try {
      const remoteMeta = await fetch('/api/meta').then(r => r.json());
      const localMeta = getLocalMeta();
      if (!localMeta || Number(remoteMeta.version) > Number(localMeta.version)) {
        const buf = await fetch('/api/db').then(r => r.arrayBuffer());
        db = new SQL.Database(new Uint8Array(buf));
        await persist();
        setLocalMeta(remoteMeta);
        return true;
      }
    } catch {}
    return false;
  }

  function getLocalMeta() {
    try { return JSON.parse(localStorage.getItem(STORE_KEY)); } catch { return null; }
  }
  function setLocalMeta(meta) {
    localStorage.setItem(STORE_KEY, JSON.stringify(meta));
  }

  function query(sql, params = []) {
    const stmt = db.prepare(sql);
    stmt.bind(params);
    const rows = [];
    while (stmt.step()) rows.push(stmt.getAsObject());
    stmt.free();
    return rows;
  }

  return { init, syncIfNeeded, query, persist };
})();

window.DB = DB;


