// app/(lib)/services/paymentService.ts
import { apiClient } from "../../app/api/client";

export interface PaymentPayload {
  user_id: number;
  gateway: string;
  amount: number;
  currency: string;
  email: string;
  registration_id?: string;
  class_id?: string;
  class_name?: string;
  fee_basis?: string;
  number_of_lessons?: number;
  frequency?: string;
  submitted_data?: Array<Record<string, string>>;
  save_card?: boolean;
}

export interface SetupPaymentPayload {
  user_id: number;
  email: string;
  registration_id: string;
  gateway: string;
  save_card?: boolean;
}

export interface PaymentResponse {
  status: boolean;
  message: string;
  data?: {
    payment_url?: string;
    transaction_id?: string;
    [key: string]: any;
  };
}

export interface StripeConnectContextResponse {
  status: boolean;
  message: string;
  data?: {
    stripe_account_id?: string | null;
  };
}

export class PaymentService {
  private readonly endpoint = "pay";
  private readonly setupEndpoint = "setup-pay";
  private readonly stripeConnectContextEndpoint = "stripe-connect-context";

  async initiatePayment(
    payload: PaymentPayload,
    domain: string
  ): Promise<PaymentResponse> {
    try {
      const response = await apiClient.post<PaymentResponse>(
        this.endpoint,
        payload,
        {
          headers: {
            "X-Domain": domain,
            "Content-Type": "application/json",
          },
        }
      );

      const data = response.data;
      if (!data?.status) {
        return {
          status: false,
          message: data?.message || "Failed to initiate payment",
        };
      }

      return data;
    } catch (error: any) {
      const backendMessage = error?.response?.data?.message;
      const message =
        backendMessage ||
        (error instanceof Error ? error.message : "Failed to initiate payment");

      return {
        status: false,
        message,
      };
    }
  }

  async setupPayment(
    payload: SetupPaymentPayload,
    domain: string
  ): Promise<PaymentResponse> {
    try {
      const response = await apiClient.post<PaymentResponse>(
        this.setupEndpoint,
        payload,
        {
          headers: {
            "X-Domain": domain,
            "Content-Type": "application/json",
          },
        }
      );

      const data = response.data;
      if (!data?.status) {
        return {
          status: false,
          message: data?.message || "Failed to setup payment",
        };
      }

      return data;
    } catch (error: any) {
      const backendMessage = error?.response?.data?.message;
      const message =
        backendMessage ||
        (error instanceof Error ? error.message : "Failed to setup payment");

      return {
        status: false,
        message,
      };
    }
  }

  async fetchStripeConnectContext(domain: string): Promise<StripeConnectContextResponse> {
    try {
      const response = await apiClient.get<StripeConnectContextResponse>(
        this.stripeConnectContextEndpoint,
        {
          headers: {
            "X-Domain": domain,
            Accept: "application/json",
          },
        }
      );

      const data = response.data;
      if (!data?.status) {
        return {
          status: false,
          message: data?.message || "Failed to load Stripe connect context",
        };
      }

      return data;
    } catch (error: unknown) {
      const backendMessage =
        error &&
        typeof error === "object" &&
        "response" in error &&
        (error as { response?: { data?: { message?: string } } }).response?.data?.message;

      return {
        status: false,
        message:
          (typeof backendMessage === "string" && backendMessage) ||
          (error instanceof Error ? error.message : "Failed to load Stripe connect context"),
      };
    }
  }
}

export const paymentService = new PaymentService();
