import {SRGBColorSpace, NoColorSpace} from 'three';
import {DEMO_ASSETS_ROOT_URL} from '../../../src/core/Assets';
import {ImageCopNode} from '../../../src/engine/nodes/cop/Image';
import {PolyDictionary} from '../../../src/types/GlobalTypes';
import {BasePreset, NodePresetsCollection, PresetRegister, PresetsCollectionFactory} from '../BasePreset';
import {matcapElements} from './image/matcap';

interface PolyhavenOptions {
	displacement?: boolean;
}
interface ImageOptions {
	sRGB?: boolean;
}

const imageCopNodePresetsCollectionFactory: PresetsCollectionFactory<ImageCopNode> = (node: ImageCopNode) => {
	const collection = new NodePresetsCollection();

	function sRGBImage(fileName: string) {
		return new BasePreset()
			.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/textures/${fileName}`)
			.addEntry(node.p.tcolorSpace, 1)
			.addEntry(node.p.colorSpace, SRGBColorSpace);
	}
	function linearImage(fileName: string) {
		return new BasePreset()
			.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/textures/${fileName}`)
			.addEntry(node.p.tcolorSpace, 0)
			.addEntry(node.p.colorSpace, NoColorSpace);
	}
	const asphalt = sRGBImage(`asphalt.jpg`);
	const scratches = sRGBImage(`lens-dirt/scratches.jpg`);
	const bunny_SSS_thickness = new BasePreset()
		.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/models/fbx/bunny_thickness.jpg`)
		.addEntry(node.p.tcolorSpace, 0)
		.addEntry(node.p.colorSpace, NoColorSpace)
		.addEntry(node.p.colorSpace, NoColorSpace);
	const disk = linearImage(`disk.png`);
	// const envMap = linearImage(`piz_compressed.exr`);
	const uv = sRGBImage(`uv.jpg`);
	const ktx2 = sRGBImage(`sample_uastc_zstd.ktx2`);

	function artveeSet() {
		function artvee(fileName: string) {
			return new BasePreset()
				.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/textures/resources/artvee.com/${fileName}`)
				.addEntry(node.p.tanisotropy, 1)
				.addEntry(node.p.useRendererMaxAnisotropy, 1)
				.addEntry(node.p.tminFilter, 1)
				.addEntry(node.p.tmagFilter, 1)
				.addEntry(node.p.tcolorSpace, 1)
				.addEntry(node.p.colorSpace, SRGBColorSpace);
		}
		return {
			'all-his-own': artvee('all-his-own-by-John-Samuel-Pughe.jpg'),
			'Bouquet-of-Flowers-in-a-Blue-Porcelain-Vase': artvee(
				'Bouquet-of-Flowers-in-a-Blue-Porcelain-Vase-by-Anne-Vallayer-Coster.jpg'
			),
			'Samson-and-Delilah': artvee('Samson-and-Delilah-by-Gerard-van-Honthorst.jpg'),
			'The-Milkmaid': artvee('The-Milkmaid-Johannes-Vermeer.jpg'),
			'The-Triumph-of-Aemilius-Paulus': artvee('The-Triumph-of-Aemilius-Paulus.jpg'),
		};
	}
	function polyhavenSets() {
		function polyhaven(fileName: string, options?: ImageOptions) {
			const preset = new BasePreset()
				.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/textures/resources/polyhaven.com/${fileName}`)
				.addEntry(node.p.tanisotropy, 1)
				.addEntry(node.p.useRendererMaxAnisotropy, 1)
				.addEntry(node.p.tminFilter, 1)
				.addEntry(node.p.tmagFilter, 1);

			if (options && options.sRGB) {
				preset.addEntry(node.p.tcolorSpace, 1).addEntry(node.p.colorSpace, SRGBColorSpace);
			} else {
				preset.addEntry(node.p.tcolorSpace, 0).addEntry(node.p.colorSpace, NoColorSpace);
			}

			return preset;
		}
		function polyhavenSet(setName: string, options?: PolyhavenOptions) {
			const elements: PolyDictionary<BasePreset> = {
				[`${setName}/diffuse`]: polyhaven(`${setName}/2k/diffuse.jpg`, {sRGB: true}),
				[`${setName}/rough`]: polyhaven(`${setName}/2k/rough.jpg`),
			};
			let displacement = true;
			if (options && options.displacement != null) {
				displacement = options.displacement;
			}
			if (displacement) {
				elements[`${setName}/displacement`] = polyhaven(`${setName}/2k/displacement.png`);
			}

			return elements;
		}
		return {
			...polyhavenSet('brick_floor_002'),
			...polyhavenSet('brick_floor_003'),
			...polyhavenSet('concrete_floor_painted'),
			...polyhavenSet('floor_tiles_06'),
			...polyhavenSet('floor_tiles_08'),
			...polyhavenSet('large_floor_tiles_02'),
			...polyhavenSet('marble_01'),
			...polyhavenSet('medieval_blocks_05'),
			...polyhavenSet('medieval_blocks_05'),
			...polyhavenSet('square_floor'),
			...polyhavenSet('tiled_floor_001'),
			...polyhavenSet('aerial_rocks_02'),
			...polyhavenSet('brick_moss_001'),
			...polyhavenSet('denmin_fabric_02', {displacement: false}),
			...polyhavenSet('fabric_pattern_07', {displacement: false}),
		};
	}
	function unsplash() {
		function _unsplash(fileName: string) {
			return new BasePreset()
				.addEntry(node.p.url, `${DEMO_ASSETS_ROOT_URL}/textures/resources/unsplash.com/${fileName}`)
				.addEntry(node.p.tanisotropy, 1)
				.addEntry(node.p.useRendererMaxAnisotropy, 1)
				.addEntry(node.p.tminFilter, 1)
				.addEntry(node.p.tmagFilter, 1)
				.addEntry(node.p.tcolorSpace, 1)
				.addEntry(node.p.colorSpace, SRGBColorSpace);
		}
		const dict: Record<string, BasePreset> = {
			'claudio-testa': _unsplash('claudio-testa--SO3JtE3gZo-unsplash.jpg'),
			charlesdeluvio: _unsplash('charlesdeluvio-pOUA8Xay514-unsplash.jpg'),
			'ivana-cajina': _unsplash('ivana-cajina-dnL6ZIpht2s-unsplash.jpg'),
			'joel-mott': _unsplash('joel-mott-LaK153ghdig-unsplash.jpg'),
			'johannes-plenio': _unsplash('johannes-plenio-DKix6Un55mw-unsplash.jpg'),
			'prince-akachi': _unsplash('prince-akachi-LWkFHEGpleE-unsplash.jpg'),
			'vince-fleming': _unsplash('vince-fleming-j3lf-Jn6deo-unsplash.jpg'),
		};
		const keys = Object.keys(dict);
		const unsplashDisct: Record<string, BasePreset> = {};
		for (let key of keys) {
			unsplashDisct[`unsplash/${key}`] = dict[key];
		}
		return unsplashDisct;
	}

	collection.setPresets({
		asphalt,
		scratches,
		bunny_SSS_thickness,
		disk,
		// envMap,
		uv,
		ktx2,
		...artveeSet(),
		...polyhavenSets(),
		...matcapElements(node),
		...unsplash(),
	});

	return collection;
};
export const imageCopPresetRegister: PresetRegister<typeof ImageCopNode, ImageCopNode> = {
	nodeClass: ImageCopNode,
	setupFunc: imageCopNodePresetsCollectionFactory,
};
