import type { TRPCRootObject } from '@trpc/server/unstable-core-do-not-import'
import { z } from 'zod'
import { access, mkdir, readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'

import { bumpImportNonce } from '../lib/import-nonce'
import { getProjectBosunApi } from '../lib/project-api'
import { getProjectDir, getProjectPackageJson } from '../lib/get-root-path'
import type { TrpcContext } from '../lib/trpc-context'

const DEFAULT_REGION_CONFIG_PATH = 'src/region-config.json'

async function resolveRegionConfigPath(): Promise<string> {
	const projectDir = await getProjectDir()
	const pkg = await getProjectPackageJson()
	const configured = pkg?.bosun?.regionConfigPath
	const rel = typeof configured === 'string' && configured.trim() ? configured.trim() : null
	return path.resolve(projectDir, rel ?? DEFAULT_REGION_CONFIG_PATH)
}

async function fileExists(p: string): Promise<boolean> {
	try {
		await access(p)
		return true
	} catch {
		return false
	}
}

export function createRegionConfigRouter(t: TRPCRootObject<TrpcContext, any, any>) {
	return t.router({
		meta: t.procedure.input(z.object({ agent: z.string() })).query(async ({ input }) => {
			const bosunApi = await getProjectBosunApi()
			if (!bosunApi) return null
			return bosunApi.getAgentMeta(input.agent)
		}),
		get: t.procedure.query(async () => {
			const configPath = await resolveRegionConfigPath()
			if (!(await fileExists(configPath))) {
				throw new Error(`Cannot find region config at path '${configPath}'`)
			}
			return await readFile(configPath, 'utf-8')
		}),
		save: t.procedure.input(z.object({ text: z.string() })).mutation(async ({ input }) => {
			const configPath = await resolveRegionConfigPath()
			await mkdir(path.dirname(configPath), { recursive: true })
			await writeFile(configPath, input.text, 'utf-8')

			// Bump import nonce so subsequent imports of the project's module graph are cache-busted.
			const importNonce = bumpImportNonce()
			return { importNonce }
		})
	})
}
