/**
 * JSON-serializable `.withReasoning()` shape (no `synthesisStrategy` function).
 * @see ReasoningOptions in types.ts — encoded row + optional runtime strategy
 */
import { Schema } from "effect";
import {
  ReactiveConfigSchema,
  PlanExecuteConfigSchema,
  TreeOfThoughtConfigSchema,
  ReflexionConfigSchema,
  ReasoningStrategy,
} from "@reactive-agents/reasoning";

const StrategyIcsOverlaySchema = Schema.Struct({
  synthesis: Schema.optional(Schema.Literal("auto", "fast", "deep", "custom", "off")),
  synthesisModel: Schema.optional(Schema.String),
  synthesisProvider: Schema.optional(Schema.String),
  synthesisTemperature: Schema.optional(Schema.Number),
});

export const ReactiveStrategyBundleSchema = Schema.extend(ReactiveConfigSchema, StrategyIcsOverlaySchema);
export const PlanExecuteStrategyBundleSchema = Schema.extend(PlanExecuteConfigSchema, StrategyIcsOverlaySchema);
export const TreeOfThoughtStrategyBundleSchema = Schema.extend(TreeOfThoughtConfigSchema, StrategyIcsOverlaySchema);
export const ReflexionStrategyBundleSchema = Schema.extend(ReflexionConfigSchema, StrategyIcsOverlaySchema);

export const ReasoningStrategiesJsonSchema = Schema.partial(
  Schema.Struct({
    reactive: ReactiveStrategyBundleSchema,
    planExecute: PlanExecuteStrategyBundleSchema,
    treeOfThought: TreeOfThoughtStrategyBundleSchema,
    reflexion: ReflexionStrategyBundleSchema,
  }),
);

export const ReasoningOptionsJsonSchema = Schema.Struct({
  defaultStrategy: Schema.optional(ReasoningStrategy),
  strategies: Schema.optional(ReasoningStrategiesJsonSchema),
  adaptive: Schema.optional(
    Schema.Struct({
      enabled: Schema.optional(Schema.Boolean),
      learning: Schema.optional(Schema.Boolean),
    }),
  ),
  enableStrategySwitching: Schema.optional(Schema.Boolean),
  maxStrategySwitches: Schema.optional(Schema.Number),
  fallbackStrategy: Schema.optional(Schema.String),
  maxIterations: Schema.optional(Schema.Number),
  /** When false, tool calls from a single LLM response execute sequentially (debug/correctness mode). Default: true. */
  parallelToolCalls: Schema.optional(Schema.Boolean),
  /**
   * LLM-based observation fact extraction for large tool results.
   * - `true`: always extract for results exceeding compression budget
   * - `false`: never extract (default)
   * - `"auto"`: extract only for local/mid tiers when results exceed budget
   */
  observationSummary: Schema.optional(Schema.Union(Schema.Boolean, Schema.Literal("auto"))),
  /**
   * Opt-in — emit a per-tool-call rationale block (the model's "why") for
   * debrief audit. Default OFF: a cross-tier ablation showed the mandatory
   * rationale instruction is a pure speed/token tax with zero quality benefit
   * (qwen3:14b −27% latency / −20% output tokens; flat success). This is an
   * AUDIT feature, not a performance one. Threads to `KernelInput.auditRationale`,
   * read by the reactive think gate (env override: `RA_RATIONALE_AUDIT=1`).
   */
  auditRationale: Schema.optional(Schema.Boolean),
  synthesis: Schema.optional(Schema.Literal("auto", "fast", "deep", "custom", "off")),
  synthesisModel: Schema.optional(Schema.String),
  synthesisProvider: Schema.optional(Schema.String),
  synthesisTemperature: Schema.optional(Schema.Number),
});

export type ReasoningOptionsEncoded = typeof ReasoningOptionsJsonSchema.Type;
