import { OpenApi } from "effect/unstable/httpapi"
import { SaeeolHttpApi } from "./api"

export type OpenApiParameter = {
  name: string
  in: string
  required?: boolean
  schema?: OpenApiSchema
}

export type OpenApiOperation = {
  parameters?: OpenApiParameter[]
  responses?: Record<string, OpenApiResponse>
  requestBody?: {
    required?: boolean
    content?: Record<string, { schema?: OpenApiSchema }>
  }
  security?: unknown
}

export type OpenApiPathItem = Partial<Record<"get" | "post" | "put" | "delete" | "patch", OpenApiOperation>>

export type OpenApiSpec = {
  components?: {
    schemas?: Record<string, OpenApiSchema>
    securitySchemes?: Record<string, unknown>
  }
  paths?: Record<string, OpenApiPathItem>
}

export type OpenApiSchema = {
  $ref?: string
  additionalProperties?: OpenApiSchema | boolean
  allOf?: OpenApiSchema[]
  anyOf?: OpenApiSchema[]
  description?: string
  enum?: Array<string | boolean>
  items?: OpenApiSchema
  maximum?: number
  minimum?: number
  oneOf?: OpenApiSchema[]
  pattern?: string
  prefixItems?: OpenApiSchema[]
  properties?: Record<string, OpenApiSchema>
  required?: string[]
  type?: string
}

export type OpenApiResponse = {
  description?: string
  content?: Record<string, { schema?: OpenApiSchema }>
}

export const InstanceQueryParameters = [
  { name: "directory", in: "query", required: false, schema: { type: "string" } },
  { name: "workspace", in: "query", required: false, schema: { type: "string" } },
] satisfies OpenApiParameter[]

export const QueryNumberParameters = new Set(["start", "cursor", "limit", "method"])
export const QueryBooleanParameters = new Set(["roots", "archived"])

export const QueryParameterSchemas = {
  "GET /find/file limit": { type: "integer", minimum: 1, maximum: 200 },
  "GET /session/{sessionID}/diff messageID": { type: "string", pattern: "^msg.*" },
  "GET /session/{sessionID}/message limit": { type: "integer", minimum: 0, maximum: Number.MAX_SAFE_INTEGER },
} satisfies Record<string, OpenApiSchema>

export const PathParameterSchemas = {
  sessionID: { type: "string", pattern: "^ses.*" },
  messageID: { type: "string", pattern: "^msg.*" },
  partID: { type: "string", pattern: "^prt.*" },
  permissionID: { type: "string", pattern: "^per.*" },
  ptyID: { type: "string", pattern: "^pty.*" },
} satisfies Record<string, OpenApiSchema>

export const LegacyComponentDescriptions = {
  LogLevel: "Log level",
  ServerConfig: "Server configuration for saeeol serve and web commands",
  LayoutConfig: "@deprecated Always uses stretch layout.",
} satisfies Record<string, string>
