/**
 * any user-application share a set of
 * properties which this interface describes.
 *  @public
 */
export interface UserApplicationBaseProperties {
  id: string
  appHost: string
  createdAt: string
  updatedAt: string
  dashboardStatus: 'default' | 'disabled'
}

/**
 * @public
 */
export interface WorkspaceManifest {
  name: string
  title: string
  subtitle?: string | null
  basePath: string
  projectId: string
  dataset: string
  icon?: string | null
  schema: string
  tools?: string
}

/**
 * @public
 */

interface StudioManifestCommon {
  version: number
  createdAt: string
  workspaces: WorkspaceManifest[]
}

/**
 * @public
 */

interface StudioManifestV2 extends StudioManifestCommon {
  version: 2
}

/**
 * @public
 */

interface StudioManifestV3 extends StudioManifestCommon {
  studioVersion: string
  version: 3
}

/**
 * @public
 */

export type StudioManifest = StudioManifestV2 | StudioManifestV3

/**
 * @public
 */
export interface WorkspaceServerManifest extends Pick<
  WorkspaceManifest,
  'icon' | 'name' | 'title' | 'dataset' | 'basePath' | 'projectId'
> {
  schemaDescriptorId: string
}

/**
 * @public
 */
export interface ServerManifest {
  buildId?: string
  bundleVersion?: string
  version?: string
  workspaces?: Array<WorkspaceServerManifest>
}

// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
type AutoUpdatingVersion = 'stable' | 'next' | 'lastest' | string

/**
 * A studio application always has a projectId
 * and is of type 'studio'.
 * @public
 */
export interface StudioApplicationProperties extends UserApplicationBaseProperties {
  title: null
  organizationId?: null
  projectId: string
  type: 'studio'
  manifest: null | StudioManifest
  autoUpdatingVersion: AutoUpdatingVersion | null
  config: {
    'live-manifest'?: {
      createdAt: string
      updatedAt: string
      updatedBy: string
      value: ServerManifest
    }
  }
}

/**
 * A core application is not tied to a project therefore
 * has no projectId.
 * @public
 */
export interface CoreApplicationProperties extends UserApplicationBaseProperties {
  title: string
  organizationId: string
  projectId?: null
  type: 'coreApp'
}

/**
 * @public
 */
interface ActiveDeployment {
  id: string
  version: string
  isActiveDeployment: boolean
  userApplicationId: string
  isAutoUpdating: boolean
  manifest: ServerManifest | null
  size: number
  deployedAt: string
  deployedBy: string
  createdAt: string
  updatedAt: string
}

/**
 * Additional properties that make an application considered
 * to be internal which is deployed on sanity infrastructure.
 * @public
 */
export interface InternalApplicationProperties {
  urlType: 'internal'
  activeDeployment: ActiveDeployment | null
}

/**
 * Representation of an internal studio application.
 * @public
 */
export interface InternalStudioApplication
  extends StudioApplicationProperties, InternalApplicationProperties {}

/**
 * Representation of an internal core application.
 * @public
 */
export interface InternalCoreApplication
  extends CoreApplicationProperties, InternalApplicationProperties {}

/**
 * Additional properties that make an application considered to be
 * external which is not deployed on sanity infrastructure, it's
 * therefore hosted elsewhere so we have no deployment info.
 * @public
 */
export interface ExternalApplicationProperties {
  urlType: 'external'
  activeDeployment: null
}

/**
 * Representation of an external studio application.
 * @public
 */
export interface ExternalStudioApplication
  extends StudioApplicationProperties, ExternalApplicationProperties {}

/**
 * Representation of an external core application.
 * @public
 */
export interface ExternalCoreApplication
  extends CoreApplicationProperties, ExternalApplicationProperties {}

/**
 * Representation of a studio applications, both internal & external.
 * @public
 */
export type StudioApplication = InternalStudioApplication | ExternalStudioApplication

/**
 * Representation of a core applications, both internal & external.
 * @public
 */
export type CoreApplication = InternalCoreApplication | ExternalCoreApplication

/**
 * Representation of a user application, both studio & core.
 * @public
 */
export type UserApplication = StudioApplication | CoreApplication

/**
 * @public
 */
export type StudioResource = Pick<
  StudioApplication,
  | 'projectId'
  | 'updatedAt'
  | 'urlType'
  | 'activeDeployment'
  | 'dashboardStatus'
  | 'autoUpdatingVersion'
  | 'manifest'
  | 'config'
> & {
  title: string
  id: string
  basePath: string
  dataset?: string
  href: string
  icon?: string | null
  name: string
  subtitle?: string | null
  url: string
  userApplicationId: string
  type: 'studio'
  hasManifest: boolean
  hasSchema: boolean
  version?: string
}

/**
 * @public
 */
export type ApplicationResource = Omit<CoreApplication, 'type'> & {
  type: 'application'
  url: string
}

/**
 * @public
 */
export interface MediaResource {
  id: string
  type: 'media-library'
}

/**
 * @public
 */
export interface CanvasResource {
  id: string
  type: 'canvas'
}

/**
 * @public
 */
export type Resource = StudioResource | ApplicationResource | MediaResource | CanvasResource
