enum Role {
  Owner
  Maintainer
  Reader
}

enum Permission {
  View
  Edit
}

enum Environment {
  Production
  Preview
  Development
}

enum DeploymentStatus {
  Building
  Ready
  Error
}

enum DomainStatus {
  Live
  Pending
}

type User {
  id: String!
  name: String
  email: String!
  organizations: [Organization!]
  projects: [Project!]
  isVerified: Boolean!
  createdAt: String!
  updatedAt: String!
  gitHubToken: String
}

type Organization {
  id: String!
  name: String!
  slug: String!
  projects: [Project!]
  createdAt: String!
  updatedAt: String!
  members: [OrganizationMember!]
}

type OrganizationMember {
  id: String!
  member: User!
  role: Role!
  createdAt: String!
  updatedAt: String!
}

type Project {
  id: String!
  owner: User!
  deployments: [Deployment!]
  name: String!
  repository: String!
  prodBranch: String!
  description: String
  template: String
  framework: String
  webhooks: [String!]
  members: [ProjectMember!]
  environmentVariables: [EnvironmentVariable!]
  createdAt: String!
  updatedAt: String!
  organization: Organization!
  icon: String
  subDomain: String
}

type ProjectMember {
  id: String!
  member: User!
  permissions: [Permission!]!
  isPending: Boolean!
  createdAt: String!
  updatedAt: String!
}

type Deployment {
  id: String!
  domain: Domain
  branch: String!
  commitHash: String!
  commitMessage: String!
  url: String
  environment: Environment!
  isCurrent: Boolean!
  status: DeploymentStatus!
  createdAt: String!
  updatedAt: String!
  createdBy: User!
}

type Domain {
  id: String!
  branch: String!
  name: String!
  redirectTo: Domain
  status: DomainStatus!
  createdAt: String!
  updatedAt: String!
}

type EnvironmentVariable {
  id: String!
  environment: Environment!
  key: String!
  value: String!
  createdAt: String!
  updatedAt: String!
}

type AuthResult {
  token: String!
}

input AddEnvironmentVariableInput {
  environments: [Environment!]!
  key: String!
  value: String!
}

input AddProjectInput {
  name: String!
  repository: String!
  prodBranch: String!
  template: String
}

input UpdateProjectInput {
  name: String
  description: String
  prodBranch: String
  organizationId: String
  webhooks: [String!]
}

input AddDomainInput {
  name: String!
}

input UpdateDomainInput {
  name: String
  branch: String
  redirectToId: String
}

input UpdateEnvironmentVariableInput {
  key: String
  value: String
}

input AddProjectMemberInput {
  email: String!
  permissions: [Permission!]
}

input UpdateProjectMemberInput {
  permissions: [Permission]
}

input FilterDomainsInput {
  branch: String
  status: DomainStatus
}

type Query {
  user: User!
  organizations: [Organization!]
  projects: [Project!]
  projectsInOrganization(organizationSlug: String!): [Project!]
  project(projectId: String!): Project
  deployments(projectId: String!): [Deployment!]
  environmentVariables(projectId: String!): [EnvironmentVariable!]
  projectMembers(projectId: String!): [ProjectMember!]
  searchProjects(searchText: String!): [Project!]
  domains(projectId: String!, filter: FilterDomainsInput): [Domain]
}

type Mutation {
  addProjectMember(projectId: String!, data: AddProjectMemberInput): Boolean!
  updateProjectMember(
    projectMemberId: String!
    data: UpdateProjectMemberInput
  ): Boolean!
  removeProjectMember(projectMemberId: String!): Boolean!
  addEnvironmentVariables(
    projectId: String!
    data: [AddEnvironmentVariableInput!]
  ): Boolean!
  updateEnvironmentVariable(
    environmentVariableId: String!
    data: UpdateEnvironmentVariableInput!
  ): Boolean!
  removeEnvironmentVariable(environmentVariableId: String!): Boolean!
  updateDeploymentToProd(deploymentId: String!): Boolean!
  addProject(organizationSlug: String!, data: AddProjectInput): Project!
  updateProject(projectId: String!, data: UpdateProjectInput): Boolean!
  redeployToProd(deploymentId: String!): Boolean!
  deleteProject(projectId: String!): Boolean!
  deleteDomain(domainId: String!): Boolean!
  rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
  addDomain(projectId: String!, data: AddDomainInput!): Boolean!
  updateDomain(domainId: String!, data: UpdateDomainInput!): Boolean!
  authenticateGitHub(code: String!): AuthResult!
  unauthenticateGitHub: Boolean!
}
