import * as stylex from "@stylexjs/stylex";
import { createElement, memo } from "react";
import { Link } from "react-router";
import { controlColor } from "./theme.stylex";
import { color, markColor, size } from "./tokens.stylex";

export type UserLinkStyle = "theme" | "plain";

export interface UserNameProps {
	/** @remarks We use a `string` instead of `api.UserName` because we don't want to pull in API types into the dependencies of this component. */
	name: string;
	/** Undefined means no link. Otherwise, the link style. */
	linkStyle?: UserLinkStyle | undefined;
	/** @remarks We use a `number` instead of `api.UserMark` because we don't want to pull in API types into the dependencies of this component. */
	mark?: number;
	isOp?: boolean;
}

export default memo(UserName);

const styles = stylex.create({
	userName: {
		display: "inline-flex",

		// Not using size units here, because we want the size to be oriented along the font
		gap: "0.125em",
		alignItems: "center",
	},
	plain: {
		color: color.white900,
	},
	mark: {
		"::after": {
			content: "''",
			// Not using size units here, because we want the size to be oriented along the font of the parent			content: "''",
			width: "0.55em",
			height: "0.55em",
			marginLeft: "0.3em",

			pointerEvents: "none",
			userSelect: "none",
			touchAction: "none",

			maskImage: "var(--mark-shape-default)",

			maskSize: "contain",
			maskRepeat: "no-repeat",
			maskPosition: "center",
		},
	},
	op: {
		"::before": {
			content: "'OP'",
			borderRadius: size.px0_5,
			color: controlColor.buttonPrimaryColor,

			backgroundColor: controlColor.buttonPrimaryBackground,
			paddingBlock: 0,
			paddingInline: size.rem1,
			fontSize: "60%",

			pointerEvents: "none",
			userSelect: "none",
			touchAction: "none",
		},
	},
});

// Old unicode shapes:
// $default-shape: "\25CF";
// SCSS map:
// $shapes: (
//   "legend": "\25C6",
//   "special": "\25A7",
//   "helper": "\2764",
// );

const markSpecificStyles = stylex.create({
	0: {
		// none
		"::after": {
			backgroundColor: markColor[0],
		},
	},
	1: {
		// newfag
		"::after": {
			backgroundColor: markColor[1],
		},
	},
	2: {
		// oldfag
		"::after": {
			backgroundColor: markColor[2],
		},
	},
	3: {
		// admin
		"::after": {
			backgroundColor: markColor[3],
		},
	},
	4: {
		// banned
		"::after": {
			backgroundColor: markColor[4],
		},
	},
	5: {
		// mod
		"::after": {
			backgroundColor: markColor[5],
		},
	},
	6: {
		// superfag
		"::after": {
			backgroundColor: markColor[6],
		},
	},
	7: {
		// legend
		"::after": {
			backgroundColor: markColor[7],
			maskImage: "var(--mark-shape-legend)",
		},
	},
	8: {
		// special
		"::after": {
			backgroundColor: markColor[8],
			maskImage: "var(--mark-shape-special)",
		},
	},
	9: {
		// paid
		"::after": {
			backgroundColor: markColor[9],
		},
	},
	10: {
		// mediumfag
		"::after": {
			backgroundColor: markColor[10],
		},
	},
	11: {
		// oldmod
		"::after": {
			backgroundColor: markColor[11],
		},
	},
	12: {
		// helper
		"::after": {
			backgroundColor: markColor[12],
			maskImage: "var(--mark-shape-helper)",
		},
	},
	13: {
		// bot
		"::after": {
			backgroundColor: markColor[13],
		},
	},
	14: {
		// sysbot
		"::after": {
			backgroundColor: markColor[14],
		},
	},
	15: {
		// oldhelper
		"::after": {
			backgroundColor: markColor[15],
		},
	},
	16: {
		// team-blue
		"::after": {
			backgroundColor: markColor[16],
		},
	},
	17: {
		// team-red
		"::after": {
			backgroundColor: markColor[17],
		},
	},
});

function UserName({ name, isOp, linkStyle, mark }: UserNameProps) {
	const p = stylex.props(
		styles.userName,
		isOp && styles.op,
		typeof mark === "number" && styles.mark,
		typeof mark === "number" &&
			markSpecificStyles[mark as keyof typeof markSpecificStyles],
		linkStyle === "plain" && styles.plain,
	);

	return linkStyle === undefined ? (
		createElement("span", p, name)
	) : (
		<Link to={`/user/${name}`} {...p}>
			{name}
		</Link>
	);
}
