import type {
  AudioFrame,
  VoiceProvider,
  VoiceProviderConnectInput,
  VoiceProviderSession,
  VoiceProviderKind,
} from "./types.ts";

export class FakeVoiceProvider implements VoiceProvider {
  readonly kind: VoiceProviderKind;

  constructor(kind: VoiceProviderKind = "openai_realtime") {
    this.kind = kind;
  }

  async connect(input: VoiceProviderConnectInput): Promise<VoiceProviderSession> {
    return new FakeVoiceSession(this.kind, input);
  }
}

class FakeVoiceSession implements VoiceProviderSession {
  readonly provider: VoiceProviderKind;
  readonly sessionId: string;

  constructor(
    provider: VoiceProviderKind,
    private readonly input: VoiceProviderConnectInput,
  ) {
    this.provider = provider;
    this.sessionId = input.callId;
  }

  async sendAudio(_frame: AudioFrame): Promise<void> {
    const text = new TextDecoder().decode(_frame.data).trim();
    if (text) await this.sendText(text);
  }

  async sendText(text: string): Promise<void> {
    await this.input.events.onTranscript?.({
      role: "caller",
      text,
      isFinal: true,
    });
    await this.respondToText(text);
  }

  async sendToolResult(toolCallId: string, result: unknown): Promise<void> {
    await this.input.events.onTranscript?.({
      role: "agent",
      text: `Tool ${toolCallId} returned ${JSON.stringify(result)}`,
      isFinal: true,
    });
  }

  async interrupt(): Promise<void> {}

  async close(reason?: string): Promise<void> {
    await this.input.events.onClose?.(reason);
  }

  private async respondToText(text: string): Promise<void> {
    const lower = text.toLowerCase();
    if (lower.includes("chest pain") || lower.includes("urgent")) {
      await this.input.events.onToolCall?.({
        id: "tool-escalate",
        name: "assess_escalation",
        arguments: { text },
      });
      return;
    }
    if (lower.includes("reschedule")) {
      await this.input.events.onToolCall?.({
        id: "tool-options",
        name: "find_reschedule_options",
        arguments: { patient_id: "test-patient", appointment_id: "test-appointment" },
      });
      return;
    }

    await this.input.events.onTranscript?.({
      role: "agent",
      text: "I can help with low-risk rescheduling after verification.",
      isFinal: true,
    });
  }
}
