import { openDB, type DBSchema, type IDBPDatabase } from "idb";

export interface QueuedAction {
  id: string;                  // clientActionId (uuid v4)
  actionName: string;          // e.g. "markOrderReady"
  payload: unknown;            // JSON-serializable args
  createdAt: number;           // Date.now()
  attempts: number;            // sync attempts
  lastAttemptAt: number | null;
  status: "pending" | "in-flight" | "synced" | "conflict" | "failed";
  error?: string;
}

interface RouteCommerceOfflineDB extends DBSchema {
  queue: {
    key: string;
    value: QueuedAction;
    indexes: { "by-status": string; "by-created": number };
  };
  cache: {
    key: string;               // e.g. "orders:brandId:abc"
    value: { key: string; data: unknown; cachedAt: number };
  };
}

const DB_NAME = "route-commerce-offline";
const DB_VERSION = 1;

let dbPromise: Promise<IDBPDatabase<RouteCommerceOfflineDB>> | null = null;

export function getOfflineDB(): Promise<IDBPDatabase<RouteCommerceOfflineDB>> {
  if (typeof window === "undefined") {
    throw new Error("getOfflineDB called on the server");
  }
  if (!dbPromise) {
    dbPromise = openDB<RouteCommerceOfflineDB>(DB_NAME, DB_VERSION, {
      upgrade(db) {
        if (!db.objectStoreNames.contains("queue")) {
          const queue = db.createObjectStore("queue", { keyPath: "id" });
          queue.createIndex("by-status", "status");
          queue.createIndex("by-created", "createdAt");
        }
        if (!db.objectStoreNames.contains("cache")) {
          db.createObjectStore("cache", { keyPath: "key" });
        }
      },
    });
  }
  return dbPromise;
}
