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

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

export interface Connection {
  id: string;
  userId: string;
  authority: 'local' | 'google' | 'msft';
  externalId: string;
  externalUsername: string;
  externalEmail?: string;
  status: 'active' | 'expired' | 'revoked' | 'pending';
  connectedAt: number; // Backend uses float for UTC timestamp in seconds
  lastChecked: number; // Backend uses float for UTC timestamp in seconds
  expiresAt?: number; // Backend uses Optional[float] for UTC timestamp in seconds
  [key: string]: any; // Allow additional properties
}

export interface AttributeDefinition {
  name: string;
  label: string;
  type: 'string' | 'number' | 'date' | 'boolean' | 'enum';
  sortable?: boolean;
  filterable?: boolean;
  searchable?: boolean;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  filterOptions?: string[];
}

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;
  };
}

export interface CreateConnectionData {
  id?: string;
  userId?: string;
  authority?: 'msft' | 'google';
  type?: 'msft' | 'google'; // Backend expects this field
  externalId?: string;
  externalUsername?: string;
  externalEmail?: string;
  status?: 'active' | 'expired' | 'revoked' | 'pending';
  connectedAt?: number;
  lastChecked?: number;
  expiresAt?: number;
}

export interface ConnectResponse {
  authUrl: string;
}

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

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

/**
 * Fetch connection attributes from backend
 * Endpoint: GET /api/attributes/UserConnection
 */
export async function fetchConnectionAttributes(_request: ApiRequestFunction): Promise<AttributeDefinition[]> {
  // Note: This uses api.get directly due to response format handling
  // For now, we'll use api.get directly in the hook as well
  throw new Error('fetchConnectionAttributes should use api instance directly for response format handling');
}

/**
 * Fetch list of connections with optional pagination
 * Endpoint: GET /api/connections/
 */
export async function fetchConnections(
  request: ApiRequestFunction,
  params?: PaginationParams
): Promise<PaginatedResponse<Connection> | Connection[]> {
  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/connections/',
    method: 'get',
    params: requestParams
  });
  
  return data;
}

/**
 * Create a new connection
 * Endpoint: POST /api/connections/
 */
export async function createConnection(
  request: ApiRequestFunction,
  connectionData: CreateConnectionData
): Promise<Connection> {
  return await request({
    url: '/api/connections/',
    method: 'post',
    data: connectionData
  });
}

/**
 * Connect to a service (initiate OAuth)
 * Endpoint: POST /api/connections/{connectionId}/connect
 */
export async function connectService(
  request: ApiRequestFunction,
  connectionId: string
): Promise<ConnectResponse> {
  return await request({
    url: `/api/connections/${connectionId}/connect`,
    method: 'post'
  });
}

/**
 * Disconnect from a service
 * Endpoint: POST /api/connections/{connectionId}/disconnect
 */
export async function disconnectService(
  request: ApiRequestFunction,
  connectionId: string
): Promise<{ message: string }> {
  return await request({
    url: `/api/connections/${connectionId}/disconnect`,
    method: 'post'
  });
}

/**
 * Delete a connection
 * Endpoint: DELETE /api/connections/{connectionId}
 */
export async function deleteConnection(
  request: ApiRequestFunction,
  connectionId: string
): Promise<{ message: string }> {
  return await request({
    url: `/api/connections/${connectionId}`,
    method: 'delete'
  });
}

/**
 * Update a connection
 * Endpoint: PUT /api/connections/{connectionId}
 */
export async function updateConnection(
  request: ApiRequestFunction,
  connectionId: string,
  updateData: Partial<Connection>
): Promise<Connection> {
  return await request({
    url: `/api/connections/${connectionId}`,
    method: 'put',
    data: updateData
  });
}

/**
 * Refresh Microsoft token
 * Endpoint: POST /api/msft/refresh
 */
export async function refreshMicrosoftToken(
  request: ApiRequestFunction,
  connectionId: string
): Promise<Connection> {
  return await request({
    url: '/api/msft/refresh',
    method: 'post',
    data: { connectionId }
  });
}

/**
 * Refresh Google token
 * Endpoint: POST /api/google/refresh
 */
export async function refreshGoogleToken(
  request: ApiRequestFunction,
  connectionId: string
): Promise<Connection> {
  return await request({
    url: '/api/google/refresh',
    method: 'post',
    data: { connectionId }
  });
}

