type WorkerStatusActive @variant {
  # No additional information needed
  _phantom: Int
}

type WorkerStatusLeft @variant {
  # TODO: Variant relationships
  workerStartedLeavingEventId: ID!

  # Set when the unstaking period is finished
  workerExitedEventId: ID
}

type WorkerStatusTerminated @variant {
  # TODO: Variant relationship
  terminatedWorkerEventId: ID!

  # Set when the unstaking period is finished
  workerExitedEventId: ID
}

union WorkerStatus = WorkerStatusActive | WorkerStatusLeft | WorkerStatusTerminated

# Working Groups
type Worker @entity {
  "Worker id ({workingGroupName}-{workerId})"
  id: ID!

  "WorkerId in specific working group module"
  runtimeId: Int!

  "The group that the worker belongs to"
  group: WorkingGroup!

  "Worker membership"
  membership: Membership!

  "Worker's role account"
  roleAccount: String!

  "Worker's reward account"
  rewardAccount: String!

  "Worker's staking account"
  stakeAccount: String!

  "Current worker status"
  status: WorkerStatus!

  "Whether the worker is also the working group lead"
  isLead: Boolean!

  "Current role stake (in JOY)"
  stake: BigInt!

  "All related reward payouts"
  payouts: [RewardPaidEvent!] @derivedFrom(field: "worker")

  "Block the worker was hired at"
  hiredAtBlock: Block!

  "Time the worker was hired at"
  hiredAtTime: DateTime!

  "The event that caused the worker to be hired"
  entry: OpeningFilledEvent!

  "Related worker entry application"
  application: WorkingGroupApplication!

  "Worker's storage data"
  storage: String
}

type WorkingGroupMetadata @entity {
  "Status name"
  name: String!

  "Status message"
  message: String

  "Working group about text"
  about: String

  "Working group description text"
  description: String

  "Block the status was set at"
  setAtBlock: Block!

  "The time at which status was set"
  setAtTime: DateTime!
}

type WorkingGroup @entity {
  "Working group name"
  name: String!

  "Working group current metadata"
  status: WorkingGroupMetadata

  "Current working group leader"
  leader: Worker

  "Workers that currently belong to the group or belonged to the group in the past"
  workers: [Worker!] @derivedFrom(field: "group")

  "All openings related to this group"
  openings: [WorkingGroupOpening!] @derivedFrom(field: "group")

  "Current working group budget (JOY)"
  budget: BigInt!

  # ...
}

type OpeningStatusCancelled @variant {
  # TODO: Variant relationships
  openingCancelledEventId: ID!
}

type OpeningStatusOpen @variant {
  # No additional information needed
  _phantom: Int
}

type OpeningStatusFilled @variant {
  # TODO: Variant relationships
  openingFilledEventId: ID!
}

union WorkingGroupOpeningStatus = OpeningStatusOpen | OpeningStatusFilled | OpeningStatusCancelled

enum WorkingGroupOpeningType {
  REGULAR
  LEADER
}

type WorkingGroupOpeningMetadata @entity {
  "Whether the originally provided metadata was valid"
  originallyValid: Boolean!

  "Opening short description"
  shortDescription: String!

  "Opening description (md-formatted)"
  description: String!

  "Expected max. number of applicants that will be hired"
  hiringLimit: Int

  "Expected time when the opening will close"
  expectedEnding: DateTime

  "Md-formatted text explaining the application process"
  applicationDetails: String!

  "List of questions that should be answered during application"
  applicationFormQuestions: [ApplicationFormQuestion!]! @derivedFrom(field: "openingMetadata")
}

type WorkingGroupOpening @entity {
  "Opening id ({workingGroupName}-{openingId})"
  id: ID!

  "OpeningId in specific working group module"
  runtimeId: Int!

  "Related working group"
  group: WorkingGroup!

  "List of opening applications"
  applications: [WorkingGroupApplication!] @derivedFrom(field: "opening")

  "Type of the opening (Leader/Regular)"
  type: WorkingGroupOpeningType!

  "Current opening status"
  status: WorkingGroupOpeningStatus!

  "Opening metadata"
  metadata: WorkingGroupOpeningMetadata!

  "Min. application/role stake amount"
  stakeAmount: BigInt!

  "Role stake unstaking period in blocks"
  unstakingPeriod: Int!

  "Initial workers' reward per block"
  rewardPerBlock: BigInt!

  "Block the opening was created at"
  createdAtBlock: Block!

  "Time of opening creation"
  createdAt: DateTime!
}

type UpcomingWorkingGroupOpening @entity {
  "Event the upcoming opening was created in"
  createdInEvent: StatusTextChangedEvent! @unique

  "Block the upcoming opening was added at"
  createdAtBlock: Block!

  "Related working group"
  group: WorkingGroup!

  "Expected opening start time"
  expectedStart: DateTime!

  "Expected min. application/role stake amount"
  stakeAmount: BigInt!

  "Expected reward per block"
  rewardPerBlock: BigInt!

  "Opening metadata"
  metadata: WorkingGroupOpeningMetadata!
}

type ApplicationStatusPending @variant {
  # No additional information needed
  _phantom: Int
}

type ApplicationStatusAccepted @variant {
  # TODO: Variant relationships
  openingFilledEventId: ID!
}

type ApplicationStatusRejected @variant {
  # TODO: Variant relationships
  openingFilledEventId: ID!
}

type ApplicationStatusCancelled @variant {
  openingCancelledEventId: ID!
}

type ApplicationStatusWithdrawn @variant {
  # TODO: Variant relationships
  applicationWithdrawnEventId: ID!
}

union WorkingGroupApplicationStatus =
    ApplicationStatusPending
  | ApplicationStatusAccepted
  | ApplicationStatusRejected
  | ApplicationStatusWithdrawn
  | ApplicationStatusCancelled

type WorkingGroupApplication @entity {
  "Application id ({workingGroupName}-{applicationId})"
  id: ID!

  "ApplicationId in specific working group module"
  runtimeId: Int!

  "Related working group opening"
  opening: WorkingGroupOpening!

  "Applicant's membership"
  applicant: Membership!

  "Application stake"
  stake: BigInt!

  "Applicant's initial role account"
  roleAccount: String!

  "Applicant's initial reward account"
  rewardAccount: String!

  "Applicant's initial staking account"
  stakingAccount: String!

  "Answers to application form questions"
  answers: [ApplicationFormQuestionAnswer!] @derivedFrom(field: "application")

  "Current application status"
  status: WorkingGroupApplicationStatus!

  "Block the application was created at"
  createdAtBlock: Block!

  "Time of application creation"
  createdAt: DateTime!
}

type ApplicationFormQuestionAnswer @entity {
  "Related application"
  application: WorkingGroupApplication!

  "The question beeing answered"
  question: ApplicationFormQuestion!

  "Applicant's answer"
  answer: String!
}

enum ApplicationFormQuestionType {
  TEXT
  TEXTAREA
}

type ApplicationFormQuestion @entity {
  "Related opening metadata"
  openingMetadata: WorkingGroupOpeningMetadata!

  "The question itself"
  question: String!

  "Type of the question (UI answer input type)"
  type: ApplicationFormQuestionType!

  "Index of the question"
  index: Int!
}