/**
 * useMandates Hook
 * 
 * Hook für die Verwaltung von Mandanten (Mandates) 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 {
  fetchMandates as fetchMandatesApi,
  fetchMandateById as fetchMandateByIdApi,
  createMandate as createMandateApi,
  updateMandate as updateMandateApi,
  deleteMandate as deleteMandateApi,
  type Mandate,
  type MandateUpdateData,
  type PaginationParams
} from '../api/mandateApi';

// Re-export types
export type { Mandate, MandateUpdateData, 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 mandates in admin panel
 */
export function useAdminMandates() {
  const [mandates, setMandates] = useState<Mandate[]>([]);
  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, Mandate[]>();
  const { checkPermission } = usePermissions();

  // Fetch attributes from backend
  const fetchAttributes = useCallback(async () => {
    try {
      const response = await api.get('/api/attributes/Mandate');
      
      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 mandate attributes.');
      } else if (error.response?.status !== 401) {
        console.error('Error fetching mandate attributes:', error);
      }
      setAttributes([]);
      return [];
    }
  }, []);

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

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

  // Optimistic updates
  const removeOptimistically = (mandateId: string) => {
    setMandates(prev => prev.filter(m => m.id !== mandateId));
  };

  const updateOptimistically = (mandateId: string, updateData: Partial<Mandate>) => {
    setMandates(prev =>
      prev.map(m => m.id === mandateId ? { ...m, ...updateData } : m)
    );
  };

  // Fetch single mandate
  const fetchMandateById = useCallback(async (mandateId: string): Promise<Mandate | null> => {
    return await fetchMandateByIdApi(request, mandateId);
  }, [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 mandate
  const handleCreate = useCallback(async (mandateData: Partial<Mandate>): Promise<boolean> => {
    try {
      await createMandateApi(request, mandateData);
      await fetchMandates();
      return true;
    } catch (error: any) {
      console.error('Error creating mandate:', error);
      return false;
    }
  }, [request, fetchMandates]);

  // Update mandate
  const handleUpdate = useCallback(async (mandateId: string, updateData: MandateUpdateData): Promise<boolean> => {
    try {
      updateOptimistically(mandateId, updateData);
      await updateMandateApi(request, mandateId, updateData);
      return true;
    } catch (error: any) {
      console.error('Error updating mandate:', error);
      await fetchMandates();
      return false;
    }
  }, [request, fetchMandates]);

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

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

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

  return {
    mandates,
    attributes,
    columns,
    permissions,
    pagination,
    loading,
    error,
    refetch: fetchMandates,
    fetchMandateById,
    handleCreate,
    handleUpdate,
    handleDelete,
    handleInlineUpdate,
    updateOptimistically,
  };
}

export default useAdminMandates;
