import { logError, logInfo } from "@/lib/logger";
import { UpdotAuthManager } from "@/lib/updot-auth";
import type {
  CreateRCIBookingRequest,
  SendRCIUnitEDMRequest,
} from "./booking.schema";

export class BookingsService {
  private static instance: BookingsService | null = null;
  private externalApiUrl: string;

  private constructor(externalApiUrl?: string, internalApiUrl?: string) {
    this.externalApiUrl =
      externalApiUrl ??
      process.env.UPDOT_PROD_BASE_URL ??
      "https://uat.core.karmagroup.com";
  }

  static getInstance(externalApiUrl?: string) {
    if (!BookingsService.instance) {
      BookingsService.instance = new BookingsService(externalApiUrl);
    }
    return BookingsService.instance;
  }

  async createRCIBooking(
    request: CreateRCIBookingRequest,
  ): Promise<{ data: any; message: string }> {
    // ) {
    try {
      const endpoint = `${this.externalApiUrl}/v1/admin/bookings/externals/rci/create`;

      const authManager = UpdotAuthManager.getInstance();
      const session = await authManager.getOrLogin();
      if (!session) {
        throw new Error("Unable to obtain Updot core authentication session.");
      }

      const getHeaders = (sess: any) => {
        const cookies = [
          `admin_session=${sess.admin_session}`,
          `admin_session_id=${sess.admin_session_id}`,
          sess.admin_scopes ? `admin_scopes=${sess.admin_scopes}` : "",
        ]
          .filter(Boolean)
          .join("; ");

        return {
          "Content-Type": "application/json",
          Cookie: cookies,
        };
      };

      logInfo(
        `BookingsService.createRCIBooking: memberRecordID=${request.memberRecordID} -> ${endpoint}`,
      );

      console.log("endpoint", endpoint);
      console.log("Request body:\n", JSON.stringify(request, null, 2));

      const res = await fetch(endpoint, {
        method: "POST",
        headers: getHeaders(session),
        body: JSON.stringify(request),
      });

      const contentType = res.headers.get("content-type") || "";
      const raw = await res.text();

      const parsed =
        contentType.includes("application/json") && raw
          ? (() => {
              try {
                return JSON.parse(raw);
              } catch {
                return raw;
              }
            })()
          : raw;

      if (!res.ok) {
        logError(
          `BookingsService.createRCIBooking: Upstream failed (${res.status})`,
          parsed,
        );

        const err: any = new Error(
          typeof parsed === "string"
            ? parsed
            : parsed?.message || `Upstream failed with ${res.status}`,
        );
        err.status = res.status;
        err.detail = parsed;
        throw err;
      }
      console.log(parsed);

      return {
        data: parsed,
        message: "Booking created successfully",
      };
    } catch (e) {
      logError("BookingsService.createRCIBooking: error", e);
      throw e;
    }
  }

  async sendRCIUnitEDM(
    unitId: string,
    request: SendRCIUnitEDMRequest,
  ): Promise<{ data: any; message: string }> {
    try {
      const endpoint = `${this.externalApiUrl}/v1/admin/bookings/externals/rci/units/${unitId}`;

      const authManager = UpdotAuthManager.getInstance();
      const session = await authManager.getOrLogin();
      if (!session) {
        throw new Error("Unable to obtain Updot core authentication session.");
      }

      const getHeaders = (sess: any) => {
        const cookies = [
          `admin_session=${sess.admin_session}`,
          `admin_session_id=${sess.admin_session_id}`,
          sess.admin_scopes ? `admin_scopes=${sess.admin_scopes}` : "",
        ]
          .filter(Boolean)
          .join("; ");

        return {
          "Content-Type": "application/json",
          Cookie: cookies,
        };
      };

      logInfo(
        `BookingsService.sendRCIUnitEDM: unitId=${unitId}, memberRecordID=${request.memberRecordID} -> ${endpoint}`,
      );

      const res = await fetch(endpoint, {
        method: "POST",
        headers: getHeaders(session),
        body: JSON.stringify(request),
      });

      const contentType = res.headers.get("content-type") || "";
      const raw = await res.text();

      const parsed =
        contentType.includes("application/json") && raw
          ? (() => {
              try {
                return JSON.parse(raw);
              } catch {
                return raw;
              }
            })()
          : raw;

      if (!res.ok) {
        logError(
          `BookingsService.sendRCIUnitEDM: Upstream failed (${res.status})`,
          parsed,
        );

        const err: any = new Error(
          typeof parsed === "string"
            ? parsed
            : parsed?.message || `Upstream failed with ${res.status}`,
        );
        err.status = res.status;
        err.detail = parsed;
        throw err;
      }

      return {
        data: parsed,
        message: "EDM sent successfully",
      };
    } catch (e) {
      logError("BookingsService.sendRCIUnitEDM: error", e);
      throw e;
    }
  }
}
