export const parseResponse = async (response: BedrockResponse) => {
  let completeBody: string;

  if (
    typeof response === "object" &&
    response !== null &&
    "body" in response &&
    typeof (response as any).body !== "undefined" &&
    typeof (response as any).body[Symbol.asyncIterator] === "function"
  ) {
    // In Node.js, response.body is an async iterable stream.
    const chunks: Uint8Array[] = [];
    for await (const chunk of response.body as AsyncIterable<Uint8Array>) {
      chunks.push(chunk as Uint8Array);
    }

    completeBody = Buffer.concat(chunks).toString("utf-8");
  } else {
    completeBody = new TextDecoder("utf-8").decode(response.body as any);
  }

  return completeBody;
};

export const cleanJsonEnclosure = (str: string): string => {
  return str.replace(/```json/g, "").replace(/```/g, "").trim();
};

export const cleanMarkdownEnclosure = (str: string): string => {
  return str.replace(/```markdown/g, "").replace(/```/g,"").trim();
}

export const isValidJsonObject = (obj: any): boolean => {
  return obj !== undefined && obj !== null && Object.keys(obj).length > 0;
}

export function cleanAndParseJSON(input: string): any {
  try {
    return JSON.parse(input);
  } catch (error) {
    const match = input.match(/({.*})/s);
    if (match) {
      try {
        return JSON.parse(match[1]); // Extract and parse only the valid JSON part
      } catch (innerError) {
        console.error("Failed to parse cleaned JSON:", innerError);
      }
    }
    console.error("Invalid JSON:", error);
    return null;
  }
}

export const getMessageText = (message: any) => {
  let outputMessage: any = "";

  if (message && !Array.isArray(message)) {
   outputMessage = message.text ?? message;
  } else {
    outputMessage = message[0].text ?? message[0];
  }

  outputMessage = cleanJsonEnclosure(outputMessage);
  outputMessage = cleanAndParseJSON(outputMessage);

  return outputMessage;
};

export const extractMarkdownContent = (input: string): string => {
  // The regex captures all text after "### Markdown Output" until it encounters "### JSON Output"
  const markdownRegex = /###(\s\S)?.?(\s)(\*\*)?Markdown Output(\*\*)?\s*([\s\S]*?)(?=\s*###(\s\S)?.?(\s)(\*\*)?JSON Output(\*\*)?)/;
  const match = input.match(markdownRegex);
  
  if (match) {
    return match[0].trim() ?? match[1].trim();
  } else {
    console.log('-----', input);
    console.error("Markdown content not found in the input.");
    return '';
  }
}

export function extractJsonContent(input: string): string {
  // This regex matches the text after "### JSON Output" within a JSON code block demarcated by triple-backticks.
  const jsonRegex = /###(\s\S)?.?(\s)(\*\*)?JSON Output(\*\*)?\s*```json\s*([\s\S]*?)\s*```/;
  const match = input.match(jsonRegex);

  if (match) {
    return match[0].trim() ?? match[1].trim();
  } else {
    console.error("JSON content not found in the input.");
    return '';
  }
}

export interface BedrockResponse {
  body?: AsyncIterable<Uint8Array>;
  [key: string]: any;
}
