/**
 * useCatalogObjects Hook
 * 
 * Fetches RBAC catalog objects (DATA, UI, RESOURCE) from the backend.
 * Used by AccessRulesEditor to populate object selection dropdowns.
 */

import { useState, useCallback } from 'react';
import api from '../api';
import { type RuleContext } from './useAccessRules';

// =============================================================================
// TYPES
// =============================================================================

export interface CatalogObject {
  objectKey: string;
  featureCode: string;
  label: { [lang: string]: string };
  meta?: Record<string, unknown>;
  type: RuleContext;
}

export interface CatalogObjects {
  DATA: CatalogObject[];
  UI: CatalogObject[];
  RESOURCE: CatalogObject[];
}

interface UseCatalogObjectsReturn {
  objects: CatalogObjects;
  loading: boolean;
  error: string | null;
  fetchObjects: (context?: RuleContext, featureCode?: string, mandateId?: string) => Promise<CatalogObjects>;
  getObjectsByContext: (context: RuleContext) => CatalogObject[];
  getObjectByKey: (objectKey: string) => CatalogObject | undefined;
}

// =============================================================================
// HOOK
// =============================================================================

export function useCatalogObjects(): UseCatalogObjectsReturn {
  const [objects, setObjects] = useState<CatalogObjects>({ DATA: [], UI: [], RESOURCE: [] });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  /**
   * Fetch catalog objects from the backend.
   * 
   * @param context - Optional filter by context type (DATA, UI, RESOURCE)
   * @param featureCode - Optional filter by feature code
   * @param mandateId - Optional filter by mandate's active features
   */
  const fetchObjects = useCallback(async (
    context?: RuleContext,
    featureCode?: string,
    mandateId?: string
  ): Promise<CatalogObjects> => {
    setLoading(true);
    setError(null);
    
    try {
      const params = new URLSearchParams();
      if (context) params.append('context', context);
      if (featureCode) params.append('featureCode', featureCode);
      if (mandateId) params.append('mandateId', mandateId);
      
      const url = `/api/rbac/catalog/objects${params.toString() ? `?${params}` : ''}`;
      const response = await api.get<CatalogObjects>(url);
      
      // Normalize response structure
      const data: CatalogObjects = {
        DATA: response.data.DATA || [],
        UI: response.data.UI || [],
        RESOURCE: response.data.RESOURCE || [],
      };
      
      setObjects(data);
      return data;
    } catch (err: unknown) {
      const errorMsg = err instanceof Error 
        ? err.message 
        : (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail || 'Fehler beim Laden der Katalog-Objekte';
      setError(errorMsg);
      return { DATA: [], UI: [], RESOURCE: [] };
    } finally {
      setLoading(false);
    }
  }, []);

  /**
   * Get objects filtered by context.
   */
  const getObjectsByContext = useCallback((context: RuleContext): CatalogObject[] => {
    return objects[context] || [];
  }, [objects]);

  /**
   * Get a specific object by its key.
   */
  const getObjectByKey = useCallback((objectKey: string): CatalogObject | undefined => {
    const allObjects = [...objects.DATA, ...objects.UI, ...objects.RESOURCE];
    return allObjects.find(obj => obj.objectKey === objectKey);
  }, [objects]);

  return {
    objects,
    loading,
    error,
    fetchObjects,
    getObjectsByContext,
    getObjectByKey,
  };
}

export default useCatalogObjects;
