import SearchIcon from "@mui/icons-material/Search";
import { IconButton, TextField } from "@mui/material";
import { getLocalizedString } from "@olenbetong/appframe-core";
import { type RefObject, useEffect, useImperativeHandle, useRef, useState } from "react";
import { type AddElement, ElementLookupDialog } from "./ElementLookupDialog";

export type Element = {
	Domain: string;
	PrimKey: string;
	ProjectID: string;
	ProjectName: string;
	ElementID: string | null;
};

export type ElementLookupHandle = {
	openDialog: () => void;
	closeDialog: () => void;
};

export type ElementLookupProps = {
	value?: Element | null;
	defaultValue?: Element | null;
	ref?: RefObject<ElementLookupHandle | null>;
	elementIDRequired?: boolean;
	openLookupDialogIcon?: boolean;
	onChange?: (value: Element | null) => void;
	onDialogChange?: (open: boolean) => void;
};

export function ElementLookup({
	value,
	defaultValue,
	ref,
	elementIDRequired = false,
	openLookupDialogIcon,
	onChange,
	onDialogChange,
}: ElementLookupProps) {
	let initializedRef = useRef<boolean>(false);

	let [openElementLookupDialog, setOpenElementLookupDialog] = useState<boolean>(false);
	let [element, setElement] = useState<Element | null>(defaultValue ?? null);
	let elementValue = value === undefined ? element : value;

	// biome-ignore lint: intentionally skipping "value" dependency as this shouldn't run when "value" changes
	useEffect(() => {
		if (initializedRef.current) {
			return;
		}

		if (value === undefined && defaultValue) {
			setElement(defaultValue);
			initializedRef.current = true;
		}
	}, [defaultValue]);

	useImperativeHandle(ref, () => ({
		openDialog: () => setOpenElementLookupDialog(true),
		closeDialog: () => setOpenElementLookupDialog(false),
	}));

	async function handleAddElement(addElement: AddElement) {
		onChange?.(addElement.element);
		setElement(addElement.element);
	}

	// biome-ignore lint: only run when openElementLookupDialog changes
	useEffect(() => {
		onDialogChange?.(openElementLookupDialog);
	}, [openElementLookupDialog]);

	return (
		<>
			<ElementLookupDialog
				open={openElementLookupDialog}
				mode="single"
				onClose={() => setOpenElementLookupDialog(false)}
				onAdd={handleAddElement}
				allowEmptyElement={!elementIDRequired}
			/>

			<input type="hidden" name="ProjectID" value={elementValue?.ProjectID ?? ""} />
			<input type="hidden" name="ElementRef" value={elementValue?.PrimKey ?? ""} />

			<TextField
				id="NewElementDamge_Project"
				value={elementValue ? `${elementValue.ProjectID}: ${elementValue.ProjectName}` : ""}
				label={getLocalizedString("Project")}
				fullWidth
				required
				autoComplete="off"
				slotProps={{ htmlInput: { readOnly: true } }}
			/>
			<TextField
				name="ElementID"
				id="NewElementDamage_ElementID"
				value={elementValue ? elementValue.ElementID : ""}
				label={getLocalizedString("Element ID")}
				fullWidth
				required={elementIDRequired}
				autoComplete="off"
				slotProps={{
					htmlInput: { readOnly: true },
					input: {
						endAdornment: openLookupDialogIcon ? (
							<IconButton onClick={() => setOpenElementLookupDialog(true)}>
								<SearchIcon />
							</IconButton>
						) : undefined,
					},
					inputLabel: { shrink: !!elementValue?.ElementID },
				}}
			/>
		</>
	);
}
