import { ApiRequestOptions } from '../hooks/useApi';

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

export interface User {
  id: string;
  username: string;
  email: string;
  fullName: string;
  language: string;
  enabled: boolean;
  roleLabels?: string[]; // Array of role labels from backend (e.g., ["user"])
  authenticationAuthority: string;
  isSysAdmin?: boolean; // System-Administrator Flag
  // mandateId ist nicht mehr Teil des User-Objekts (Multi-Tenant-Konzept)
  // Der Mandant-Kontext wird über Feature-Instanzen bestimmt
  [key: string]: any; // Allow additional properties
}

export type UserUpdateData = Partial<Omit<User, 'id' | 'mandateId'>>;

export interface AttributeDefinition {
  name: string;
  type: 'text' | 'email' | 'date' | 'checkbox' | 'select' | 'multiselect' | 'number' | 'textarea';
  label: string;
  description?: string;
  required?: boolean;
  default?: any;
  options?: Array<{ value: string | number; label: string | { [key: string]: string } }> | string;
  validation?: any;
  sortable?: boolean;
  filterable?: boolean;
  searchable?: boolean;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  filterOptions?: string[];
  readonly?: boolean;
  editable?: boolean;
}

export interface PaginationParams {
  page?: number;
  pageSize?: number;
  sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
  filters?: Record<string, any>;
  search?: string;
}

export interface PaginatedResponse<T> {
  items: T[];
  pagination?: {
    currentPage: number;
    pageSize: number;
    totalItems: number;
    totalPages: number;
  };
}

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

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

/**
 * Fetch current user data
 * Endpoint: GET /api/local/me | /api/msft/me | /api/google/me
 */
export async function fetchCurrentUser(
  request: ApiRequestFunction,
  authAuthority?: string
): Promise<User> {
  let endpoint = '/api/local/me';
  
  if (authAuthority === 'msft') {
    endpoint = '/api/msft/me';
  } else if (authAuthority === 'google') {
    endpoint = '/api/google/me';
  }
  
  console.log('📡 fetchCurrentUser: Requesting user data from:', endpoint);
  const response = await request({
    url: endpoint,
    method: 'get'
  });
  
  console.log('📥 fetchCurrentUser: Received response:', {
    endpoint,
    hasData: !!response,
    username: response?.username,
    roleLabels: response?.roleLabels,
    allKeys: response ? Object.keys(response) : [],
    fullResponse: response
  });
  
  return response;
}

/**
 * Logout current user
 * Endpoint: POST /api/local/logout | /api/msft/logout
 */
export async function logoutUser(
  request: ApiRequestFunction,
  authAuthority: string = 'local'
): Promise<void> {
  let endpoint = '/api/local/logout';
  
  if (authAuthority === 'msft') {
    endpoint = '/api/msft/logout';
  }
  
  await request({
    url: endpoint,
    method: 'post'
  });
}

/**
 * Fetch user attributes from backend
 * Endpoint: GET /api/attributes/User
 */
export async function fetchUserAttributes(_request: ApiRequestFunction): Promise<AttributeDefinition[]> {
  // Note: This uses api.get directly in the hook due to response format handling
  // Keeping the function signature here for consistency, but implementation may need api instance
  throw new Error('fetchUserAttributes should use api instance directly for response format handling');
}

/**
 * Fetch list of users with optional pagination
 * Endpoint: GET /api/users/
 */
export async function fetchUsers(
  request: ApiRequestFunction,
  params?: PaginationParams
): Promise<PaginatedResponse<User> | User[]> {
  const requestParams: any = {};
  
  // Build pagination object if provided
  if (params) {
    const paginationObj: any = {};
    
    if (params.page !== undefined) paginationObj.page = params.page;
    if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize;
    if (params.sort) paginationObj.sort = params.sort;
    if (params.filters) paginationObj.filters = params.filters;
    if (params.search) paginationObj.search = params.search;
    
    if (Object.keys(paginationObj).length > 0) {
      requestParams.pagination = JSON.stringify(paginationObj);
    }
  }
  
  const data = await request({
    url: '/api/users/',
    method: 'get',
    params: requestParams
  });
  
  return data;
}

/**
 * Fetch a single user by ID
 * Endpoint: GET /api/users/{userId}
 */
export async function fetchUserById(
  request: ApiRequestFunction,
  userId: string
): Promise<User | null> {
  try {
    const data = await request({
      url: `/api/users/${userId}`,
      method: 'get'
    });
    return data || null;
  } catch (error: any) {
    console.error('Error fetching user by ID:', error);
    return null;
  }
}

/**
 * Create a new user
 * Endpoint: POST /api/users
 */
export async function createUser(
  request: ApiRequestFunction,
  userData: Partial<User>
): Promise<User> {
  return await request({
    url: '/api/users',
    method: 'post',
    data: userData
  });
}

/**
 * Update a user
 * Endpoint: PUT /api/users/{userId}
 */
export async function updateUser(
  request: ApiRequestFunction,
  userId: string,
  userData: UserUpdateData
): Promise<User> {
  return await request({
    url: `/api/users/${userId}`,
    method: 'put',
    data: userData
  });
}

/**
 * Delete a user
 * Endpoint: DELETE /api/users/{userId}
 */
export async function deleteUser(
  request: ApiRequestFunction,
  userId: string
): Promise<void> {
  await request({
    url: `/api/users/${userId}`,
    method: 'delete'
  });
}

/**
 * Send password setup link to a user
 * Endpoint: POST /api/users/{userId}/send-password-link
 */
export async function sendPasswordLink(
  request: ApiRequestFunction,
  userId: string,
  frontendUrl: string
): Promise<{ message: string; userId: string; email: string }> {
  return await request({
    url: `/api/users/${userId}/send-password-link`,
    method: 'post',
    data: { frontendUrl }
  });
}

