import { Connector, Item, StickyNote } from "@mirohq/websdk-types";

const getTypedMiroItem = async <T extends Item>(id: string, type: T['type']): Promise<T | undefined> => {
  const item = await miro.board.getById(id);
  return item?.type === type ? item as T : undefined;
};

interface ConnectorDirection {
  parentId?: string;
  childId?: string;
}

const getConnectorDirection = (connector: Connector): ConnectorDirection | undefined => {
  const hasEndArrow = connector.style.endStrokeCap !== 'none';
  const hasStartArrow = connector.style.startStrokeCap !== 'none';
  
  if (hasEndArrow && !hasStartArrow) {
    return { parentId: connector.start?.item, childId: connector.end?.item };
  }
  if (hasStartArrow && !hasEndArrow) {
    return { parentId: connector.end?.item, childId: connector.start?.item };
  }
  return;
};

export const getStickiesToChopInTree = async (root: StickyNote, removableColors: string[]): Promise<StickyNote[]> => {
  if (!removableColors.includes(root.style.fillColor)) return [];
  
  const toRemove: StickyNote[] = [];
  const visitedIds = new Set<string>();
  
  const traverseTree = async (node: StickyNote) => {
    if (visitedIds.has(node.id)){
      // prevent infinite loops of circular arrows
      return;
    }
    visitedIds.add(node.id);
    
    for (const connectorId of node.connectorIds || []) {
      const connector = await getTypedMiroItem<Connector>(connectorId, 'connector');
      if (!connector) continue;

      const direction = getConnectorDirection(connector);
      if (!direction || !direction.childId || direction.parentId !== node.id) continue;
      
      const childSticky = await getTypedMiroItem<StickyNote>(direction.childId, 'sticky_note');
      if (childSticky) {
        if (removableColors.includes(childSticky.style.fillColor)) {
          toRemove.push(childSticky);
        }
        await traverseTree(childSticky);
      }
    }
  };
  
  await traverseTree(root);
  return toRemove;
};