import {__, _x} from '@wordpress/i18n'

import {
	useMemo,
} from '@wordpress/element'

import {
	store as editorStore,
} from '@wordpress/editor'

import {
	useSelect,
} from '@wordpress/data'

import {
	type Attachment,
} from '@wordpress/core-data'

import {
	intermediateImageDimensions,
} from '../../data'

import {
	ARRAY_UNIQUE,
} from '@ska/utils'

import {
	CUSTOM_SIZE,
	NO_SIZES,
	NO_DIMENSIONS,
} from './constants'

import {
	getImageSizeName,
	SORT_SIZES,
} from './util'

import type {
	ImageDimensions,
	ImageSizes,
	MediaSize,
} from './types'

const useImageSettings = (): {
	imageSizes: ImageSizes,
	imageDimensions: ImageDimensions,
} => {

	const {
		imageSizes = NO_SIZES,
		imageDimensions = NO_DIMENSIONS,
	} = useSelect((select: any) => {

		const {
			getEditorSettings,
		} = select(editorStore)

		const {
			imageSizes,
			imageDimensions,
		} = getEditorSettings()

		return {
			imageSizes,
			imageDimensions,
		}
	}, [])

	return {
		imageSizes,
		imageDimensions,
	}
}

export const useMediaSizeOptions = (attachment?: Attachment, custom: boolean = false) => {

	const {
		imageSizes,
		imageDimensions,
	} = useImageSettings()

	return useMemo(() => {

		const intermediateSizes = Object.entries(intermediateImageDimensions).map(([slug, {width, height, crop}]) => {
			return {
				slug,
				width,
				height,
				crop,
			}
		})

		const allSizes = imageSizes
			.map(({slug, name}: {slug: string, name: string}) => {

				const {
					width = 0,
					height = 0,
					crop = false,
				} = Object(imageDimensions).hasOwnProperty(slug) ? imageDimensions[slug] : {}

				return {
					slug,
					width,
					height,
					crop,
				}
			})
			.reduce((acc: MediaSize[], cur: MediaSize) => {
				return [
					...acc,
					...(cur.slug === 'full' ? intermediateSizes : []),
					cur,
				]
			}, []) as MediaSize[]

		let sizes = allSizes

		if(attachment) {

			const {
				media_details = {} as Attachment['media_details'],
			} = attachment

			const {
				sizes: mediaSizes = {},
				width = 0,
				height = 0,
			} = media_details

			const slugs = Object.keys(mediaSizes).concat(allSizes.map(({slug}) => slug)).filter(ARRAY_UNIQUE)

			const adaptedSizes = slugs.map(slug => {

				if(slug in mediaSizes) {

					const {
						width = 0,
						height = 0,
					} = mediaSizes[slug]

					return {
						slug,
						width,
						height,
						// @ts-ignore
						crop: slug in imageSizes ? imageSizes[slug].crop : false,
					}
				}

				if(slug in imageDimensions) {

					const {
						width = 0,
						height = 0,
						crop = false,
					} = imageDimensions[slug]

					return {
						slug,
						width,
						height,
						crop,
					}
				}

				return {
					slug,
					width,
					height,
					crop: false,
				}
			})

			sizes = adaptedSizes.sort(SORT_SIZES)
		}

		const {
			width: fullWidth = 99999,
			height: fullHeight = 99999,
		} = sizes.find(({slug}) => slug === 'full') || {}

		return sizes
			.filter(({slug, width, height}) => {
				if(attachment) {
					/** Skip sizes that have same (or greater than) dimensions as full size. */
					return slug === 'full' || width < fullWidth || height < fullHeight
				}
				return true
			})
			.sort(SORT_SIZES)
			.concat(custom ? CUSTOM_SIZE : [])
			.map(({slug, width, height}) => ({
				label: getImageSizeName(slug, width, height, imageSizes, imageDimensions),
				value: slug,
				width,
				height,
			}))
	}, [attachment, custom, imageSizes, imageDimensions])
}
