// ═══════════════════════════════════════════════════════════
// Modal → Learning Pipeline Integration
//
// Receives feedback from modal postMessage events,
// validates with Zod schemas, and feeds into the
// learning pipeline.
// ═══════════════════════════════════════════════════════════

import { ModalResponseSchema } from "../schemas/feedback.schema.js";
import type { ModalResponse, FeedbackEvent } from "../types/feedback.js";

/**
 * Convert a raw postMessage payload from a modal into a validated
 * ModalResponse. Returns null if validation fails.
 */
export function parseModalMessage(raw: unknown): {
  valid: true;
  response: ModalResponse;
} | {
  valid: false;
  error: string;
  details?: unknown;
} {
  if (!raw || typeof raw !== "object" || !("type" in raw)) {
    return { valid: false, error: "Not a valid modal message: missing type field" };
  }

  const msg = raw as Record<string, unknown>;

  // Only process factory_modal_response messages
  if (msg.type !== "factory_modal_response") {
    return { valid: false, error: `Not a feedback response: type=${msg.type}` };
  }

  const parsed = ModalResponseSchema.safeParse(raw);
  if (!parsed.success) {
    return {
      valid: false,
      error: "Modal response failed schema validation",
      details: parsed.error.issues.map((i) => ({
        path: i.path.join("."),
        message: i.message,
      })),
    };
  }

  return { valid: true, response: parsed.data as ModalResponse };
}

/**
 * Transform a validated ModalResponse into a FeedbackEvent
 * suitable for the learning pipeline's processFeedback() function.
 *
 * The caller must provide workProduct context since the modal
 * doesn't carry that information.
 */
export function modalResponseToFeedbackEvent(
  response: ModalResponse,
  context: {
    workProductType: "mcp_server" | "code_module" | "design" | "test_suite" | "documentation" | "pipeline_config";
    workProductId: string;
    workProductVersion: string;
    workProductSummary: string;
    pipelineStage?: string | null;
    mcpServerType?: string;
    bubaConfidence?: number;
  },
): FeedbackEvent {
  const now = new Date();
  const hour = now.getHours();

  const timeOfDay =
    hour >= 6 && hour < 12 ? "morning" as const :
    hour >= 12 && hour < 17 ? "afternoon" as const :
    hour >= 17 && hour < 21 ? "evening" as const :
    "night" as const;

  const days = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];

  return {
    id: crypto.randomUUID(),
    timestamp: response.timestamp,
    sessionId: response.sessionId,
    modalType: response.modalType,
    modalVersion: response.modalVersion,
    workProduct: {
      type: context.workProductType,
      id: context.workProductId,
      version: context.workProductVersion,
      summary: context.workProductSummary,
      bubaConfidence: context.bubaConfidence ?? 0.5,
      generationContext: {
        promptHash: "",
        memorySnapshot: [],
        modelUsed: "unknown",
        generationTimeMs: 0,
        iterationCount: 1,
      },
    },
    pipelineId: response.pipelineId || null,
    pipelineStage: (context.pipelineStage as FeedbackEvent["pipelineStage"]) ?? null,
    mcpServerType: context.mcpServerType,
    feedback: response.feedback,
    meta: {
      ...response.meta,
      timeOfDay,
      dayOfWeek: days[now.getDay()],
      sessionFatigue: 0,
      concurrentModals: 0,
    },
  };
}
