import { extractTriggersFromPoint } from "./extractTriggersFromPoint";

export function getConveyorSequencesInProduct(
    product: {
        productName: string;
        productId: string;
        eventDatas: EventsSchema[];
    }
): EventsSchema[][][] {  // Now returns array of array of arrays
    // Get all machine sequences for this product
    const machineSequences = determineExecutionMachineSequences([product]);

    const allConveyorSequences: EventsSchema[][][] = [];

    // Process each machine sequence separately
    for (const machineSequence of machineSequences) {
        const conveyorSequencesForThisMachineSequence: EventsSchema[][] = [];
        let currentConveyorSequence: EventsSchema[] = [];

        for (const event of machineSequence) {
            if (event.type === 'transfer') {
                // Add conveyor to current sequence
                currentConveyorSequence.push(event);
            } else if (event.type === 'vehicle') {
                // Vehicle encountered - split the sequence
                if (currentConveyorSequence.length > 0) {
                    conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]);
                    currentConveyorSequence = [];
                }
            }
            // Other machine types don't affect the conveyor sequence
        }

        // Add any remaining conveyors in the current sequence
        if (currentConveyorSequence.length > 0) {
            conveyorSequencesForThisMachineSequence.push([...currentConveyorSequence]);
        }

        if (conveyorSequencesForThisMachineSequence.length > 0) {
            allConveyorSequences.push(conveyorSequencesForThisMachineSequence);
        }
    }

    return allConveyorSequences;
}

// Helper function to get machine sequences (simplified from your example)
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] {
    const pointToEventMap = new Map<string, EventsSchema>();
    const allPoints: PointsScheme[] = [];

    // First pass: map points to their corresponding events
    products.forEach(product => {
        product.eventDatas.forEach(event => {
            if (event.type === 'transfer') {
                event.points.forEach(point => {
                    pointToEventMap.set(point.uuid, event);
                    allPoints.push(point);
                });
            } else if (
                event.type === 'vehicle' ||
                event.type === 'machine' ||
                event.type === 'storageUnit' ||
                event.type === 'roboticArm'
            ) {
                pointToEventMap.set(event.point.uuid, event);
                allPoints.push(event.point);
            }
        });
    });

    // Build dependency graph
    const dependencyGraph = new Map<string, string[]>();
    const triggeredPoints = new Set<string>();

    allPoints.forEach(point => {
        const triggers = extractTriggersFromPoint(point);
        const dependencies: string[] = [];

        triggers.forEach(trigger => {
            const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid;
            if (targetUuid && pointToEventMap.has(targetUuid)) {
                dependencies.push(targetUuid);
                triggeredPoints.add(targetUuid);
            }
        });

        dependencyGraph.set(point.uuid, dependencies);
    });

    // Find root points (points that aren't triggered by others)
    const rootPoints = allPoints.filter(point =>
        !triggeredPoints.has(point.uuid) &&
        dependencyGraph.get(point.uuid)?.length
    );

    const executionSequences: EventsSchema[][] = [];

    function buildSequence(startUuid: string): EventsSchema[] {
        const sequence: EventsSchema[] = [];
        const visited = new Set<string>();

        function traverse(uuid: string) {
            if (visited.has(uuid)) return;
            visited.add(uuid);

            const event = pointToEventMap.get(uuid);
            if (event && !sequence.includes(event)) {
                sequence.push(event);
            }

            const nextPoints = dependencyGraph.get(uuid) || [];
            nextPoints.forEach(nextUuid => traverse(nextUuid));
        }

        traverse(startUuid);
        return sequence;
    }

    // Build sequences from root points
    rootPoints.forEach(root => {
        executionSequences.push(buildSequence(root.uuid));
    });

    return executionSequences;
}