import type { Flashcard, Note, Profile, DocumentBase } from '@eweser/shared';
import type { Collections, Documents, YDoc } from '../types.js';
import { buildRef } from '../utils/index.js';
import { Room } from '../room.js';
import { Database } from '../index.js';

const db = new Database();

/**
 * some metadata that exists on each document
 */
const metadata: DocumentBase = {
  /**
   * The reference to the room and document. This is used to make relational links between documents.
   * format: <collection_key>.<room_id>.<document_id>
   * room_id includes the auth server url
   */
  _ref: 'profiles.https://www.eweser.com|123abc.123abc',
  _id: '123abc',
  _created: 1653135317729,
  _updated: 1653135317729,
  _deleted: false,
};

const profileYDoc: { documents: Documents<Profile> } = {
  documents: {
    ['default']: {
      firstName: 'Eweser',
      ...metadata,
    },
  },
};
const profilePrivateYDoc: { documents: Documents<Profile> } = {
  documents: {
    ['default']: {
      lastName: 'DB',
      ...metadata,
    },
  },
};

const myStudyNotesYDoc: { documents: Documents<Note> } = {
  documents: {
    ['0']: {
      text: 'A fact about Typescript',
      ...metadata,
      _ref: 'notes.https://www.eweser.com|0.0',
      _id: '0',
    },
    ['1']: {
      text: 'Second fact about Typescript',
      ...metadata,
      _id: '0',
      _ref: 'notes.https://www.eweser.com|0.1',
    },
    ['abc']: {
      text: 'Third fact about Typescript. Uses a string for id',
      ...metadata,
      _id: 'abc',
      _ref: 'notes.https://www.eweser.com|0.abc',
    },
  },
};

const typescriptFlashcardsYDoc: { documents: Documents<Flashcard> } = {
  documents: {
    ['0']: {
      frontText: 'Question',
      backText: 'Answer',
      // links to other document ref
      noteRefs: ['notes.my_study_notes.0'], // or use buildRef()
      ...metadata,
    },
  },
};

const chineseFlashcardsYDoc: { documents: Documents<Flashcard> } = {
  documents: {
    ['0']: {
      frontText: 'What does 火 mean?',
      backText: 'Fire🔥',
      noteRefs: [
        buildRef({
          collectionKey: 'notes',
          roomId: 'https://www.eweser.com|abc123',
          documentId: '0',
          authServer: 'https://www.eweser.com',
        }),
      ],
      _ref: buildRef({
        collectionKey: 'flashcards',
        roomId: 'https://www.eweser.com|abc123',
        documentId: '0',
        authServer: 'https://www.eweser.com',
      }),
      _id: 'noteID',
      _created: 1653135317729,
      _updated: 1653135317729,
    },
  },
};

//** to conceptualize DB shape */
const _exampleDb: { collections: Collections } = {
  collections: {
    notes: {
      // Rooms
      ['my_study_notes']: new Room({
        db,
        collectionKey: 'notes',
        name: 'My Study Notes',
        ydoc: myStudyNotesYDoc as unknown as YDoc<Note>,
      }),
    },
    flashcards: {
      ['typescript_study_cards']: new Room({
        db,
        collectionKey: 'flashcards',
        name: 'Typescript Study Flashcards',
        ydoc: typescriptFlashcardsYDoc as unknown as YDoc<Flashcard>,
      }),
      ['chinese_flashcards']: new Room({
        db,
        collectionKey: 'flashcards',
        name: 'Chinese Study Flashcards',
        ydoc: chineseFlashcardsYDoc as unknown as YDoc<Flashcard>,
      }),
    },
    profiles: {
      ['public']: new Room({
        db,
        collectionKey: 'profiles',
        name: 'Public Profile',
        ydoc: profileYDoc as unknown as YDoc<Profile>,
      }),
      ['private']: new Room({
        db,
        collectionKey: 'profiles',
        name: 'Private Profile',
        ydoc: profilePrivateYDoc as unknown as YDoc<Profile>,
      }),
    },
    agentConfigs: {},
    agentAccessLogs: {},
    conversations: {},
  },
};

/** V2, drafts for y-sweet control flow: */

/**AUTH SERVER MODEL */

/**
 * A room is a folder or a collection of documents. It is a place where documents are stored. access permissions are set at the room level.
 */
const _room = new Room({
  db,
  id: 'uuid',
  name: 'room_name',
  collectionKey: 'flashcards', // CollectionKey
  tokenExpiry: '12-12-12',
  syncUrl: 'wss://sync.example.com',
  publicAccess: 'private', //"private" | "read" | "write" // if read or write will invite all aggregators.
  readAccess: ['userId', 'AUTH_SERVER_DOMAIN'], // auth server if just for personal use, more (aggregators) if public
  writeAccess: ['userId', 'AUTH_SERVER_DOMAIN'], // auth server if just for personal use, more (other users) if shared writable
  adminAccess: ['userId'], // generally only user has admin but could give uring sharing
  createdAt: '12-12-12',
  updatedAt: '12-12-12',
  _deleted: false,
  _ttl: null, // '12-12-12' if deleted,

  indexedDbProvider: null,
  webRtcProvider: null,
  syncProvider: null,
  ydoc: null,
});

export const _jwt = {
  id: 'jwt_id',
  access_record_id: '<user_id>|<requester_id>',

  owner_id: 'user_id',
  requester_id: 'requester_app_domain or requester_user_server_id',
  requester_type: "enum 'app' 'user'",
  created: 'date',
  updated: 'date',
  expires: 'date',
  keep_alive_days: 'number', // auto renew, extend expiry date by x days every time token is used
};

/**
 * generate on signup (give db access to an app). used to create the access token jwt
 * can only update from the auth server website.
 * basically what is inside the jwt... except for the room_ids array which might be a bit too large for a jwt.
 * after an app is permissioned by the user, they use the jwt to quickly access this access_grant from the db, and make a join call for all the room.tokens, room.names, and room.collection_keys for any room_ids in the access_grant.
 * The access grant has some duplicate data from the room table, but it is necessary to have it in one place for quick access.
 * make helper functions that update the access_grant and room tables at the same time.
 */
export const access_grant = {
  id: '<user_id>|<requester_id>',

  is_valid: 'boolean', // use to revoke an existing jwt, although it is better to just create a new jwt
  room_ids: 'enum array string[]',

  // jwt info:
  owner_id: 'user_id',
  requester_id: 'requester_app_domain or requester_user_server_id',
  requester_type: "enum 'app' 'user'",
  jwt_id: 'jwt_id',
  created: 'date',
  updated: 'date',
  expires: 'date',
  keep_alive_days: 'number', // auto renew, extend expiry date by x days every time token is used

  // validate url to make sure it isnt too long like over 200 chars
  // requester_user_id: '<https://authserver.com>|<user_id>',
  // requester_app_domain: 'app.com',
};
