import z from "zod"
import { Schema } from "effect"
import {
  CodeIndexManager,
} from "@saeeol/indexing/engine"
import {
  IndexingStatus,
  INDEXING_STATUS_STATES,
} from "@saeeol/indexing/status"
import { Bus } from "@/bus"
import { BusEvent } from "@/bus/bus-event"

type Status = z.infer<typeof IndexingStatus>

const StateSchema = Schema.Literals(INDEXING_STATUS_STATES).annotate({ identifier: "IndexingStatusState" })

const StatusSchema = Schema.Struct({
  state: StateSchema,
  message: Schema.String,
  processedFiles: Schema.Number,
  totalFiles: Schema.Number,
  percent: Schema.Number,
}).annotate({ identifier: "IndexingStatus" })

type Entry = {
  manager?: CodeIndexManager
  current(): Status
  publish(): Promise<void>
  dispose(): void
}

type Cache = {
  promise: Promise<Entry>
  ready: Promise<Entry>
  resolve(entry: Entry): void
  reject(err: unknown): void
  entry?: Entry
  disposed?: boolean
}

const Event = BusEvent.define(
  "indexing.status",
  Schema.Struct({
    status: StatusSchema,
  }),
)

export { StatusSchema, Event }
export type { Status, Entry, Cache }
