import { api } from './api';
import { AUTHENTIK_URL, CLIENT_ID } from '../utils/config';
import { User } from '../types/auth.types';

const REDIRECT_URI = `${window.location.origin}/auth/callback`;

export interface AuthCallbackResponse {
  token: string;
  refreshToken: string;
  user: User;
  isNewUser?: boolean;
}

// The backend returns camelCase field names; map them to the snake_case User type.
function mapBackendUser(backendUser: Record<string, unknown>): User {
  return {
    id: backendUser.id as string,
    email: backendUser.email as string,
    name: backendUser.name as string,
    given_name: (backendUser.given_name ?? backendUser.givenName) as string,
    family_name: (backendUser.family_name ?? backendUser.familyName) as string,
    preferred_username: (backendUser.preferred_username ?? backendUser.preferredUsername) as string | undefined,
    groups: backendUser.groups as string[] | undefined,
  };
}

export const authService = {
  /**
   * Generate Authentik authorization URL
   */
  getAuthUrl(): string {
    const params = new URLSearchParams({
      client_id: CLIENT_ID,
      redirect_uri: REDIRECT_URI,
      response_type: 'code',
      scope: 'openid profile email',
    });

    return `${AUTHENTIK_URL}/application/o/authorize/?${params.toString()}`;
  },

  /**
   * Handle OAuth callback - send code to backend, receive JWT
   */
  async handleCallback(code: string): Promise<AuthCallbackResponse> {
    const response = await api.post<{
      success: boolean;
      message: string;
      data: { accessToken: string; refreshToken: string; isNewUser?: boolean; user: Record<string, unknown> };
    }>('/api/auth/callback', {
      code,
      redirect_uri: REDIRECT_URI,
    });
    return {
      token: response.data.data.accessToken,
      refreshToken: response.data.data.refreshToken,
      user: mapBackendUser(response.data.data.user),
      isNewUser: response.data.data.isNewUser,
    };
  },

  /**
   * Logout - clear tokens
   */
  async logout(): Promise<void> {
    try {
      // Optionally call backend logout endpoint
      await api.post('/api/auth/logout');
    } catch (error) {
      console.error('Error during logout:', error);
      // Continue with logout even if backend call fails
    }
  },

  /**
   * Get current user information
   */
  async getCurrentUser(): Promise<User> {
    const response = await api.get<{ success: boolean; data: Record<string, unknown> }>('/api/user/me');
    return mapBackendUser(response.data.data);
  },
};
