import * as prismic from "@prismicio/client"

import { sentenceCase, snakeCase } from "../lib/changeCase"
import { createFaker } from "../lib/createFaker"
import * as modelGen from "../model"
import type { MockValueStateConfig, MockValueConfig } from "../types"

export type MockLinkToMediaValueConfig<
	Model extends prismic.CustomTypeModelLinkToMediaField = prismic.CustomTypeModelLinkToMediaField,
	State extends prismic.FieldState = prismic.FieldState,
> = {
	withText?: NonNullable<Model["config"]>["allowText"] extends undefined ? false : boolean
} & MockValueConfig<Model> &
	MockValueStateConfig<State>

export type MockLinkToMediaValue<State extends prismic.FieldState = prismic.FieldState> =
	prismic.LinkToMediaField<State>

export const linkToMedia = <
	Model extends prismic.CustomTypeModelLinkToMediaField = prismic.CustomTypeModelLinkToMediaField,
	State extends prismic.FieldState = "filled",
>(
	config: MockLinkToMediaValueConfig<Model, State>,
): MockLinkToMediaValue<State> => {
	const faker = config.faker || createFaker(config.seed)

	if (config.state === "empty") {
		return {
			link_type: prismic.LinkType.Media,
		} as MockLinkToMediaValue<State>
	} else {
		const model = config.model || modelGen.link({ faker })

		return {
			link_type: prismic.LinkType.Media,
			id: faker.hash(11),
			name: `${snakeCase(faker.words(faker.range(1, 2)))}.example`,
			kind: snakeCase(faker.word()),
			url: faker.url(),
			size: faker.range(500, 3000).toString(),
			height: faker.range(500, 3000).toString(),
			width: faker.range(500, 3000).toString(),
			...((config.withText ?? (model.config?.allowText && faker.boolean()))
				? { text: sentenceCase(faker.words(2)) }
				: {}),
		} as MockLinkToMediaValue<State>
	}
}
