/**
 * API Client for WooNooW Customer SPA
 * Handles all HTTP requests to WordPress REST API
 */

// Get API base URL from WordPress
const getApiBase = (): string => {
  return (window as any).woonoowCustomer?.apiUrl || '/wp-json/woonoow/v1';
};

// Get nonce for authentication
const getNonce = (): string => {
  return (window as any).woonoowCustomer?.nonce || '';
};

interface RequestOptions {
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  body?: any;
  headers?: Record<string, string>;
}

class ApiClient {
  private baseUrl: string;

  constructor() {
    this.baseUrl = getApiBase();
  }

  private async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {
    const { method = 'GET', body, headers = {} } = options;

    const url = `${this.baseUrl}${endpoint}`;

    const config: RequestInit = {
      method,
      headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': getNonce(),
        ...headers,
      },
      credentials: 'same-origin',
    };

    if (body) {
      config.body = JSON.stringify(body);
    }

    try {
      const response = await fetch(url, config);

      if (!response.ok) {
        const error = await response.json().catch(() => ({ message: response.statusText }));
        throw new Error(error.message || `HTTP ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('[API Error]', error);
      throw error;
    }
  }

  // GET request
  async get<T>(endpoint: string, params?: Record<string, any>): Promise<T> {
    let url = endpoint;
    if (params) {
      const query = new URLSearchParams(params).toString();
      url += `?${query}`;
    }
    return this.request<T>(url, { method: 'GET' });
  }

  // POST request
  async post<T>(endpoint: string, body?: any): Promise<T> {
    return this.request<T>(endpoint, { method: 'POST', body });
  }

  // PUT request
  async put<T>(endpoint: string, body?: any): Promise<T> {
    return this.request<T>(endpoint, { method: 'PUT', body });
  }

  // DELETE request
  async delete<T>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, { method: 'DELETE' });
  }
}

// API endpoints
const endpoints = {
  shop: {
    products: '/shop/products',
    product: (id: number) => `/shop/products/${id}`,
    categories: '/shop/categories',
    search: '/shop/search',
  },
  cart: {
    get: '/cart',
    add: '/cart/add',
    update: '/cart/update',
    remove: '/cart/remove',
    applyCoupon: '/cart/apply-coupon',
    removeCoupon: '/cart/remove-coupon',
  },
  checkout: {
    calculate: '/checkout/calculate',
    create: '/checkout/create-order',
    paymentMethods: '/checkout/payment-methods',
    shippingMethods: '/checkout/shipping-methods',
  },
  account: {
    orders: '/account/orders',
    order: (id: number) => `/account/orders/${id}`,
    downloads: '/account/downloads',
    profile: '/account/profile',
    password: '/account/password',
    addresses: '/account/addresses',
  },
};

// Create singleton instance with endpoints
const client = new ApiClient();

// Export as apiClient with endpoints attached
export const apiClient = Object.assign(client, { endpoints });

// Also export individual pieces for convenience
export const api = client;
export { endpoints };
