import * as types from './types.js';
import { CoreResponse as AbstractCoreResponse } from '../core_base/response.js';

/**
 * Deno implementation of Core Response class that wraps native fetch Response
 */
export class CoreResponse<T = any>
  extends AbstractCoreResponse<T>
  implements types.IDenoResponse<T>
{
  private response: Response;
  private responseClone: Response;

  // Public properties
  public readonly ok: boolean;
  public readonly status: number;
  public readonly statusText: string;
  public readonly headers: types.Headers;
  public readonly url: string;

  constructor(response: Response) {
    super();
    // Clone the response so we can read the body multiple times if needed
    this.response = response;
    this.responseClone = response.clone();

    this.ok = response.ok;
    this.status = response.status;
    this.statusText = response.statusText;
    this.url = response.url;

    // Convert Headers to plain object
    this.headers = {};
    response.headers.forEach((value, key) => {
      this.headers[key] = value;
    });
  }

  /**
   * Parse response as JSON
   */
  async json(): Promise<T> {
    this.ensureNotConsumed();
    try {
      return await this.response.json();
    } catch (error) {
      throw new Error(`Failed to parse JSON: ${error.message}`);
    }
  }

  /**
   * Get response as text
   */
  async text(): Promise<string> {
    this.ensureNotConsumed();
    return await this.response.text();
  }

  /**
   * Get response as ArrayBuffer
   */
  async arrayBuffer(): Promise<ArrayBuffer> {
    this.ensureNotConsumed();
    return await this.response.arrayBuffer();
  }

  /**
   * Get response as a readable stream (Web Streams API)
   */
  stream(): ReadableStream<Uint8Array> | null {
    this.ensureNotConsumed();
    return this.response.body;
  }

  /**
   * Get the raw Response object
   */
  raw(): Response {
    return this.responseClone;
  }
}
