export interface FetchResult<T> {
  data: T | null;
  errors: Record<string, Error>;
  hasErrors: boolean;
}

export class PageDataFetcher {
  /**
   * Fetch using manual service instantiation
   * Use for: Multiple dependencies, request-scoped services, or auth context
   * RECOMMENDED for SSR
   */
  static async fetchManual<TData>(
    serviceFactory: () => Promise<TData> | TData
  ): Promise<TData | null> {
    try {
      const result = await serviceFactory();
      return result;
    } catch (error) {
      console.error('Failed to fetch manual:', error);
      return null;
    }
  }

  /**
   * Fetch multiple datasets in parallel with error aggregation
   * Use for: Pages needing multiple service calls
   * UPDATED: Returns both data and errors for proper handling
   */
  static async fetchMultiple<T extends Record<string, any>>(
    queries: T
  ): Promise<FetchResult<{ [K in keyof T]: T[K] }>> {
    const results = {} as { [K in keyof T]: T[K] };
    const errors = {} as Record<string, Error>;
    
    const entries = await Promise.all(
      Object.entries(queries).map(async ([key, query]) => {
        try {
          const result = await query();
          return [key, { success: true, data: result }] as const;
        } catch (error) {
          console.error(`Failed to fetch ${key}:`, error);
          return [key, { success: false, error: error instanceof Error ? error : new Error(String(error)) }] as const;
        }
      })
    );

    entries.forEach(([key, result]) => {
      if (typeof result === 'object' && result !== null && 'success' in result) {
        if (result.success) {
          results[key as keyof T] = (result as { data: T[keyof T] }).data;
        } else {
          errors[key] = (result as { error: Error }).error;
        }
      }
    });

    return {
      data: results,
      errors,
      hasErrors: Object.keys(errors).length > 0
    };
  }
}