import { Effect, Types, Option } from "effect"
import path from "path"
import os from "os"
import { ConfigMarkdown } from "@/config/markdown"
import { pathToFileURL } from "url"
import { InstanceState } from "@/effect/instance-state"
import type { PromptInput } from "./prompt-schemas"
import type { PromptDeps } from "./prompt-types"

export const resolvePromptParts = (deps: PromptDeps) =>
  Effect.fn("SessionPrompt.resolvePromptParts")(function* (template: string) {
    const ctx = yield* InstanceState.context
    const parts: Types.DeepMutable<PromptInput["parts"]> = [{ type: "text", text: template }]
    const files = ConfigMarkdown.files(template)
    const seen = new Set<string>()
    yield* Effect.forEach(
      files,
      Effect.fnUntraced(function* (match: RegExpExecArray) {
        const name = match[1]
        if (seen.has(name)) return
        seen.add(name)
        const filepath = name.startsWith("~/")
          ? path.join(os.homedir(), name.slice(2))
          : path.resolve(ctx.worktree, name)
        const info = yield* deps.fsys.stat(filepath).pipe(Effect.option)
        if (Option.isNone(info)) {
          const found = yield* deps.agents.get(name)
          if (found) parts.push({ type: "agent", name: found.name })
          return
        }
        const stat = info.value
        parts.push({
          type: "file",
          url: pathToFileURL(filepath).href,
          filename: name,
          mime: stat.type === "Directory" ? "application/x-directory" : "text/plain",
        })
      }),
      { concurrency: "unbounded", discard: true },
    )
    return parts
  })
