// This file is auto-generated by @hey-api/openapi-ts

import {
  createClient,
  type Config,
  type ClientOptions as DefaultClientOptions,
} from '@hey-api/client-axios';
import Cookies from 'js-cookie';

import { AUTH_TOKEN_KEY, REFRESH_TOKEN_KEY } from '@/lib/constants';
import type { ClientOptions } from './types.gen';

/**
 * The `createClientConfig()` function will be called on client initialization
 * and the returned object will become the client's initial configuration.
 *
 * You may want to initialize your client this way instead of calling
 * `setConfig()`. This is useful for example if you're using Next.js
 * to ensure your client always has the correct values.
 */
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> =
  (
    override?: Config<DefaultClientOptions & T>
  ) => Config<Required<DefaultClientOptions> & T>;

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001';

export const client = createClient();

client.setConfig({
  baseURL: API_BASE_URL,
});

// Request Interceptor
client.instance.interceptors.request.use(config => {
  const token = Cookies.get(AUTH_TOKEN_KEY);
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// Response Interceptor
client.instance.interceptors.response.use(
  response => response,
  async error => {
    const originalRequest = error.config;
    if (originalRequest.url?.includes('/auth/login')) {
      return Promise.reject(error);
    }
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      try {
        const refreshToken = Cookies.get(REFRESH_TOKEN_KEY);
        if (!refreshToken) {
          throw new Error('No refresh token');
        }

        const baseURL = client.getConfig().baseURL || API_BASE_URL;
        const response = await fetch(`${baseURL}/api/auth/refresh`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ refreshToken: refreshToken }),
        });

        const data = await response.json();

        if (response.ok && data.success) {
          const { token, refreshToken: newRefreshToken } = data.data;

          // Update cookies
          Cookies.set(AUTH_TOKEN_KEY, token, {
            secure: true,
            sameSite: 'Strict',
          });
          if (newRefreshToken) {
            Cookies.set(REFRESH_TOKEN_KEY, newRefreshToken, {
              secure: true,
              sameSite: 'Strict',
            });
          }

          client.instance.defaults.headers.common[
            'Authorization'
          ] = `Bearer ${token}`;
          originalRequest.headers['Authorization'] = `Bearer ${token}`;

          return client.instance(originalRequest);
        } else {
          throw new Error('Refresh failed');
        }
      } catch (err) {
        Cookies.remove(AUTH_TOKEN_KEY);
        Cookies.remove(REFRESH_TOKEN_KEY);
        if (typeof window !== 'undefined') {
          window.location.href = '/login';
        }
        return Promise.reject(err);
      }
    }
    return Promise.reject(error);
  }
);
