import React from "react";
import { css, cx } from "@emotion/css";
import { intersperse, sleep } from "../util";

// && is used to increase specificity to override global styles

// prettier-ignore
const opaque = css`&& { opacity: 1 }`;

// prettier-ignore
const halfVisible = css`&&& {opacity: 0.5}`;

// prettier-ignore
const opacities = [0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45].map(each => css`&&& { opacity: ${0.5 + each} }`);

const tripleBlink = async (el: HTMLElement) => {
	const delay = 150;

	await sleep(1000);
	el.classList.add(halfVisible);
	await sleep(delay);
	el.classList.remove(halfVisible);
	await sleep(delay);
	el.classList.add(halfVisible);
	await sleep(delay);
	el.classList.remove(halfVisible);
	await sleep(delay);
	el.classList.add(halfVisible);
	await sleep(delay * 2);
	el.classList.remove(halfVisible);
};

const Flicker: React.FC<{
	children: React.ReactNode;
	index: number;
	description: string;
	style?: React.CSSProperties;
}> = ({ children, index, description, style }) => {
	return (
		<span
			style={style}
			className={css`
				position: relative;

				&&& button:focus ~ .tooltip,
				&&& button:hover ~ .tooltip {
					opacity: 1;
				}

				&&& button:focus,
				&&& button:hover {
					opacity: 1;
				}
			`}>
			<button
				className={css`
					border-bottom: 1px dashed var(--text-colour);
					opacity: 0;
					background-color: transparent;
					border: none;
					color: inherit;
					position: relative;
					font-size: 0.9rem;
				`}
				ref={async el => {
					if (!el) return;

					await sleep(500);
					await sleep(300 * index);
					el.classList.add(opaque);

					await sleep(1000 + Math.random() * 1000);
					tripleBlink(el);

					while (true) {
						await sleep(5000 + Math.random() * 10000);
						const chosen =
							opacities[Math.floor(Math.random() * opacities.length)];
						el.classList.add(chosen);
						await sleep(2000);
						el.classList.remove(chosen);
						tripleBlink(el);
					}
				}}>
				{children}
			</button>
			<span
				className={cx(
					"tooltip",
					css`
						/* tooltip */
						position: absolute;
						top: 150%;
						left: 50%;
						transform: translateX(-50%);
						background: var(--card-tags);
						color: var(--text-colour);
						border-radius: 0.5rem;
						padding: 0.5rem 0.8rem;
						font-size: 0.8rem;
						min-width: 20rem;
						width: fit-content;
						max-width: 80vw;
						opacity: 0;
						transition: opacity 0.2s;
						user-select: none;
						text-align: left;
						pointer-events: none;

						@media screen and (max-width: 65rem) {
							position: fixed;
							top: unset;
							left: 1rem;
							transform: translateY(2rem);
						}
					`,
				)}>
				{description}
			</span>
		</span>
	);
};

const FlickerList: React.FC<{
	list: { text: string; description: string }[];
	style?: React.CSSProperties;
}> = ({ list, style }) => {
	return (
		<ul
			style={style}
			className={css`
				display: flex;
				flex-wrap: wrap;
				gap: 0.5rem;
				margin: 0;
				padding: 0;
				list-style: none;

				&:has(> li button:focus) li button:not(:focus),
				&:has(> li button:hover) li button:not(:hover) {
					opacity: 0.5;
				}

				/* any button that has a subsequent button focused, hide its tooltip */
				&&&& li:has(~ li button:focus) .tooltip,
				/* any button that has a previous button focused, hide its tooltip */
				&&&& li:has(button:focus) ~ li .tooltip {
					opacity: 0;
				}
			`}>
			{[
				...intersperse(
					list.map((item, index) => (
						<li
							key={item.text}
							className={css`
								display: inline-block;
							`}>
							<Flicker index={index} description={item.description}>
								{item.text}
							</Flicker>
						</li>
					)),
					index => <li key={index}>ยท</li>,
				),
			]}
		</ul>
	);
};

export default FlickerList;