import { For, createEffect, createSignal, onCleanup, onMount, type JSX } from "solid-js";
import { ChevronDown } from "../../../lib/icons";
import { useAppShellData } from "../data/app-shell.context";
import { type DepartmentItem } from "../data/shell.data";
import styles from "./DepartmentSelector.module.scss";

export const DepartmentSelector = (): JSX.Element => {
	const appShellData = useAppShellData();
	const [isOpen, setIsOpen] = createSignal(false);
	const [selectedDepartment, setSelectedDepartment] = createSignal<DepartmentItem>(appShellData.departmentItems()[0] ?? appShellData.activeDepartment());
	const [selectedTeamName, setSelectedTeamName] = createSignal(appShellData.activeDepartment().teamName);

	let rootRef: HTMLDivElement | undefined;

	createEffect(() => {
		const activeDepartment = appShellData.activeDepartment();
		const matchingDepartment = appShellData.departmentItems().find((item) => item.id === activeDepartment.id) ?? appShellData.departmentItems()[0];

		if (!matchingDepartment) {
			return;
		}

		setSelectedDepartment(matchingDepartment);
		setSelectedTeamName(activeDepartment.teamName || matchingDepartment.teams[0] || "");
	});

	onMount(() => {
		const handlePointerDown = (event: PointerEvent): void => {
			if (!isOpen()) return;
			if (!rootRef) return;

			const target = event.target;
			if (target instanceof Node && !rootRef.contains(target)) {
				setIsOpen(false);
			}
		};

		document.addEventListener("pointerdown", handlePointerDown);
		onCleanup(() => document.removeEventListener("pointerdown", handlePointerDown));
	});

	const selectDepartment = (item: DepartmentItem): void => {
		setSelectedDepartment(item);
		setSelectedTeamName(item.teams[0] ?? "");
	};

	const selectTeam = (teamName: string): void => {
		setSelectedTeamName(teamName);
		setIsOpen(false);
	};

	return (
		<div class={styles.root} ref={rootRef}>
			<button
				classList={{ [styles.selector]: true, [styles.selectorOpen]: isOpen() }}
				type="button"
				aria-label="Select department"
				title="Select department"
				aria-haspopup="menu"
				aria-expanded={isOpen()}
				onClick={() => setIsOpen((open) => !open)}
			>
				<span class={styles.copy}>
					<strong class={styles.value}>{selectedDepartment().name}</strong>
					<span class={styles.meta}>{selectedTeamName()}</span>
				</span>

				<ChevronDown classList={{ [styles.icon]: true, [styles.iconOpen]: isOpen() }} size={16} strokeWidth={2} />
			</button>

			{isOpen() ? (
				<div class={styles.menu} role="menu" aria-label="Department selector menu">
					<div class={styles.menuSection}>
						<span class={styles.menuSectionLabel}>Departments</span>

						<For each={appShellData.departmentItems()}>
							{(item): JSX.Element => (
								<button
									classList={{ [styles.menuItem]: true, [styles.menuItemActive]: item.id === selectedDepartment().id }}
									type="button"
									role="menuitemradio"
									aria-checked={item.id === selectedDepartment().id}
									onClick={() => selectDepartment(item)}
								>
									<div class={styles.menuItemCopy}>
										<strong class={styles.menuItemValue}>{item.name}</strong>
										<span class={styles.menuItemMeta}>{item.teams.length} teams</span>
									</div>
								</button>
							)}
						</For>
					</div>

					<div class={styles.menuDivider} aria-hidden="true" />

					<div class={styles.menuSection}>
						<span class={styles.menuSectionLabel}>Teams in {selectedDepartment().name}</span>

						<For each={selectedDepartment().teams}>
							{(teamName): JSX.Element => (
								<button
									classList={{ [styles.submenuItem]: true, [styles.submenuItemActive]: teamName === selectedTeamName() }}
									type="button"
									role="menuitemradio"
									aria-checked={teamName === selectedTeamName()}
									onClick={() => selectTeam(teamName)}
								>
									<span class={styles.submenuIndicator} aria-hidden="true" />
									<div class={styles.menuItemCopy}>
										<strong class={styles.menuItemValue}>{teamName}</strong>
									</div>
								</button>
							)}
						</For>
					</div>
				</div>
			) : null}
		</div>
	);
};
