/**
 * useRoles Hook
 * 
 * Hook für die Verwaltung von globalen RBAC-Rollen im Admin-Bereich.
 * Folgt dem gleichen Pattern wie useOrgUsers.
 */

import { useState, useEffect, useCallback } from 'react';
import { useApiRequest } from './useApi';
import api from '../api';
import { usePermissions, type UserPermissions } from './usePermissions';
import {
  fetchRoles as fetchRolesApi,
  fetchRoleById as fetchRoleByIdApi,
  createRole as createRoleApi,
  updateRole as updateRoleApi,
  deleteRole as deleteRoleApi,
  type Role,
  type RoleUpdateData,
  type PaginationParams
} from '../api/roleApi';

// Re-export types
export type { Role, RoleUpdateData, PaginationParams };

export interface AttributeDefinition {
  name: string;
  type: string;
  label: string;
  description?: string;
  required?: boolean;
  default?: any;
  options?: Array<{ value: string | number; label: string | { [key: string]: string } }> | string;
  sortable?: boolean;
  filterable?: boolean;
  searchable?: boolean;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  readonly?: boolean;
  editable?: boolean;
}

/**
 * Hook for managing RBAC roles in admin panel
 */
export function useAdminRoles() {
  const [roles, setRoles] = useState<Role[]>([]);
  const [attributes, setAttributes] = useState<AttributeDefinition[]>([]);
  const [permissions, setPermissions] = useState<UserPermissions | null>(null);
  const [pagination, setPagination] = useState<{
    currentPage: number;
    pageSize: number;
    totalItems: number;
    totalPages: number;
  } | null>(null);
  const { request, isLoading: loading, error } = useApiRequest<null, Role[]>();
  const { checkPermission } = usePermissions();

  // Fetch attributes from backend
  const fetchAttributes = useCallback(async () => {
    try {
      const response = await api.get('/api/attributes/Role');
      
      let attrs: AttributeDefinition[] = [];
      if (response.data?.attributes && Array.isArray(response.data.attributes)) {
        attrs = response.data.attributes;
      } else if (Array.isArray(response.data)) {
        attrs = response.data;
      } else if (response.data && typeof response.data === 'object') {
        const keys = Object.keys(response.data);
        for (const key of keys) {
          if (Array.isArray(response.data[key])) {
            attrs = response.data[key];
            break;
          }
        }
      }
      
      setAttributes(attrs);
      return attrs;
    } catch (error: any) {
      if (error.response?.status === 429) {
        console.warn('Rate limit exceeded while fetching role attributes.');
      } else if (error.response?.status !== 401) {
        console.error('Error fetching role attributes:', error);
      }
      setAttributes([]);
      return [];
    }
  }, []);

  // Fetch permissions
  const fetchPermissions = useCallback(async () => {
    try {
      const perms = await checkPermission('DATA', 'Role');
      setPermissions(perms);
      return perms;
    } catch (error: any) {
      console.error('Error fetching role permissions:', error);
      const defaultPerms: UserPermissions = {
        view: false,
        read: 'n',
        create: 'n',
        update: 'n',
        delete: 'n',
      };
      setPermissions(defaultPerms);
      return defaultPerms;
    }
  }, [checkPermission]);

  // Fetch roles
  const fetchRoles = useCallback(async (params?: PaginationParams) => {
    try {
      const data = await fetchRolesApi(request, params);
      
      if (data && typeof data === 'object' && 'items' in data) {
        const items = Array.isArray(data.items) ? data.items : [];
        setRoles(items);
        if (data.pagination) {
          setPagination(data.pagination);
        }
      } else {
        const items = Array.isArray(data) ? data : [];
        setRoles(items);
        setPagination(null);
      }
    } catch (error: any) {
      setRoles([]);
      setPagination(null);
    }
  }, [request]);

  // Optimistic updates
  const removeOptimistically = (roleId: string) => {
    setRoles(prev => prev.filter(r => r.id !== roleId));
  };

  const updateOptimistically = (roleId: string, updateData: Partial<Role>) => {
    setRoles(prev =>
      prev.map(r => r.id === roleId ? { ...r, ...updateData } : r)
    );
  };

  // Fetch single role
  const fetchRoleById = useCallback(async (roleId: string): Promise<Role | null> => {
    return await fetchRoleByIdApi(request, roleId);
  }, [request]);

  // Generate columns from attributes (including fkSource/fkDisplayField for FK resolution)
  const columns = attributes.map(attr => ({
    key: attr.name,
    label: attr.label || attr.name,
    type: attr.type as any,
    sortable: attr.sortable !== false,
    filterable: attr.filterable !== false,
    searchable: attr.searchable !== false,
    width: attr.width || 150,
    minWidth: attr.minWidth || 100,
    maxWidth: attr.maxWidth || 400,
    fkSource: (attr as any).fkSource, // API endpoint for FK data
    fkDisplayField: (attr as any).fkDisplayField, // Which field of FK target to display
  }));

  // Create role
  const handleCreate = useCallback(async (roleData: Partial<Role>): Promise<boolean> => {
    try {
      await createRoleApi(request, roleData);
      await fetchRoles();
      return true;
    } catch (error: any) {
      console.error('Error creating role:', error);
      return false;
    }
  }, [request, fetchRoles]);

  // Update role
  const handleUpdate = useCallback(async (roleId: string, updateData: RoleUpdateData): Promise<boolean> => {
    try {
      updateOptimistically(roleId, updateData);
      await updateRoleApi(request, roleId, updateData);
      return true;
    } catch (error: any) {
      console.error('Error updating role:', error);
      await fetchRoles();
      return false;
    }
  }, [request, fetchRoles]);

  // Delete role
  const handleDelete = useCallback(async (roleId: string): Promise<boolean> => {
    try {
      removeOptimistically(roleId);
      await deleteRoleApi(request, roleId);
      return true;
    } catch (error: any) {
      console.error('Error deleting role:', error);
      await fetchRoles();
      return false;
    }
  }, [request, fetchRoles]);

  // Inline update
  const handleInlineUpdate = useCallback(async (
    roleId: string,
    updateData: Partial<Role>
  ): Promise<void> => {
    await handleUpdate(roleId, updateData);
  }, [handleUpdate]);

  // Load data on mount
  useEffect(() => {
    fetchAttributes();
    fetchPermissions();
    fetchRoles();
  }, []);

  return {
    roles,
    attributes,
    columns,
    permissions,
    pagination,
    loading,
    error,
    refetch: fetchRoles,
    fetchRoleById,
    handleCreate,
    handleUpdate,
    handleDelete,
    handleInlineUpdate,
    updateOptimistically,
  };
}

export default useAdminRoles;
