/**
 * Pipeline Orchestrator — Coordinates the 6-stage feedback processing pipeline.
 *
 * Stages:
 * 1. Validate → Schema check, dedup, range validation
 * 2. Enrich   → Time categorization, NLP themes, sentiment, prediction delta
 * 3. Store    → Append to JSONL, update indexes
 * 4. Analyze  → Pattern detection, calibration, rule extraction
 * 5. Act      → Update memory files, adjust thresholds
 *
 * The pipeline is designed to fail gracefully: if analysis or action fail,
 * the validated + stored feedback is still preserved.
 */

import { validateFeedback } from "./validate.js";
import { enrichFeedback } from "./enrich.js";
import { storeFeedback } from "./store.js";
import { analyzeFeedback } from "./analyze.js";
import { applyLearnings } from "./act.js";
import type { PipelineResult, PipelineConfig } from "./types.js";
import { DEFAULT_PIPELINE_CONFIG } from "./types.js";
import { countStoredEvents } from "../storage/feedback-store.js";

/** Track events since last analysis run */
let eventsSinceLastAnalysis = 0;

/**
 * Process a single feedback event through the full pipeline.
 *
 * @param raw - Raw feedback data from the modal system
 * @param config - Pipeline configuration (uses defaults if omitted)
 * @returns Pipeline execution result with per-stage details
 */
export async function processFeedback(
  raw: unknown,
  config: Partial<PipelineConfig> = {}
): Promise<PipelineResult> {
  const cfg: PipelineConfig = { ...DEFAULT_PIPELINE_CONFIG, ...config };
  const start = Date.now();

  // ─── Stage 1: Validate ───
  const validateResult = validateFeedback(raw);
  if (!validateResult.valid || !validateResult.event) {
    return {
      success: false,
      stages: { validate: validateResult },
      processingTimeMs: Date.now() - start,
      error: validateResult.error?.message ?? "Validation failed",
    };
  }

  // ─── Stage 2: Enrich ───
  const enrichResult = enrichFeedback(validateResult.event);
  if (!enrichResult.success || !enrichResult.event) {
    return {
      success: false,
      stages: {
        validate: validateResult,
        enrich: enrichResult,
      },
      processingTimeMs: Date.now() - start,
      error: enrichResult.error ?? "Enrichment failed",
    };
  }

  // ─── Stage 3: Store ───
  const storeResult = await storeFeedback(enrichResult.event, cfg);
  if (!storeResult.success) {
    return {
      success: false,
      eventId: validateResult.event.id,
      stages: {
        validate: validateResult,
        enrich: enrichResult,
        store: storeResult,
      },
      processingTimeMs: Date.now() - start,
      error: storeResult.error ?? "Storage failed",
    };
  }

  eventsSinceLastAnalysis++;

  // ─── Stage 4: Analyze (conditional) ───
  // Run analysis if configured to run on every event, or if threshold reached
  const shouldAnalyze =
    cfg.analyzeOnEvery ||
    eventsSinceLastAnalysis >= cfg.analysisThreshold;

  let analyzeResult;
  let actResult;

  if (shouldAnalyze) {
    analyzeResult = await analyzeFeedback(cfg);
    eventsSinceLastAnalysis = 0;

    // ─── Stage 5: Act (only if analysis succeeded) ───
    if (analyzeResult.success && analyzeResult.results) {
      actResult = await applyLearnings(analyzeResult.results, cfg);
    }
  }

  return {
    success: true,
    eventId: validateResult.event.id,
    stages: {
      validate: validateResult,
      enrich: enrichResult,
      store: storeResult,
      analyze: analyzeResult,
      act: actResult,
    },
    processingTimeMs: Date.now() - start,
  };
}

/**
 * Force a full analysis + action cycle on all stored data.
 * Useful for recalibration or after bulk imports.
 */
export async function runFullAnalysis(
  config: Partial<PipelineConfig> = {}
): Promise<PipelineResult> {
  const cfg: PipelineConfig = { ...DEFAULT_PIPELINE_CONFIG, ...config };
  const start = Date.now();

  const analyzeResult = await analyzeFeedback(cfg);
  let actResult;

  if (analyzeResult.success && analyzeResult.results) {
    actResult = await applyLearnings(analyzeResult.results, cfg);
  }

  return {
    success: analyzeResult.success,
    stages: {
      validate: { valid: true },
      analyze: analyzeResult,
      act: actResult,
    },
    processingTimeMs: Date.now() - start,
  };
}

/**
 * Get the count of events since last analysis.
 */
export function getEventsSinceLastAnalysis(): number {
  return eventsSinceLastAnalysis;
}

export { validateFeedback } from "./validate.js";
export { enrichFeedback } from "./enrich.js";
export { storeFeedback } from "./store.js";
export { analyzeFeedback } from "./analyze.js";
export { applyLearnings } from "./act.js";
export type {
  PipelineResult,
  PipelineConfig,
  ValidationResult,
  EnrichmentResult,
  StorageResult,
  AnalysisResult,
  ActionResult,
} from "./types.js";
