/**
 * PR-37 Delivery Planning — Entry Point
 *
 * Parts F, G, H, I:
 *   - F: Sprint Planner
 *   - G: Release Planner
 *   - H: Batch Planner
 *   - I: Capacity Planner
 *
 * Consumes SF-02 Requirement Package output and generates delivery
 * planning artifacts. Compatible with PR-36 Factory Registry.
 *
 * @module pr-37-delivery-planning
 * @since PR-37
 */

import { generateSprintPlan, defaultSprintConfig } from "./sprint-planner.mjs";
import { generateReleasePlan } from "./release-planner.mjs";
import { generateBatchPlan } from "./batch-planner.mjs";
import { generateCapacityPlan, defaultCapacityConfig } from "./capacity-planner.mjs";

import { alignRoadmapWithPlans } from "./roadmap-aligner.mjs";

// ═══════════════════════════════════════════════════════
// PR-37 Artifact Constants
// ═══════════════════════════════════════════════════════

export const PR37_ARTIFACTS = Object.freeze({
  SPRINT_PLAN:      "sprint-plan",
  RELEASE_PLAN:     "release-plan",
  BATCH_PLAN:       "batch-plan",
  CAPACITY_PLAN:    "capacity-plan",
  ALIGNMENT_REPORT: "alignment-report",
});

// ═══════════════════════════════════════════════════════
// Factory Integration
// ═══════════════════════════════════════════════════════

/**
 * Create a delivery planning factory that consumes SF-02 upstream artifacts
 * and produces all 4 delivery plans.
 *
 * The factory accepts a PR-36 FactoryInput object (or a simplified upstream
 * artifacts object) and returns all plans bundled as a FactoryOutput.
 *
 * @param {object} upstreamArtifacts — SF-02 output containing:
 *   - epics: object[]
 *   - features: object[]
 *   - userStories: object[]
 *   - dependencies / graph: dependency graph
 *   - priorities: priority matrix entries
 *   - mvpScope: MVP scope definition
 * @param {object} [config] — Optional config overrides
 * @param {object} [config.sprint] — Sprint planner config
 * @param {object} [config.capacity] — Capacity planner config
 * @returns {object} FactoryOutput with all delivery plans
 *
 * @example
 * ```js
 * const factory = createDeliveryPlanningFactory();
 * const output = factory(sf02Output, {
 *   sprint: { teamVelocity: 20, maxStoryPointsPerSprint: 25 },
 *   capacity: { teamSize: 5, availabilityFactor: 0.8 },
 * });
 * // output.sprintPlan, output.releasePlan, output.batchPlan, output.capacityPlan
 * ```
 */
export function createDeliveryPlanningFactory(upstreamArtifacts, config = {}) {
  if (!upstreamArtifacts) {
    return {
      factoryId: "PR-37",
      status: "failed",
      error: "No upstream artifacts provided. Provide SF-02 output.",
    };
  }

  const warnings = [];

  // ── 1. Extract SF-02 artifacts ──
  const stories = upstreamArtifacts.userStories || upstreamArtifacts.stories || [];
  const epics = upstreamArtifacts.epics || [];
  const features = upstreamArtifacts.features || [];

  // Support both { graph: { nodes, edges } } and flat { nodes, edges }
  const dependencies = upstreamArtifacts.dependencies
    || upstreamArtifacts.graph
    || { nodes: [], edges: [] };

  const priorities = upstreamArtifacts.priorities || [];
  const mvpScope = upstreamArtifacts.mvpScope || null;

  // ── 2. Validate data ──
  if (stories.length === 0) {
    warnings.push("No user stories found in upstream artifacts");
  }

  // ── 3. Generate Sprint Plan (Part F) ──
  const sprintConfig = defaultSprintConfig(config.sprint || {});
  const sprintPlan = generateSprintPlan({
    stories,
    dependencies,
    priorities,
    config: sprintConfig,
  });

  if (sprintPlan.warnings && sprintPlan.warnings.length > 0) {
    warnings.push(...sprintPlan.warnings.map(w => `[Sprint] ${w}`));
  }

  // ── 4. Generate Release Plan (Part G) ──
  const releasePlan = generateReleasePlan({
    mvpScope,
    priorities,
    dependencies,
    stories,
    epics,
    features,
  });

  if (releasePlan.warnings && releasePlan.warnings.length > 0) {
    warnings.push(...releasePlan.warnings.map(w => `[Release] ${w}`));
  }

  // ── 5. Generate Batch Plan (Part H) ──
  const batchPlan = generateBatchPlan({
    stories,
    dependencies,
    priorities,
    sprints: sprintPlan,
    releases: releasePlan,
  });

  if (batchPlan.warnings && batchPlan.warnings.length > 0) {
    warnings.push(...batchPlan.warnings.map(w => `[Batch] ${w}`));
  }

  // ── 6. Generate Capacity Plan (Part I) ──
  const capacityConfig = defaultCapacityConfig(config.capacity || {});
  const capacityPlan = generateCapacityPlan({
    sprints: sprintPlan,
    releases: releasePlan,
    config: capacityConfig,
  });

  if (capacityPlan.warnings && capacityPlan.warnings.length > 0) {
    warnings.push(...capacityPlan.warnings.map(w => `[Capacity] ${w}`));
  }

  // ── 7. Align with Roadmap (Part J) ──
  const roadmap = upstreamArtifacts.roadmap || mvpScope?.phases;
  const alignmentReport = roadmap
    ? alignRoadmapWithPlans({
        roadmap: { phases: Array.isArray(roadmap) ? roadmap : (roadmap.phases || []) },
        sprintPlan,
        releasePlan,
        batchPlan,
        mvpScope,
      })
    : null;

  // ── 8. Assemble output ──
  const output = {
    factoryId: "PR-37",
    status: warnings.length > 0 && stories.length === 0 ? "blocked" : "passed",
    sprintPlan,
    releasePlan,
    batchPlan,
    capacityPlan,
    alignmentReport,
    warnings: warnings.length > 0 ? warnings : undefined,
    metadata: {
      factoryId: "PR-37",
      upstreamArtifactId: upstreamArtifacts.id || "SF-02",
      generatedAt: new Date().toISOString(),
      totalStories: stories.length,
      totalEpics: epics.length,
      totalFeatures: features.length,
      totalSprints: sprintPlan.metrics.totalSprints,
      totalReleases: releasePlan.releases ? releasePlan.releases.length : 0,
    },
  };

  return output;
}

// ═══════════════════════════════════════════════════════
// Barrel Re-exports
// ═══════════════════════════════════════════════════════

export { generateSprintPlan, defaultSprintConfig } from "./sprint-planner.mjs";
export { generateReleasePlan } from "./release-planner.mjs";
export { generateBatchPlan } from "./batch-planner.mjs";
export { generateCapacityPlan, defaultCapacityConfig } from "./capacity-planner.mjs";
export { alignRoadmapWithPlans } from "./roadmap-aligner.mjs";
