// Import dependencies for internal use
import { createClient, ApiError } from "./runtime/client";
import { getApiErrorMessage } from "./runtime/error-message";
import { logger } from "@/core/logger";
import { emitUnauthorized } from "./unauthorized";

export { createClient, resolveBaseUrl } from "./runtime/client";
export type {
  ApiClient,
  AuthHeaderResolver,
  CreateClientOptions,
  QueryParams,
  PathParams,
} from "./runtime/client";
export { ApiError, isApiError } from "./runtime/client";
export { onUnauthorized } from "./unauthorized";

// Re-export API helpers
export * from "./response-helpers";

/**
 * Auth endpoints that should NOT trigger automatic logout on 401
 * These are endpoints where 401 means "invalid credentials" or is handled by the auth flow itself
 */
const AUTH_ENDPOINTS = [
  "/api/auth/login",
  "/api/auth/signup",
  "/api/auth/set-password",
  "/api/auth/reset-password",
  "/api/auth/check-password-needed",
  "/api/auth/me", // Auth check endpoint - handled by refreshUser flow
  "/api/auth/refresh", // Refresh endpoint - handled by refreshSession flow
  "/api/me", // Profile endpoint - handled by refreshUser flow
];

/**
 * Check if a URL path is an auth endpoint
 */
function isAuthEndpoint(url: string): boolean {
  try {
    const urlPath = new URL(url).pathname;
    return AUTH_ENDPOINTS.some(endpoint => urlPath.endsWith(endpoint));
  } catch {
    return AUTH_ENDPOINTS.some(endpoint => url.includes(endpoint));
  }
}

/**
 * Global error handler for API client
 * Handles authentication errors and triggers logout when needed
 */
async function handleApiError(response: Response): Promise<void> {
  // Don't import useAuthStore at module level to avoid circular dependencies
  // We'll handle auth errors by dispatching a custom event that the auth system can listen to

  // Only dispatch logout event for 401s on non-auth endpoints
  // Auth endpoints (login, signup, etc.) return 401 for invalid credentials,
  // which should NOT trigger logout - just show the error message
  if (response.status === 401 && !isAuthEndpoint(response.url)) {
    logger.warn("Received 401 Unauthorized response - triggering logout");

    emitUnauthorized({ url: response.url, status: response.status });
  }

  // Still throw the error so the calling code can handle it
  let body: unknown;
  let message = response.statusText || `Request failed with status ${response.status}`;

  try {
    const cloned = response.clone();
    const contentType = cloned.headers.get("content-type");
    if (contentType?.includes("application/json")) {
      body = await cloned.json();
      const extractedMessage = getApiErrorMessage(body);
      if (extractedMessage) {
        message = extractedMessage;
      }
    }
  } catch {
    // Ignore body parse errors
  }

  throw new ApiError(message, response, body);
}

export const apiClient = createClient({
  handleError: handleApiError,
});

// Query keys for React Query - matching the expected structure
export const queryKeys = {
  auth: {
    me: () => ["auth", "me"] as const,
    session: () => ["auth", "session"] as const,
  },
  me: {
    status: () => ["me", "status"] as const,
  },
  billing: {
    invoices: (params?: Record<string, unknown>) => ["billing", "invoices", params] as const,
    invoice: (id: string) => ["billing", "invoice", id] as const,
    paymentMethods: () => ["billing", "payment-methods"] as const,
  },
  subscriptions: {
    all: () => ["subscriptions"] as const,
    list: (params?: Record<string, unknown>) => ["subscriptions", "list", params] as const,
    active: () => ["subscriptions", "active"] as const,
    stats: () => ["subscriptions", "stats"] as const,
    detail: (id: string) => ["subscriptions", "detail", id] as const,
    invoices: (id: number, params?: Record<string, unknown>) =>
      ["subscriptions", "invoices", id, params] as const,
  },
  dashboard: {
    summary: () => ["dashboard", "summary"] as const,
  },
  services: {
    all: () => ["services"] as const,
    products: () => ["services", "products"] as const,
    internet: {
      combined: () => ["services", "internet", "combined"] as const,
      eligibility: () => ["services", "internet", "eligibility"] as const,
    },
    sim: {
      combined: () => ["services", "sim", "combined"] as const,
    },
    vpn: {
      combined: () => ["services", "vpn", "combined"] as const,
    },
  },
  orders: {
    list: () => ["orders", "list"] as const,
    detail: (id: string | number) => ["orders", "detail", String(id)] as const,
  },
  verification: {
    residenceCard: () => ["verification", "residence-card"] as const,
  },
  support: {
    cases: (params?: Record<string, unknown>) => ["support", "cases", params] as const,
    case: (id: string) => ["support", "case", id] as const,
  },
  currency: {
    default: () => ["currency", "default"] as const,
  },
  address: {
    zipLookup: (zipCode: string) => ["address", "zip-lookup", zipCode] as const,
    status: () => ["address", "status"] as const,
  },
} as const;
