import { BestAgentError } from "@best-agent/foundation";
import { structuredActionRequiredObservation } from "./runtime-observation.js";
import { handleProviderControlLeakResponse } from "./provider-control-leak-response-handler.js";
import { validateProviderResponseFinalAnswer } from "./provider-final-answer-handler.js";
import type { ProviderResponseHandlerInput } from "./provider-response-handler-types.js";

export async function handleProviderResponse(input: ProviderResponseHandlerInput): Promise<string> {
  const controlLeakResponse = await handleProviderControlLeakResponse(input);
  if (controlLeakResponse !== undefined) {
    return controlLeakResponse;
  }
  if (input.controls.allowPlanUpdate) {
    return repairStructuredActionRequired(input);
  }
  if (input.controls.allowPhaseResult) {
    return repairStructuredActionRequired(input);
  }
  if (!input.actionPolicy.directResponseAllowed) {
    return repairStructuredActionRequired(input);
  }
  const finalValidation = validateProviderResponseFinalAnswer({
    availableTools: input.availableTools,
    messages: input.messages,
    objective: input.objective,
    text: input.decision.text,
  });
  if (!finalValidation.ok) {
    input.runtime.markDecisionOutcome(input.decision, {
      runtimeOutcome: "failed",
      validation: {
        message: finalValidation.observation.message,
        reasonCode: "final-answer-unsupported",
      },
    });
    throw new BestAgentError("PROVIDER_DECISION_INVALID", finalValidation.observation.message);
  }
  input.runtime.markDecisionOutcome(input.decision, { runtimeOutcome: "accepted" });
  return input.decision.text;
}

async function repairStructuredActionRequired(
  input: ProviderResponseHandlerInput,
): Promise<string> {
  const observation = structuredActionRequiredObservation({
    actionPolicy: input.actionPolicy,
    responseText: input.decision.text,
  });
  input.runtime.markDecisionOutcome(input.decision, {
    runtimeOutcome: "failed",
    validation: {
      message: observation.message,
      reasonCode: "structured-action-required",
    },
  });
  throw new BestAgentError("PROVIDER_DECISION_INVALID", observation.message);
}
