export class TimelineGenerator {
    generateQuarterlyView(roadmap, startQuarter, endQuarter) {
        const items = [];
        const startDate = this.parseQuarter(startQuarter);
        const endDate = this.parseQuarter(endQuarter);
        // Add themes
        for (const theme of roadmap.themes) {
            const themeStart = this.parseQuarter(theme.timeframe.startQuarter);
            const themeEnd = this.parseQuarter(theme.timeframe.endQuarter);
            // Only include themes that overlap with the view period
            if (themeEnd >= startDate && themeStart <= endDate) {
                items.push({
                    id: theme.id,
                    type: 'theme',
                    name: theme.name,
                    startDate: themeStart,
                    endDate: themeEnd,
                    status: theme.status,
                    dependencies: [],
                    progress: theme.metrics.progressPercentage
                });
            }
        }
        // Add milestones
        for (const milestone of roadmap.milestones) {
            if (milestone.date >= startDate && milestone.date <= endDate) {
                items.push({
                    id: milestone.id,
                    type: 'milestone',
                    name: milestone.name,
                    startDate: milestone.date,
                    endDate: milestone.date,
                    status: milestone.status,
                    dependencies: milestone.dependencies
                });
            }
        }
        // Sort by start date
        items.sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
        return {
            type: 'quarterly',
            startDate,
            endDate,
            items
        };
    }
    generateMonthlyView(roadmap, initiatives, features, startMonth, months) {
        const items = [];
        const endDate = new Date(startMonth);
        endDate.setMonth(endDate.getMonth() + months);
        // Add initiatives with estimated timelines
        for (const initiative of initiatives) {
            const estimatedStart = this.estimateInitiativeStart(initiative, roadmap);
            const estimatedEnd = this.estimateInitiativeEnd(initiative, estimatedStart);
            if (estimatedEnd >= startMonth && estimatedStart <= endDate) {
                items.push({
                    id: initiative.id,
                    type: 'initiative',
                    name: initiative.title,
                    startDate: estimatedStart,
                    endDate: estimatedEnd,
                    status: initiative.status,
                    dependencies: initiative.dependencies.map(d => d.targetId || '').filter(Boolean),
                    progress: this.calculateInitiativeProgress(initiative, features)
                });
            }
        }
        // Add features
        for (const feature of features) {
            const featureStart = this.estimateFeatureStart(feature, initiatives);
            const featureEnd = this.estimateFeatureEnd(feature, featureStart);
            if (featureEnd >= startMonth && featureStart <= endDate) {
                items.push({
                    id: feature.id,
                    type: 'feature',
                    name: feature.name,
                    startDate: featureStart,
                    endDate: featureEnd,
                    status: feature.status,
                    dependencies: [],
                    progress: feature.status === 'completed' ? 100 :
                        feature.status === 'in-progress' ? 50 : 0
                });
            }
        }
        // Add releases
        for (const release of roadmap.releases) {
            if (release.date >= startMonth && release.date <= endDate) {
                items.push({
                    id: release.id,
                    type: 'release',
                    name: `v${release.version}: ${release.name}`,
                    startDate: release.date,
                    endDate: release.date,
                    status: release.status,
                    dependencies: []
                });
            }
        }
        // Sort by start date
        items.sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
        return {
            type: 'monthly',
            startDate: startMonth,
            endDate,
            items
        };
    }
    generateReleaseView(roadmap, features) {
        const items = [];
        const now = new Date();
        // Group features by release
        const releaseGroups = new Map();
        for (const [_, feature] of features) {
            if (feature.targetRelease) {
                if (!releaseGroups.has(feature.targetRelease)) {
                    releaseGroups.set(feature.targetRelease, []);
                }
                releaseGroups.get(feature.targetRelease).push(feature);
            }
        }
        // Add releases with their features
        for (const release of roadmap.releases) {
            items.push({
                id: release.id,
                type: 'release',
                name: `v${release.version}: ${release.name}`,
                startDate: release.date,
                endDate: release.date,
                status: release.status,
                dependencies: [],
                progress: this.calculateReleaseProgress(release, releaseGroups.get(release.id) || [])
            });
            // Add features for this release
            const releaseFeatures = releaseGroups.get(release.id) || [];
            for (const feature of releaseFeatures) {
                const featureStart = new Date(release.date);
                featureStart.setMonth(featureStart.getMonth() - 3); // Assume 3 months development
                items.push({
                    id: feature.id,
                    type: 'feature',
                    name: feature.name,
                    startDate: featureStart,
                    endDate: release.date,
                    status: feature.status,
                    dependencies: [],
                    progress: feature.status === 'completed' ? 100 :
                        feature.status === 'in-progress' ? 50 : 0
                });
            }
        }
        // Sort by date
        items.sort((a, b) => a.startDate.getTime() - b.startDate.getTime());
        const startDate = items[0]?.startDate || now;
        const endDate = items[items.length - 1]?.endDate || now;
        return {
            type: 'release',
            startDate,
            endDate,
            items
        };
    }
    generateNowNextLaterView(roadmap, themes, initiatives, features) {
        const now = new Date();
        const nextQuarter = new Date(now);
        nextQuarter.setMonth(nextQuarter.getMonth() + 3);
        const laterDate = new Date(now);
        laterDate.setMonth(laterDate.getMonth() + 9);
        const items = [];
        // Categorize items into Now, Next, Later
        const categorizeByTiming = (startDate) => {
            if (startDate <= now)
                return 'now';
            if (startDate <= nextQuarter)
                return 'next';
            return 'later';
        };
        // Process themes
        for (const theme of roadmap.themes) {
            const themeStart = this.parseQuarter(theme.timeframe.startQuarter);
            const timing = categorizeByTiming(themeStart);
            items.push({
                id: theme.id,
                type: 'theme',
                name: `[${timing.toUpperCase()}] ${theme.name}`,
                startDate: timing === 'now' ? now :
                    timing === 'next' ? nextQuarter : laterDate,
                endDate: this.parseQuarter(theme.timeframe.endQuarter),
                status: theme.status,
                dependencies: [],
                progress: theme.metrics.progressPercentage
            });
        }
        // Process initiatives
        for (const [_, initiative] of initiatives) {
            const initiativeStart = this.estimateInitiativeStart(initiative, roadmap);
            const timing = categorizeByTiming(initiativeStart);
            items.push({
                id: initiative.id,
                type: 'initiative',
                name: `[${timing.toUpperCase()}] ${initiative.title}`,
                startDate: timing === 'now' ? now :
                    timing === 'next' ? nextQuarter : laterDate,
                endDate: this.estimateInitiativeEnd(initiative, initiativeStart),
                status: initiative.status,
                dependencies: initiative.dependencies.map(d => d.targetId || '').filter(Boolean),
                progress: 0
            });
        }
        // Group by timing for better visualization
        items.sort((a, b) => {
            // First sort by timing category
            const aCategory = a.name.startsWith('[NOW]') ? 0 :
                a.name.startsWith('[NEXT]') ? 1 : 2;
            const bCategory = b.name.startsWith('[NOW]') ? 0 :
                b.name.startsWith('[NEXT]') ? 1 : 2;
            if (aCategory !== bCategory)
                return aCategory - bCategory;
            // Then by type (themes first, then initiatives, then features)
            const typeOrder = { theme: 0, initiative: 1, feature: 2, milestone: 3, release: 4 };
            return typeOrder[a.type] - typeOrder[b.type];
        });
        return {
            type: 'now-next-later',
            startDate: now,
            endDate: laterDate,
            items
        };
    }
    // Helper methods
    parseQuarter(quarter) {
        const [q, year] = quarter.split(' ');
        const quarterNum = parseInt(q.substring(1));
        const yearNum = parseInt(year);
        const month = (quarterNum - 1) * 3;
        return new Date(yearNum, month, 1);
    }
    estimateInitiativeStart(initiative, roadmap) {
        // Find the theme this initiative belongs to
        const theme = roadmap.themes.find(t => t.initiatives.some(i => (typeof i === 'string' ? i : i.id) === initiative.id));
        if (theme) {
            return this.parseQuarter(theme.timeframe.startQuarter);
        }
        // Default to current date
        return new Date();
    }
    estimateInitiativeEnd(initiative, startDate) {
        const endDate = new Date(startDate);
        // Estimate based on effort
        const totalWeeks = initiative.effort.developmentWeeks +
            initiative.effort.designWeeks +
            initiative.effort.qaWeeks;
        endDate.setDate(endDate.getDate() + (totalWeeks * 7));
        return endDate;
    }
    estimateFeatureStart(feature, initiatives) {
        // Find the initiative this feature belongs to
        const initiative = initiatives.find(i => i.features.some(f => (typeof f === 'string' ? f : f.id) === feature.id));
        if (initiative) {
            // Return current date as we don't have the full roadmap context here
            return new Date();
        }
        return new Date();
    }
    estimateFeatureEnd(feature, startDate) {
        const endDate = new Date(startDate);
        // Estimate based on complexity
        const complexityWeeks = {
            'low': 2,
            'medium': 4,
            'high': 8,
            'very-high': 12
        };
        const weeks = complexityWeeks[feature.technicalComplexity];
        endDate.setDate(endDate.getDate() + (weeks * 7));
        return endDate;
    }
    calculateInitiativeProgress(initiative, features) {
        const initiativeFeatures = features.filter(f => initiative.features.some(initiativeFeature => (typeof initiativeFeature === 'string' ? initiativeFeature : initiativeFeature.id) === f.id));
        if (initiativeFeatures.length === 0)
            return 0;
        const completedCount = initiativeFeatures.filter(f => f.status === 'completed').length;
        return Math.round((completedCount / initiativeFeatures.length) * 100);
    }
    calculateReleaseProgress(release, features) {
        if (features.length === 0)
            return 0;
        const completedCount = features.filter(f => f.status === 'completed').length;
        return Math.round((completedCount / features.length) * 100);
    }
    // Generate Gantt chart data
    generateGanttData(timelineView) {
        return {
            tasks: timelineView.items.map((item, index) => ({
                id: item.id,
                name: item.name,
                start: item.startDate.toISOString(),
                end: item.endDate.toISOString(),
                progress: item.progress || 0,
                dependencies: item.dependencies,
                type: item.type,
                status: item.status,
                row: index
            })),
            viewStart: timelineView.startDate.toISOString(),
            viewEnd: timelineView.endDate.toISOString()
        };
    }
    // Critical path analysis
    findCriticalPath(items) {
        // Build dependency graph
        const graph = new Map();
        const itemMap = new Map();
        for (const item of items) {
            itemMap.set(item.id, item);
            graph.set(item.id, new Set(item.dependencies));
        }
        // Find items with no dependencies (start nodes)
        const startNodes = items.filter(item => item.dependencies.length === 0);
        // Calculate earliest start/finish times
        const earliestTimes = new Map();
        const calculateEarliestTimes = (itemId) => {
            if (earliestTimes.has(itemId)) {
                return earliestTimes.get(itemId);
            }
            const item = itemMap.get(itemId);
            const dependencies = Array.from(graph.get(itemId) || []);
            let earliestStart = item.startDate.getTime();
            if (dependencies.length > 0) {
                const depFinishTimes = dependencies.map(depId => {
                    const depTimes = calculateEarliestTimes(depId);
                    return depTimes.finish;
                });
                earliestStart = Math.max(...depFinishTimes);
            }
            const duration = item.endDate.getTime() - item.startDate.getTime();
            const earliestFinish = earliestStart + duration;
            earliestTimes.set(itemId, { start: earliestStart, finish: earliestFinish });
            return { start: earliestStart, finish: earliestFinish };
        };
        // Calculate for all items
        for (const item of items) {
            calculateEarliestTimes(item.id);
        }
        // Find the critical path (items with no slack)
        const criticalPath = [];
        // Implementation simplified - in production would need full CPM algorithm
        // For now, return the longest dependency chain
        let maxDuration = 0;
        let longestPath = [];
        const findLongestPath = (itemId, currentPath, currentDuration) => {
            currentPath.push(itemId);
            const item = itemMap.get(itemId);
            currentDuration += item.endDate.getTime() - item.startDate.getTime();
            const dependents = items.filter(i => i.dependencies.includes(itemId));
            if (dependents.length === 0) {
                if (currentDuration > maxDuration) {
                    maxDuration = currentDuration;
                    longestPath = [...currentPath];
                }
            }
            else {
                for (const dependent of dependents) {
                    findLongestPath(dependent.id, [...currentPath], currentDuration);
                }
            }
        };
        for (const startNode of startNodes) {
            findLongestPath(startNode.id, [], 0);
        }
        return longestPath;
    }
}
//# sourceMappingURL=timeline-generator.js.map