import { Arg, Mutation, Query, Resolver } from "@aet/gql-tools/macro"
import UAParser from "ua-parser-js"
import { ClientMetadata, InputExportedV1 } from "~/shared/models/index"
import { getDocs, localDb } from "../../couchdb"
import { PreferencesCache } from "./PreferencesResolver"

/**
 * Handles exporting, importing and synchronizing the database and
 * preferences.
 */
@Resolver()
export class DatabaseResolver {
  @Query()
  async export(): Promise<Record<string, any>> {
    const { clientName, ...preferences } = PreferencesCache.cache.get()
    const files: InputExportedV1 = {
      schema: 1,
      files: await getDocs(),
      source: clientName || getDefaultClientName(),
      preferences,
    }
    return files
  }

  @Mutation()
  async restore(@Arg() backup: InputExportedV1): Promise<boolean> {
    const { schema, files, preferences } = backup
    switch (schema) {
      case 1:
        await Promise.all(
          files.map(file =>
            localDb.put({
              _id: file.id,
              ...file,
              createdAt: new Date(file.createdAt).valueOf(),
              updatedAt: new Date(file.updatedAt).valueOf(),
              state: file.state ?? "None",
            }),
          ),
        )
        PreferencesCache.cache.set(preferences)
        return true

      default:
        throw new Error("Unknown backup schema")
    }
  }

  @Query()
  clientMetadata(): ClientMetadata {
    const parser = new UAParser(navigator.userAgent)
    return {
      browser: parser.getBrowser().name || "Unknown",
      os: parser.getOS().name || "Unknown",
    }
  }
}

function getDefaultClientName() {
  const parser = new UAParser(navigator.userAgent)
  const browser = parser.getBrowser().name || "Unknown"
  const os = parser.getOS().name || "Unknown"
  return `${os} ${browser}`
}
