import { ApiRequestOptions } from '../hooks/useApi';
import api from '../api';
import { addCSRFTokenToHeaders } from '../utils/csrfUtils';

// ============================================================================
// TYPES & INTERFACES
// ============================================================================

export interface LoginRequest {
  username: string;
  password: string;
}

export interface LoginResponse {
  type: 'local_auth_success';
  accessToken?: string;
  tokenType?: string;
  authenticationAuthority?: string;
  label?: any;
  fieldLabels?: any;
}

export interface RegisterData {
  username: string;
  email: string;
  fullName: string;
  language?: string;
  enabled?: boolean;
  privilege?: string;
}

export interface RegisterRequest {
  userData: {
    username: string;
    email: string;
    fullName: string;
    language: string;
    enabled: boolean;
    privilege: string;
    authenticationAuthority: string;
  };
  frontendUrl: string;
}

export interface PasswordResetRequestResponse {
  success: boolean;
  message: string;
}

export interface PasswordResetResponse {
  success: boolean;
  message: string;
}

export interface RegisterResponse {
  success: boolean;
  message?: string;
  user?: {
    id: string;
    username: string;
    email: string;
    fullName: string;
    language: string;
    enabled: boolean;
    privilege: string;
  };
}

export interface MsalRegisterData {
  username: string;
  email: string;
  fullName: string;
  language?: string;
}

export interface UsernameAvailabilityRequest {
  username: string;
  authenticationAuthority?: string;
}

export interface UsernameAvailabilityResponse {
  username: string;
  authenticationAuthority: string;
  available: boolean;
  message: string;
}

// User-Typ wird aus userApi.ts importiert
// Hier nur für Rückwärtskompatibilität
export interface AuthUser {
  id: string;
  username: string;
  email: string;
  fullName: string;
  language: string;
  enabled: boolean;
  roleLabels?: string[];
  authenticationAuthority: string;
  isSysAdmin?: boolean;
  [key: string]: any;
}

// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================

/**
 * Login with username and password
 * Endpoint: POST /api/local/login
 */
export async function loginApi(loginData: LoginRequest): Promise<LoginResponse> {
  // Create the form data in the exact format FastAPI OAuth2 expects
  const params = new URLSearchParams();
  params.append('username', loginData.username);
  params.append('password', loginData.password);
  params.append('grant_type', 'password');
  params.append('scope', '');
  params.append('client_id', '');
  params.append('client_secret', '');

  // Prepare headers with CSRF token if available
  const headers: Record<string, string> = {
    'Content-Type': 'application/x-www-form-urlencoded'
  };

  // Add CSRF token if available (for new security implementation)
  addCSRFTokenToHeaders(headers);

  // Use the existing api instance with custom headers for this request
  const response = await api.post<LoginResponse>('/api/local/login', params, {
    headers
  });

  return response.data;
}

/**
 * Fetch current user data
 * Endpoint: GET /api/local/me | /api/msft/me | /api/google/me
 */
export async function fetchCurrentUserApi(authAuthority?: string): Promise<AuthUser> {
  let endpoint = '/api/local/me';
  
  if (authAuthority === 'msft') {
    endpoint = '/api/msft/me';
  } else if (authAuthority === 'google') {
    endpoint = '/api/google/me';
  }
  
  const response = await api.get<AuthUser>(endpoint);
  return response.data;
}

/**
 * Register a new user (magic link based - no password required)
 * Endpoint: POST /api/local/register
 * 
 * After registration, user receives an email with a magic link to set their password.
 */
export async function registerApi(registerData: RegisterData): Promise<RegisterResponse> {
  // Prepare data to match backend expectations (no password - magic link flow)
  const dataToSend: RegisterRequest = {
    userData: {
      username: registerData.username,
      email: registerData.email,
      fullName: registerData.fullName,
      language: registerData.language || 'de',
      enabled: registerData.enabled !== undefined ? registerData.enabled : true,
      privilege: registerData.privilege || 'user',
      authenticationAuthority: 'local'
    },
    frontendUrl: window.location.origin
  };

  // Prepare headers with CSRF token if available
  const headers: Record<string, string> = {
    'Content-Type': 'application/json'
  };

  // Add CSRF token if available (for new security implementation)
  addCSRFTokenToHeaders(headers);

  const response = await api.post<RegisterResponse>('/api/local/register', dataToSend, {
    headers
  });

  const userData: any = response.data;
  return {
    success: true,
    message: 'Registration successful - check email for password setup link',
    user: userData && typeof userData === 'object' && 'id' in userData ? {
      id: String(userData.id || ''),
      username: String(userData.username || ''),
      email: String(userData.email || ''),
      fullName: String(userData.fullName || ''),
      language: String(userData.language || 'de'),
      enabled: Boolean(userData.enabled !== false),
      privilege: String(userData.privilege || 'user')
    } : undefined
  };
}

/**
 * Request password reset by username
 * Endpoint: POST /api/local/password-reset-request
 * 
 * Sends a reset email to the user's registered email address.
 */
export async function requestPasswordResetApi(username: string): Promise<PasswordResetRequestResponse> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json'
  };

  addCSRFTokenToHeaders(headers);

  const response = await api.post<PasswordResetRequestResponse>(
    '/api/local/password-reset-request',
    {
      username,
      frontendUrl: window.location.origin
    },
    { headers }
  );

  return response.data;
}

/**
 * Reset password using token from magic link
 * Endpoint: POST /api/local/password-reset
 */
export async function resetPasswordApi(token: string, password: string): Promise<PasswordResetResponse> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json'
  };

  addCSRFTokenToHeaders(headers);

  const response = await api.post<PasswordResetResponse>(
    '/api/local/password-reset',
    { token, password },
    { headers }
  );

  return response.data;
}

/**
 * Register with Microsoft account
 * Endpoint: POST /api/msft/register
 */
export async function registerWithMsalApi(
  request: ApiRequestFunction,
  userData: MsalRegisterData
): Promise<RegisterResponse> {
  const response = await request({
    url: '/api/msft/register',
    method: 'post',
    data: userData,
    additionalConfig: {
      headers: {
        'Content-Type': 'application/json'
      }
    }
  });

  const responseData: any = response;
  return {
    success: true,
    message: 'Registration successful',
    user: responseData && typeof responseData === 'object' && 'id' in responseData ? {
      id: String(responseData.id || ''),
      username: String(responseData.username || ''),
      email: String(responseData.email || ''),
      fullName: String(responseData.fullName || ''),
      language: String(responseData.language || 'en'),
      enabled: Boolean((responseData as any).enabled !== false),
      privilege: String((responseData as any).privilege || 'user')
    } : undefined
  };
}

/**
 * Check username availability
 * Endpoint: GET /api/local/available
 */
export async function checkUsernameAvailabilityApi(
  username: string,
  authenticationAuthority: string = 'local'
): Promise<UsernameAvailabilityResponse> {
  const response = await api.get<UsernameAvailabilityResponse>('/api/local/available', {
    params: {
      username,
      authenticationAuthority
    }
  });

  return response.data;
}

/**
 * Logout current user
 * Endpoint: POST /api/local/logout
 */
export async function logoutApi(): Promise<void> {
  await api.post('/api/local/logout');
}

