import PouchDB from "pouchdb-browser"
import { LAST_SYNC, PASSWORD_KEY, USERNAME_KEY } from "~/shared/constants"
import type { File } from "~/shared/models"

export const localDb = new PouchDB<File>("styles")
export let remoteDb: PouchDB.Database<File> | undefined
let sync: PouchDB.Replication.Sync<File>

export function login(username: string, password: string) {
  logout()

  remoteDb = new PouchDB<File>(process.env.NEXT_PUBLIC_SERVER_URL, {
    auth: { username, password },
  })
  sync = localDb.sync(remoteDb, {
    live: true,
    retry: true,
  })

  void sync.on

  void sync.on("change", () => {
    localStorage.setItem(LAST_SYNC, new Date().toISOString())
  })

  return remoteDb
}

export function logout() {
  if (remoteDb) {
    sync!.cancel()
    remoteDb = undefined
  }
}

const username = localStorage.getItem(USERNAME_KEY)
const password = localStorage.getItem(PASSWORD_KEY)

if (username && password) {
  void login(username, password)
}

export async function getDocs() {
  const docs = await localDb.allDocs({ include_docs: true })
  return docs.rows.map(row => row.doc!)
}

export async function deleteDoc(id: string) {
  const doc = await localDb.get(id)
  await localDb.remove(doc)
}

export async function exists(id: string) {
  try {
    await localDb.get(id)
    return true
  } catch (e) {
    if ((e as Error).name === "not_found") {
      return false
    } else {
      throw e
    }
  }
}

Object.assign(globalThis, { localDb, remoteDb })
