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

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

export interface Role {
  id: string;
  [key: string]: any; // Allow additional properties from backend
}

export type RoleUpdateData = Partial<Omit<Role, 'id'>>;

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 list of roles with optional pagination
 * Endpoint: GET /api/rbac/roles
 * Query parameter: pagination (optional, JSON-encoded string)
 * Example: /api/rbac/roles?pagination={"page":1,"pageSize":10}
 */
export async function fetchRoles(
  request: ApiRequestFunction,
  params?: PaginationParams
): Promise<PaginatedResponse<Role> | Role[]> {
  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/rbac/roles',
    method: 'get',
    params: requestParams
  });
  
  return data;
}

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

/**
 * Fetch role options
 * Endpoint: GET /api/rbac/roles/options
 */
export async function fetchRoleOptions(
  request: ApiRequestFunction
): Promise<any> {
  try {
    const data = await request({
      url: '/api/rbac/roles/options',
      method: 'get'
    });
    return data || null;
  } catch (error: any) {
    console.error('Error fetching role options:', error);
    return null;
  }
}

/**
 * Create a new role
 * Endpoint: POST /api/rbac/roles
 * Request body: Role object
 * Required fields:
 * - roleLabel: string (e.g., "admin", "user")
 * - description: TextMultilingual object (at least en is required)
 */
export async function createRole(
  request: ApiRequestFunction,
  roleData: Partial<Role>
): Promise<Role> {
  console.log('🔵 createRole - Complete request structure:', {
    url: '/api/rbac/roles',
    method: 'post',
    requestOptions: {
      url: '/api/rbac/roles',
      method: 'post',
      data: roleData
    },
    roleData: roleData,
    roleDataKeys: Object.keys(roleData || {}),
    roleDataValues: Object.entries(roleData || {}).map(([key, value]) => ({
      key,
      value,
      type: typeof value,
      isObject: typeof value === 'object' && value !== null,
      isArray: Array.isArray(value),
      stringified: typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value)
    })),
    dataStringified: JSON.stringify(roleData, null, 2),
    dataStringifiedCompact: JSON.stringify(roleData)
  });
  
  try {
    const result = await request({
      url: '/api/rbac/roles',
      method: 'post',
      data: roleData
    });
    
    console.log('✅ createRole - Response:', result);
    
    return result;
  } catch (error: any) {
    console.error('❌ createRole - Request failed:', {
      error,
      errorMessage: error.message,
      errorResponse: error.response,
      errorResponseData: error.response?.data,
      errorResponseStatus: error.response?.status,
      errorResponseHeaders: error.response?.headers,
      errorRequest: error.request,
      errorConfig: error.config
    });
    throw error;
  }
}

/**
 * Update a role
 * Endpoint: PUT /api/rbac/roles/{roleId}
 */
export async function updateRole(
  request: ApiRequestFunction,
  roleId: string,
  updateData: RoleUpdateData
): Promise<Role> {
  return await request({
    url: `/api/rbac/roles/${roleId}`,
    method: 'put',
    data: updateData
  });
}

/**
 * Delete a role
 * Endpoint: DELETE /api/rbac/roles/{roleId}
 */
export async function deleteRole(
  request: ApiRequestFunction,
  roleId: string
): Promise<void> {
  await request({
    url: `/api/rbac/roles/${roleId}`,
    method: 'delete'
  });
}
