import type { EntitySet } from "@sap-ux/vocabularies-types";
import CommonUtils from "sap/fe/core/CommonUtils";
import type PageController from "sap/fe/core/PageController";
import { blockAttribute, defineBuildingBlock } from "sap/fe/core/buildingBlocks/BuildingBlockSupport";
import RuntimeBuildingBlock from "sap/fe/core/buildingBlocks/RuntimeBuildingBlock";
import * as MetaModelConverter from "sap/fe/core/converters/MetaModelConverter";
import { Entity, UI } from "sap/fe/core/helpers/BindingHelper";
import { and, ifElse, not, pathInModel } from "sap/fe/core/helpers/BindingToolkit";
import type { PropertiesOf } from "sap/fe/core/helpers/ClassSupport";
import { defineReference } from "sap/fe/core/helpers/ClassSupport";
import type { Ref } from "sap/fe/core/jsx-runtime/jsx";
import { getSwitchDraftAndActiveVisibility } from "sap/fe/templates/ObjectPage/ObjectPageTemplating";
import Button from "sap/m/Button";
import ResponsivePopover from "sap/m/ResponsivePopover";
import type { SelectList$ItemPressEvent } from "sap/m/SelectList";
import SelectList from "sap/m/SelectList";
import type Event from "sap/ui/base/Event";
import type Control from "sap/ui/core/Control";
import InvisibleText from "sap/ui/core/InvisibleText";
import Item from "sap/ui/core/Item";
import type View from "sap/ui/core/mvc/View";
import type Context from "sap/ui/model/odata/v4/Context";

@defineBuildingBlock({ name: "DraftHandlerButton", namespace: "sap.fe.templates.ObjectPage.components" })
export default class DraftHandlerButtonBlock extends RuntimeBuildingBlock {
	private _containingView!: View;

	private popover?: ResponsivePopover;

	private readonly SWITCH_TO_DRAFT_KEY = "switchToDraft";

	private readonly SWITCH_TO_ACTIVE_KEY = "switchToActive";

	constructor(props: PropertiesOf<DraftHandlerButtonBlock>) {
		super(props);
	}

	@blockAttribute({ type: "string" })
	public id?: string;

	@blockAttribute({ type: "sap.ui.model.Context" })
	public contextPath?: Context;

	@defineReference()
	public switchToActiveRef!: Ref<Item>;

	@defineReference()
	public switchToDraftRef!: Ref<Item>;

	private initialSelectedKey: string = this.SWITCH_TO_ACTIVE_KEY;

	handleSelectedItemChange = (event: SelectList$ItemPressEvent): void => {
		const selectedItemKey = event.getParameter("item")?.getProperty("key");
		if (selectedItemKey !== this.initialSelectedKey) {
			(this._containingView.getController() as PageController).editFlow.toggleDraftActive(
				this._containingView.getBindingContext() as Context
			);
		}
		if (this.popover) {
			this.popover.close();
			this.popover.destroy();
			delete this.popover;
		}
	};

	openSwitchActivePopover = (event: Event) => {
		const sourceControl = event.getSource() as Control;
		const containingView = CommonUtils.getTargetView(sourceControl);

		const context: Context = containingView.getBindingContext() as Context;
		const isActiveEntity = context.getObject().IsActiveEntity;
		this.initialSelectedKey = isActiveEntity ? this.SWITCH_TO_ACTIVE_KEY : this.SWITCH_TO_DRAFT_KEY;
		this.popover = this.createPopover();

		this._containingView = containingView;
		containingView.addDependent(this.popover);
		this.popover.openBy(sourceControl);
		this.popover.attachEventOnce("afterOpen", () => {
			if (isActiveEntity) {
				this.switchToDraftRef.current?.focus();
			} else {
				this.switchToActiveRef.current?.focus();
			}
		});
		return this.popover;
	};

	createPopover(): ResponsivePopover {
		return (
			<ResponsivePopover
				showHeader={false}
				contentWidth={"15.625rem"}
				verticalScrolling={false}
				class={"sapUiNoContentPadding"}
				placement={"Bottom"}
			>
				<SelectList selectedKey={this.initialSelectedKey} itemPress={this.handleSelectedItemChange}>
					<Item
						text={"{sap.fe.i18n>C_COMMON_OBJECT_PAGE_DISPLAY_DRAFT_MIT}"}
						key={this.SWITCH_TO_DRAFT_KEY}
						ref={this.switchToDraftRef}
					/>
					<Item
						text={"{sap.fe.i18n>C_COMMON_OBJECT_PAGE_DISPLAY_SAVED_VERSION_MIT}"}
						key={this.SWITCH_TO_ACTIVE_KEY}
						ref={this.switchToActiveRef}
					/>
				</SelectList>
			</ResponsivePopover>
		);
	}

	getContent() {
		const entityset = MetaModelConverter.convertMetaModelContext(this.contextPath!) as EntitySet;
		const textValue = ifElse(
			and(not(UI.IsEditable), not(UI.IsCreateMode), Entity.HasDraft),
			pathInModel("C_COMMON_OBJECT_PAGE_SAVED_VERSION_BUT", "sap.fe.i18n"),
			pathInModel("C_COMMON_OBJECT_PAGE_DRAFT_BUT", "sap.fe.i18n")
		);
		const visible = getSwitchDraftAndActiveVisibility(entityset);
		return (
			<>
				<Button
					id="fe::StandardAction::SwitchDraftAndActiveObject"
					text={textValue}
					visible={visible}
					icon="sap-icon://navigation-down-arrow"
					iconFirst={false}
					type="Transparent"
					press={this.openSwitchActivePopover}
					ariaDescribedBy={["fe::StandardAction::SwitchDraftAndActiveObject::AriaTextDraftSwitcher"]}
				></Button>
				<InvisibleText
					text="{sap.fe.i18n>T_HEADER_DATAPOINT_TITLE_DRAFT_SWITCHER_ARIA_BUTTON}"
					id="fe::StandardAction::SwitchDraftAndActiveObject::AriaTextDraftSwitcher"
				/>
			</>
		);
	}
}
