import {
	defineConfig,
	presetIcons,
	presetTypography,
	presetUno,
	presetWebFonts,
	transformerDirectives,
	transformerVariantGroup,
} from 'unocss';
import { definePreset } from 'unocss';
import { colorResolver, variantGetParameter } from '@unocss/preset-mini/utils';

import * as utils from './uno-utils.js';

const presetForcedColors = definePreset(
	/** @returns {import('unocss').Preset} */
	() => {
		return {
			name: 'preset-forced-colors',
			variants: [
				{
					name: 'forced-colors',
					match(matcher, ctx) {
						if (!matcher.startsWith('forced-colors:')) {
							return matcher
						}
						return {
							matcher: matcher.slice('forced-colors:'.length),
							handle: (input, next) => next({
								...input,
								parent: `${input.parent ? `${input.parent} $$` : ''}@media(forced-colors: active)`,
								parentOrder: 1000,
							}),
						}
						/* handle: (input, next) => next({
							...input,
							parent: `${input.parent ? `${input.parent} $$` : ''}@container${label ? ` ${label} ` : ''}${container}`,
							parentOrder: order,
						}), */
					},
					multiPass: true,
				}
			],
		}
	}
)

/**
 * Preset based on https://github.com/tailwindlabs/tailwindcss-container-queries
 */
const presetContainers = definePreset(
	/**
	 * @param {{ containers?: Record<string, string | number>}} [options={}]
	 */
	(options = {}) => {
		const defaultContainers = {
			'xs': '20rem' /* 320px */,
			'sm': '24rem' /* 384px */,
			'md': '28rem' /* 448px */,
			'lg': '32rem' /* 512px */,
			'xl': '36rem' /* 576px */,
			'2xl': '42rem' /* 672px */,
			'3xl': '48rem' /* 768px */,
			'4xl': '56rem' /* 896px */,
			'5xl': '64rem' /* 1024px */,
			'6xl': '72rem' /* 1152px */,
			'7xl': '80rem' /* 1280px */,
		};
		options.containers = {
			...defaultContainers,
			...Object.fromEntries(Object.entries(defaultContainers).map(e => [`h-${e[0]}`, e[1]])),
			...Object.fromEntries(Object.entries(defaultContainers).map(e => [`w-${e[0]}`, e[1]])),
			...options.containers,
		};
		/** @type {import('unocss').Preset} */
		const preset = {
			name: 'preset-containers',
			rules: [
				[/^@container(?:\/(\w+))?(?:-(normal|size))?$/, ([, l, v]) => {
					return {
						'container-type': v ?? 'inline-size',
						'container-name': l,
					}
				}],
			],
			variants: [
				{
					name: '@',
					match(matcher, ctx) {
						if (matcher.startsWith('@container')) {
							return matcher
						}
						const variant = variantGetParameter('@', matcher, ctx.generator.config.separators)
						if (variant) {
							const [match, rest, label] = variant;
							const unit = utils.bracket(match);

							/** @type {string | undefined } */
							let container;
							if (unit?.startsWith("h:")) {
								container = `(min-height: ${unit.replace('h:', '')})`
							} else if (unit?.startsWith("w:") || unit) {
								container = `(min-width: ${unit.replace('w:', '')})`
							} else {
								/** @type {string | number} */
								const size = options.containers?.[match] ?? '';
								container =
									`(${match.startsWith('h-') ? 'min-height' : 'min-width'}: ` +
									`${typeof size === 'number' ? `${size}px` : size})`
							}

							if (!container) {
								return
							}

							let order = (label ? 1000 : 2000) + Object.keys(options.containers ?? {}).indexOf(match);

							return {
								matcher: rest,
								handle: (input, next) => next({
									...input,
									parent: `${input.parent ? `${input.parent} $$` : ''}@container${label ? ` ${label} ` : ''}${container}`,
									parentOrder: order,
								}),
							}
						}
					},
					multiPass: true,
				}
			],
		}
		return preset;
	})

export default defineConfig({
	theme: {
		colors: {
			'black': '#000000',
			'white': '#ffffff',
			'light-gray': '#9c9c9c',
			'gray': '#383838',
			'dark-gray': '#0c0c0c',
			'mauve': '#cba6f7',
			'yellow': '#f9e2af',
		},
	},
	rules: [
		[
			'scrollbar',
			{
				'scrollbar-color': 'var(--un-scrollbar-thumb, #ddd) var(--un-scrollbar-track, #f5f5f5)',
			},
		],
		[
			/^(?:scrollbar-)?thumb-(?:color-)?(.+)$/,
			// @ts-expect-error
			colorResolver('--un-scrollbar-thumb', 'scrollbar-thumb'),
			{ autocomplete: 'scrollbar-thumb-$colors' },
		],
		[
			/^(?:scrollbar-)?track-(?:color-)?(.+)$/,
			// @ts-expect-error
			colorResolver('--un-scrollbar-track', 'scrollbar-thumb'),
			{ autocomplete: 'scrollbar-track-$colors' },
		],
	],
	cli: {
		entry: {
			patterns: [
				'./{components,layouts,pages}/*.templ',
				'./static/*.{js,html}',
			],
			outFile: './static/uno.css',
		},
	},
	presets: [
		presetForcedColors(),
		presetContainers(),
		presetIcons(),
		presetTypography(),
		presetUno(),
		presetWebFonts({
			provider: 'bunny',
			fonts: {
				sans: {
					name: 'Inter',
					provider: 'none'
				},
				cal: {
					name: 'Cal Sans',
					provider: 'none',
				},
				mono: {
					name: 'Fira Code',
					provider: 'none',
				},
			},
		}),
	],
	transformers: [
		transformerDirectives(),
		transformerVariantGroup(),
	],
});
