import { nanoid } from '../nanoid.js'
import { IFile, File } from './store/File.js'
import { Thing } from './Thing.js'
import { HttpProject, IHttpProject } from './HttpProject.js'
import { ProjectKind } from './kinds.js'

/**
 * This model represents a meta data for an HTTP project stored with the data store.
 * This does not include the HTTP project entity, though, it is referenced through the same key.
 */
export interface IProject extends IFile {
  kind: typeof ProjectKind
}

/**
 * This model represents a meta data for an HTTP project stored with the data store.
 * This does not include the HTTP project entity, though, it is referenced through the same key.
 */
export class Project extends File {
  override kind = ProjectKind

  static fromProject(project: HttpProject | IHttpProject): Project {
    let final: IHttpProject
    if (typeof (project as HttpProject).toJSON === 'function') {
      final = (project as HttpProject).toJSON()
    } else {
      final = project as IHttpProject
    }
    const init: IProject = {
      kind: ProjectKind,
      key: project.key,
      info: { ...final.info },
      lastModified: { user: '', time: 0, byMe: false },
      parents: [],
      permissionIds: [],
      permissions: [],
    }
    return new Project(init)
  }

  /**
   * @param name The name to set.
   */
  static override fromName(name: string): Project {
    return super.fromName(name, ProjectKind) as Project
  }

  constructor(input?: string | IProject) {
    super()
    let init: IProject
    if (typeof input === 'string') {
      init = JSON.parse(input)
    } else if (typeof input === 'object') {
      init = input
    } else {
      init = {
        kind: ProjectKind,
        key: nanoid(),
        info: Thing.fromName('').toJSON(),
        parents: [],
        permissionIds: [],
        permissions: [],
        lastModified: { user: '', time: 0, byMe: false },
      }
    }
    this.new(init)
  }

  override new(init: IProject): this {
    if (!Project.isProject(init)) {
      throw new Error(`Not a project file.`)
    }
    super.new(init)
    this.kind = ProjectKind
    return this
  }

  static isProject(input: unknown): boolean {
    const typed = input as IProject
    if (!input || typed.kind !== ProjectKind) {
      return false
    }
    return true
  }

  override toJSON(): IProject {
    const result: IProject = {
      ...super.toJSON(),
      kind: ProjectKind,
    }
    return result
  }
}
