import { glob } from 'glob'
import path from 'node:path'
import fs from 'node:fs'

// TODO Drop this when all agents have bosun root
const legacyPath = 'src/bosun/workflows.ts'

async function resolveProjectPackageJsonPath(warnings: string[]): Promise<string> {
	let projectRoot: string | undefined
	if (process.env.BOSUN_NPX_RUN === 'true') {
		if (fs.existsSync(path.join(process.cwd(), 'package.json'))) {
			projectRoot = path.join(process.cwd(), 'package.json')
		}
	} else {
		warnings.push(
			'Run Bosun from your project folder.\n' +
				' `projects` folder inside Bosun is deprecated, only first project is loaded!'
		)
		const projectFiles = await glob(`projects/*/package.json`, { absolute: true })
		projectRoot = projectFiles[0]
	}

	if (!projectRoot) {
		throw new Error('Cannot find project root directory or package.json in it.')
	}

	return projectRoot
}

export async function getProjectPackageJsonPath(): Promise<string> {
	const warnings: string[] = []
	const projectRoot = await resolveProjectPackageJsonPath(warnings)
	if (warnings.length) {
		printWarnings(warnings)
	}
	return projectRoot
}

export async function getProjectDir(): Promise<string> {
	return path.dirname(await getProjectPackageJsonPath())
}

export async function getProjectPackageJson(): Promise<any> {
	const pkgPath = await getProjectPackageJsonPath()
	return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
}

/**
 * @returns full path to the file with agents factories
 */
export async function getRootPath() {
	const warnings: string[] = []
	const projectRoot = await resolveProjectPackageJsonPath(warnings)
	const pkg = JSON.parse(fs.readFileSync(projectRoot, 'utf-8'))
	let bosunRoot: string | undefined = pkg?.bosun?.root
	if (!bosunRoot) {
		warnings.push(
			'Specify `bosun.root` in your `package.json`.\n' +
				`Running with legacy path: \`${legacyPath}\` which is deprecated!`
		)
		bosunRoot = legacyPath
	}

	if (warnings.length) {
		printWarnings(warnings)
	}
	return path.resolve(path.dirname(projectRoot), bosunRoot)
}

function printWarnings(warnings: string[]) {
	if (warnings.length === 0) return
	const length = 100

	const orange = '\x1b[91m' // ANSI bright red color
	const reset = '\x1b[0m' // Reset color
	const header = 'WARNING'

	console.log(`${orange}┌─ ${header} ${'─'.repeat(length - header.length - 3)}┐${reset}`)

	for (const warning of warnings) {
		const lines = warning.split('\n')
		for (let i = 0; i < lines.length; i++) {
			const prefix = i === 0 ? '• ' : '  '
			console.log(`${orange}│ ${prefix}${lines[i].padEnd(length - 4)} │${reset}`)
		}
	}

	console.log(`${orange}└${'─'.repeat(length)}┘${reset}`)
}
