const TOKEN_KEY = 'fitcrm_platform_access_token';
const REFRESH_TOKEN_KEY = 'fitcrm_platform_refresh_token';

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/v1';

export interface AuthTokens {
  accessToken: string;
  refreshToken: string;
}

export async function login(
  phone: string,
  password: string,
): Promise<AuthTokens> {
  const response = await fetch(`${API_URL}/auth/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ phone, password }),
  });

  if (!response.ok) {
    const error: Record<string, unknown> = await (response.json() as Promise<Record<string, unknown>>).catch(() => ({}));
    throw new Error(typeof error.message === 'string' ? error.message : 'Ошибка авторизации');
  }

  const data = (await response.json()) as AuthTokens;

  localStorage.setItem(TOKEN_KEY, data.accessToken);
  localStorage.setItem(REFRESH_TOKEN_KEY, data.refreshToken);

  return data;
}

export async function refreshToken(): Promise<string> {
  const refresh = localStorage.getItem(REFRESH_TOKEN_KEY);

  if (!refresh) {
    throw new Error('Нет refresh-токена');
  }

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

  if (!response.ok) {
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(REFRESH_TOKEN_KEY);
    throw new Error('Сессия истекла');
  }

  const data = (await response.json()) as AuthTokens;
  localStorage.setItem(TOKEN_KEY, data.accessToken);

  if (data.refreshToken) {
    localStorage.setItem(REFRESH_TOKEN_KEY, data.refreshToken);
  }

  return data.accessToken;
}

export function logout(): void {
  localStorage.removeItem(TOKEN_KEY);
  localStorage.removeItem(REFRESH_TOKEN_KEY);
  window.location.href = '/login';
}

export function getAccessToken(): string | null {
  if (typeof window === 'undefined') return null;
  return localStorage.getItem(TOKEN_KEY);
}

export function getAuthHeaders(): Record<string, string> {
  const token = getAccessToken();
  if (!token) return {};
  return { Authorization: `Bearer ${token}` };
}

export function isAuthenticated(): boolean {
  return !!getAccessToken();
}

/**
 * Authenticated fetch — automatically attaches Bearer token
 * and retries once with a refreshed token on 401.
 */
export async function authFetch(
  url: string,
  init?: RequestInit,
): Promise<Response> {
  const token = getAccessToken();

  const headers: Record<string, string> = {
    ...(init?.headers as Record<string, string> | undefined),
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
  };

  const res = await fetch(url, { ...init, headers });

  if (res.status === 401 && token) {
    try {
      const newToken = await refreshToken();
      const retryHeaders: Record<string, string> = {
        ...(init?.headers as Record<string, string> | undefined),
        Authorization: `Bearer ${newToken}`,
      };
      return fetch(url, { ...init, headers: retryHeaders });
    } catch {
      logout();
      return res;
    }
  }

  return res;
}
