/**
 * Simple API Client (auto-generated, strict types, minimal, DRY)
 * Generated at: {{ generation_time }}
 * DO NOT EDIT - This file is automatically generated
 */



{%- for zone in zones %}
import * as {{ zone | title }}Endpoints from './{{ zone }}';
import { createClient as create{{ zone | title }}Client, createConfig as create{{ zone | title }}Config } from './{{ zone }}/client';
{%- endfor %}

{%- for zone in zones %}
export * as {{ zone | title }}Types from './{{ zone }}';
{%- endfor %}

export const TOKEN_KEY = "auth_token";
export const REFRESH_TOKEN_KEY = "refresh_token";

function makeEndpoints<T extends Record<string, any>, C>(
  endpoints: T,
  client: C
): {
  [K in keyof T]: T[K] extends (options: infer O) => infer R
    ? (options?: Omit<O, 'client'>) => R
    : never;
} {
  const result = {} as any;
  (Object.keys(endpoints) as Array<keyof T>).forEach((key) => {
    const fn = endpoints[key];
    if (typeof fn === 'function') {
      result[key] = (options = {}) => fn({ ...options, client });
    }
  });
  return result as {
    [K in keyof T]: T[K] extends (options: infer O) => infer R
      ? (options?: Omit<O, 'client'>) => R
      : never;
  };
}

export class API {
  private apiUrl: string;
  private customHeaders: Record<string, string> = {};
  {%- for zone in zones %}
  public {{ camelcase(zone) }}!: {
    [K in keyof typeof {{ zone | title }}Endpoints]: typeof {{ zone | title }}Endpoints[K] extends (options: infer O) => infer R
      ? (options?: Omit<O, 'client'>) => R
      : never;
  };
  {%- endfor %}

  constructor(apiUrl: string) {
    this.apiUrl = apiUrl;
    this._initClients();
  }

  private _makeConfig() {
    const token = this.getToken();
    const headers: Record<string, string> = { ...this.customHeaders };
    
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }
    
    return {
      baseUrl: this.apiUrl,
      headers: Object.keys(headers).length > 0 ? headers : undefined,
    };
  }

  _initClients() {
    const config = this._makeConfig();
    {%- for zone in zones %}
    this.{{ camelcase(zone) }} = makeEndpoints(
      {{ zone | title }}Endpoints,
      create{{ zone | title }}Client(create{{ zone | title }}Config(config))
    );
    {%- endfor %}
  }

  /**
   * Set custom headers for API requests
   * @param headers - Object with header key-value pairs
   */
  setHeaders(headers: Record<string, string>) {
    this.customHeaders = { ...this.customHeaders, ...headers };
    this._initClients();
  }

  /**
   * Set API key for authentication
   * @param apiKey - The API key to use
   */
  setApiKey(apiKey: string) {
    this.setHeaders({ 'X-API-Key': apiKey });
  }

  /**
   * Clear all custom headers
   */
  clearHeaders() {
    this.customHeaders = {};
    this._initClients();
  }

  /**
   * Get current custom headers
   */
  getHeaders(): Record<string, string> {
    return { ...this.customHeaders };
  }

  getToken() {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem(TOKEN_KEY);
  }
  getRefreshToken() {
    if (typeof window === 'undefined') return null;
    return localStorage.getItem(REFRESH_TOKEN_KEY);
  }
  setToken(token: string, refreshToken?: string) {
    if (typeof window === 'undefined') return;
    localStorage.setItem(TOKEN_KEY, token);
    if (refreshToken) {
      localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
    }
    this._initClients();
  }
  clearTokens() {
    if (typeof window === 'undefined') return;
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(REFRESH_TOKEN_KEY);
    this._initClients();
  }
  isAuthenticated() {
    return !!this.getToken();
  }
  setApiUrl(url: string) {
    this.apiUrl = url;
    this._initClients();
  }
  getApiUrl() {
    return this.apiUrl;
  }
}

// Export the class for manual instantiation
export default API; 