import { diff } from 'deep-object-diff'

export type MaybeContext = string | Record<string, unknown> | undefined
export function makeContextDiff(seedContext: MaybeContext, defaultContext: MaybeContext) {
	const base = makeContext(defaultContext)
	const provided = makeContext(seedContext)
	const result = diff(base, provided)
	if (!isPlainObject(result)) {
		throw new Error(`Context (${typeof result}) is not a plain object`)
	}
	return result
}

export function makeContext(ctx: MaybeContext) {
	if (typeof ctx === 'string') {
		try {
			ctx = JSON.parse(ctx)
			let c = 0
			while (typeof ctx === 'string') {
				if (c > 3) return {}
				c++
			}
			if (!isPlainObject(ctx)) {
				throw new Error(`Context (${ctx}) is not a plain object`)
			}
			return ctx
		} catch (err) {
			console.error(err)
			return {}
		}
	} else {
		return ctx || {}
	}
}

function isPlainObject(value: unknown): value is Record<string, unknown> {
	return value !== null && typeof value === 'object'
}
