import { reactive, ref } from 'vue';

/**
 * Shared state for the element context menu (right-click on a canvas element or a navigator row).
 * The menu itself is rendered once by App.vue (panels/ContextMenu.vue); callers only open/close it.
 */
export type ContextMenuSource = 'canvas' | 'navigator';

export interface ContextMenuState {
  open: boolean;
  /** Shell (editor document) client coordinates. */
  x: number;
  y: number;
  id: string | null;
  source: ContextMenuSource;
}

export const contextMenu = reactive<ContextMenuState>({ open: false, x: 0, y: 0, id: null, source: 'canvas' });

export function openContextMenu(id: string, x: number, y: number, source: ContextMenuSource = 'canvas'): void {
  contextMenu.id = id;
  contextMenu.x = x;
  contextMenu.y = y;
  contextMenu.source = source;
  contextMenu.open = true;
}

export function closeContextMenu(): void {
  contextMenu.open = false;
  contextMenu.id = null;
}

/**
 * Rename requests are fulfilled by the navigator row of that element (inline input). The row watches
 * this ref, starts editing and resets it to null.
 */
export const renameRequest = ref<string | null>(null);

export function requestRename(id: string): void {
  renameRequest.value = id;
}

/**
 * Extra items contributed by features (components T168: "Save as component…", "Edit component", "Detach").
 * Providers are called with the right-clicked element each time the menu opens; items appear after the
 * clipboard / template group.
 */
export interface ContextMenuExtraItem {
  id: string;
  label: string;
  icon: string;
  hint?: string;
  disabled?: boolean;
  danger?: boolean;
  separator?: boolean;
  run: () => void | Promise<void>;
}

export type ContextMenuProvider = (id: string) => ContextMenuExtraItem[];

const providers = new Map<string, ContextMenuProvider>();

/** Registers (or replaces) a provider under a key. Returns an unregister function. */
export function registerContextMenuItems(key: string, provider: ContextMenuProvider): () => void {
  providers.set(key, provider);
  return () => {
    if (providers.get(key) === provider) providers.delete(key);
  };
}

export function extraContextMenuItems(id: string): ContextMenuExtraItem[] {
  const out: ContextMenuExtraItem[] = [];
  for (const provider of providers.values()) out.push(...provider(id));
  return out;
}
