import { useDataWithFilter } from "@olenbetong/appframe-react";
import { forwardRef, useImperativeHandle, useMemo, useState } from "react";
import { type DamagesRecord, dsDamagesDuplicateCheck } from "../../data";
import type { Element } from "../../ElementLookup";
import { DuplicateElementDamageDialog } from "./DublicateElementDamageDialog";

export { DuplicateElementDamageDialog } from "./DublicateElementDamageDialog";

export type DuplicateElementDamageHandle = {
	onClose: () => void;
	checkDuplicate: () => Promise<DamagesRecord[] | null>;
	record: DamagesRecord[];
};

type DuplicateElementDamageProps = {
	element: Element | null;
	/**
	 * External control of dialog visibility
	 */
	open?: boolean;
	onOpenChange?: (value: boolean) => void;
	/**
	 * Skip duplicate checking (used in edit mode)
	 */
	disableCheck?: boolean;
	/**
	 * Loading state for submit button
	 */
	loading?: boolean;
	/**
	 * Indicate if a link to the element damage form should be used
	 */
	linkToDamage?: boolean;
	/**
	 * Called when duplicate or duplicates are found
	 * @param record Array with all of the duplicate damages
	 * @returns void
	 */
	onDuplicateFound?: (record: DamagesRecord[]) => void;
	/**
	 * Called when user presses register anyway in dialog
	 * @returns void
	 */
	onRegisterAnyway?: () => void;
};

export const DuplicateElementDamage = forwardRef<DuplicateElementDamageHandle, DuplicateElementDamageProps>(
	function DuplicateElementDamage(
		{
			element,
			open: controlledOpen,
			onOpenChange,
			disableCheck = false,
			loading = false,
			linkToDamage = true,
			onRegisterAnyway,
		}: DuplicateElementDamageProps,
		ref,
	) {
		let [record, setRecord] = useState<DamagesRecord[]>([]);
		let [uncontrolledOpen, setUncontrolledOpen] = useState<boolean>(false);
		let open = controlledOpen === undefined ? uncontrolledOpen : controlledOpen;

		let whereClause = useMemo(() => {
			if (!element) {
				return "1=0";
			}
			return `Domain = '${element.Domain}' AND ElementID = '${element.ElementID}' AND ProjectID = '${element.ProjectID}'`;
		}, [element]);

		let duplicateRecord = useDataWithFilter(dsDamagesDuplicateCheck, whereClause, "whereClause");

		async function runDuplicateCheck(): Promise<DamagesRecord[] | null> {
			// If we are editing a record, we don't need to check for duplicates
			if (disableCheck) {
				return null;
			}

			if (duplicateRecord.length > 0) {
				setRecord(duplicateRecord);
				setUncontrolledOpen(true);

				return duplicateRecord;
			}

			return null;
		}

		function handleOpenChange(value: boolean) {
			setUncontrolledOpen(value);
			onOpenChange?.(value);
		}

		useImperativeHandle(ref, () => ({
			onClose: () => setUncontrolledOpen(false),
			checkDuplicate: () => runDuplicateCheck(),
			record: record,
		}));

		return (
			<DuplicateElementDamageDialog
				open={open}
				onClose={() => {
					setRecord([]);
					handleOpenChange(false);
				}}
				record={record}
				onRegisterAnyway={onRegisterAnyway ?? (() => {})}
				loading={loading ?? false}
				linkToDamage={linkToDamage}
			/>
		);
	},
);
