/**
 * AdminMandateRolesPage
 * 
 * Admin page for managing ALL ROLES (system + global + mandate-specific).
 * Consolidated view replacing separate System-Roles page.
 * 
 * Shows:
 * - System roles (admin, user, viewer) - read-only, cannot be deleted
 * - Global roles (mandateId=null) - CRUD available
 * - Mandate-specific roles (mandateId=xyz) - CRUD available
 * - Feature-template roles are managed in AdminFeatureRolesPage
 * 
 * ALL filtering, sorting, and pagination is handled by the backend.
 */

import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import { useMandateRoles, type Role, type RoleCreate, type RoleUpdate, type PaginationParams } from '../../hooks/useMandateRoles';
import { useUserMandates, type Mandate } from '../../hooks/useUserMandates';
import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable';
import { FormGeneratorForm, type AttributeDefinition } from '../../components/FormGenerator/FormGeneratorForm';
import { FaPlus, FaSync, FaUserShield, FaBuilding, FaGlobe } from 'react-icons/fa';
import { useToast } from '../../contexts/ToastContext';
import api from '../../api';
import styles from './Admin.module.css';

export const AdminMandateRolesPage: React.FC = () => {
  const { showError, showWarning } = useToast();
  const {
    roles,
    loading,
    error,
    pagination,
    fetchRoles,
    createRole,
    updateRole,
    deleteRole,
  } = useMandateRoles();

  const { fetchMandates } = useUserMandates();

  // State
  const [mandates, setMandates] = useState<Mandate[]>([]);
  const [selectedMandateId, setSelectedMandateId] = useState<string>('');
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [editingRole, setEditingRole] = useState<Role | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [scopeFilter, setScopeFilter] = useState<'all' | 'mandate' | 'global'>('all');
  const [backendAttributes, setBackendAttributes] = useState<AttributeDefinition[]>([]);
  
  // Store current filter state for refetch
  const currentScopeFilterRef = useRef(scopeFilter);
  currentScopeFilterRef.current = scopeFilter;

  // Load mandates and attributes on mount
  useEffect(() => {
    const loadMandates = async () => {
      const data = await fetchMandates();
      setMandates(data);
      if (data.length > 0 && !selectedMandateId) {
        setSelectedMandateId(data[0].id);
      }
    };
    loadMandates();
    // Fetch Role attributes from backend
    api.get('/api/attributes/Role').then(response => {
      const attrs = response.data?.attributes || response.data || [];
      setBackendAttributes(Array.isArray(attrs) ? attrs : []);
    }).catch(() => setBackendAttributes([]));
  }, [fetchMandates]);

  // Load roles when mandate or scopeFilter changes
  useEffect(() => {
    if (selectedMandateId) {
      fetchRoles(selectedMandateId, { scopeFilter });
    }
  }, [selectedMandateId, scopeFilter, fetchRoles]);

  // Refetch wrapper that accepts pagination params from FormGeneratorTable
  // and includes the current mandateId and scopeFilter
  const refetchWithParams = useCallback(async (paginationParams?: PaginationParams) => {
    if (!selectedMandateId) return;
    // Merge pagination params with current filter state
    return fetchRoles(selectedMandateId, {
      ...paginationParams,
      scopeFilter: currentScopeFilterRef.current
    });
  }, [selectedMandateId, fetchRoles]);

  // Get description text
  const getDescriptionText = (desc: string | { [key: string]: string } | undefined) => {
    if (!desc) return '-';
    if (typeof desc === 'string') return desc;
    return desc.de || desc.en || Object.values(desc)[0] || '-';
  };

  // Table columns - scopeType is now a backend-computed field
  const columns = useMemo(() => [
    { 
      key: 'roleLabel', 
      label: 'Bezeichnung', 
      type: 'string' as const, 
      sortable: true, 
      filterable: true, 
      searchable: true, 
      width: 150 
    },
    { 
      key: 'description', 
      label: 'Beschreibung', 
      type: 'string' as const, 
      sortable: false, 
      filterable: false,
      width: 250,
      formatter: (value: string | { [key: string]: string }) => getDescriptionText(value)
    },
    { 
      key: 'scopeType', 
      label: 'Geltungsbereich', 
      type: 'string' as const, 
      sortable: true, 
      filterable: true, 
      width: 140,
      formatter: (value: string) => {
        if (value === 'system') {
          return (
            <span className={styles.badge} style={{ background: 'var(--warning-color, #d69e2e)', color: 'white' }}>
              <FaUserShield style={{ marginRight: 4 }} /> System
            </span>
          );
        }
        if (value === 'global') {
          return (
            <span className={styles.badge} style={{ background: 'var(--info-color, #3182ce)', color: 'white' }}>
              <FaGlobe style={{ marginRight: 4 }} /> Global
            </span>
          );
        }
        return (
          <span className={styles.badge} style={{ background: 'var(--success-color, #38a169)', color: 'white' }}>
            <FaBuilding style={{ marginRight: 4 }} /> Mandant
          </span>
        );
      }
    },
  ], []);

  // Form attributes from backend - for create form
  const createFields: AttributeDefinition[] = useMemo(() => {
    const excludedFields = ['id', 'mandateId', 'featureInstanceId', 'featureCode', 'isSystemRole', 'scopeType'];
    
    const fields = backendAttributes
      .filter(attr => !excludedFields.includes(attr.name))
      .map(attr => ({ ...attr })) as AttributeDefinition[];
    
    // Add scope field for mandate/global selection (not a model attribute)
    if (fields.length > 0) {
      fields.push({
        name: 'scope',
        label: 'Geltungsbereich',
        type: 'enum' as any,
        required: true,
        default: 'mandate',
        options: [
          { value: 'mandate', label: 'Nur dieser Mandant' },
          { value: 'global', label: 'Global (alle Mandanten)' },
        ]
      });
    }
    return fields;
  }, [backendAttributes]);

  // Form attributes from backend - for edit form
  // NOTE: mandateId/featureInstanceId/featureCode are IMMUTABLE - only description can be edited
  const editFields: AttributeDefinition[] = useMemo(() => {
    const excludedFields = ['id', 'mandateId', 'featureInstanceId', 'featureCode', 'isSystemRole', 'scopeType'];
    
    const fields = backendAttributes
      .filter(attr => !excludedFields.includes(attr.name))
      .map(attr => ({
        ...attr,
        // Mark roleLabel as readonly (cannot change after creation)
        readonly: attr.name === 'roleLabel' ? true : attr.readonly,
      })) as AttributeDefinition[];
    
    // No scope field for edit - context is immutable!
    return fields;
  }, [backendAttributes]);

  // Handle create role
  const handleCreateRole = async (data: { roleLabel: string; description?: string | { [key: string]: string }; scope: 'mandate' | 'global' }) => {
    if (!selectedMandateId) return;
    setIsSubmitting(true);
    try {
      // Ensure description is always a multilingual object
      let description: { [key: string]: string } = {};
      if (typeof data.description === 'string') {
        description = { de: data.description, en: data.description };
      } else if (data.description && typeof data.description === 'object') {
        description = data.description;
      }
      
      const roleData: RoleCreate = {
        roleLabel: data.roleLabel.toLowerCase().replace(/\s+/g, '_'),
        description: description,
        mandateId: data.scope === 'mandate' ? selectedMandateId : undefined
      };
      
      const result = await createRole(roleData, selectedMandateId);
      
      if (result.success) {
        setShowCreateModal(false);
        await fetchRoles(selectedMandateId, { scopeFilter });
      } else {
        showError('Fehler', result.error || 'Fehler beim Erstellen der Rolle');
      }
    } catch (err: any) {
      console.error('Create role error:', err);
      showError('Fehler', err.message || 'Fehler beim Erstellen der Rolle');
    } finally {
      setIsSubmitting(false);
    }
  };

  // Handle edit role
  const handleEditRole = async (data: RoleUpdate & { scope?: 'mandate' | 'global' }) => {
    if (!editingRole) return;
    setIsSubmitting(true);
    try {
      // Ensure description is always a multilingual object
      let description: { [key: string]: string } | undefined;
      if (typeof data.description === 'string') {
        description = { de: data.description, en: data.description };
      } else if (data.description && typeof data.description === 'object') {
        description = data.description as { [key: string]: string };
      }
      
      // Convert scope to mandateId - NOTE: Context fields are IMMUTABLE per concept!
      // We should not be changing mandateId after creation
      const updateData: RoleUpdate = {
        roleLabel: data.roleLabel,
        description: description,
        // mandateId is immutable - don't include in update
      };
      
      const result = await updateRole(editingRole.id, updateData);
      
      if (result.success) {
        setEditingRole(null);
        if (selectedMandateId) {
          await fetchRoles(selectedMandateId, { scopeFilter });
        }
      } else {
        showError('Fehler', result.error || 'Fehler beim Aktualisieren der Rolle');
      }
    } catch (err: any) {
      console.error('Update role error:', err);
      showError('Fehler', err.message || 'Fehler beim Aktualisieren der Rolle');
    } finally {
      setIsSubmitting(false);
    }
  };

  // Handle delete role (confirmation handled by DeleteActionButton)
  const handleDeleteRole = async (role: Role) => {
    if (role.isSystemRole) {
      showWarning('Nicht erlaubt', 'System-Rollen können nicht gelöscht werden.');
      return;
    }
    
    const result = await deleteRole(role.id);
    if (result.success) {
      // Refetch to update the list
      await fetchRoles(selectedMandateId, { scopeFilter });
    } else {
      showError('Fehler', result.error || 'Fehler beim Löschen der Rolle');
    }
  };

  // Handle edit click
  const handleEditClick = (role: Role) => {
    setEditingRole(role);
  };

  // Get mandate name
  const getMandateName = (mandate: Mandate) => {
    if (typeof mandate.name === 'object') {
      return mandate.name.de || mandate.name.en || Object.values(mandate.name)[0] || mandate.id;
    }
    return mandate.name || mandate.id;
  };

  if (error && !selectedMandateId) {
    return (
      <div className={styles.adminPage}>
        <div className={styles.errorContainer}>
          <span className={styles.errorIcon}>⚠️</span>
          <p className={styles.errorMessage}>Fehler: {error}</p>
          <button className={styles.secondaryButton} onClick={() => fetchMandates()}>
            <FaSync /> Erneut versuchen
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className={styles.adminPage}>
      <div className={styles.pageHeader}>
        <div>
          <h1 className={styles.pageTitle}>Rollen</h1>
          <p className={styles.pageSubtitle}>Verwalten Sie System-, globale und mandantenspezifische Rollen</p>
        </div>
      </div>

      {/* Mandate Selector and Filters */}
      <div className={styles.filterSection}>
        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>
            <FaBuilding style={{ marginRight: 8 }} />
            Mandant:
          </label>
          <select
            className={styles.filterSelect}
            value={selectedMandateId}
            onChange={(e) => setSelectedMandateId(e.target.value)}
          >
            <option value="">-- Mandant wählen --</option>
            {mandates.map(m => (
              <option key={m.id} value={m.id}>
                {getMandateName(m)}
              </option>
            ))}
          </select>
        </div>

        <div className={styles.filterGroup}>
          <label className={styles.filterLabel}>Filter:</label>
          <select
            className={styles.filterSelect}
            value={scopeFilter}
            onChange={(e) => setScopeFilter(e.target.value as 'all' | 'mandate' | 'global')}
            style={{ minWidth: 150 }}
          >
            <option value="all">Alle Rollen</option>
            <option value="mandate">Nur Mandanten-Rollen</option>
            <option value="global">Nur globale Rollen</option>
          </select>
        </div>
        
        {selectedMandateId && (
          <div className={styles.headerActions}>
            <button
              className={styles.secondaryButton}
              onClick={() => fetchRoles(selectedMandateId, { scopeFilter })}
              disabled={loading}
            >
              <FaSync className={loading ? 'spinning' : ''} /> Aktualisieren
            </button>
            <button
              className={styles.primaryButton}
              onClick={() => setShowCreateModal(true)}
            >
              <FaPlus /> Neue Rolle
            </button>
          </div>
        )}
      </div>

      {/* Info Box */}
      {selectedMandateId && (
        <div className={styles.infoBox}>
          <FaUserShield style={{ marginRight: 8 }} />
          <span>
            <strong>System-Rollen</strong> (admin, user, viewer) können nicht bearbeitet oder gelöscht werden.
            <strong> Globale Rollen</strong> gelten für alle Mandanten. 
            <strong> Mandanten-Rollen</strong> gelten nur für den ausgewählten Mandanten.
          </span>
        </div>
      )}

      {/* Content */}
      {!selectedMandateId ? (
        <div className={styles.emptyState}>
          <FaBuilding className={styles.emptyIcon} />
          <h3 className={styles.emptyTitle}>Kein Mandant ausgewählt</h3>
          <p className={styles.emptyDescription}>
            Wählen Sie einen Mandanten aus, um dessen Rollen zu verwalten.
          </p>
        </div>
      ) : loading && roles.length === 0 ? (
        <div className={styles.loadingContainer}>
          <div className={styles.spinner} />
          <span>Lade Rollen...</span>
        </div>
      ) : roles.length === 0 ? (
        <div className={styles.emptyState}>
          <FaUserShield className={styles.emptyIcon} />
          <h3 className={styles.emptyTitle}>Keine Rollen</h3>
          <p className={styles.emptyDescription}>
            {scopeFilter === 'mandate' 
              ? 'Es gibt noch keine mandantenspezifischen Rollen.'
              : scopeFilter === 'global'
              ? 'Es gibt noch keine globalen Rollen.'
              : 'Es gibt noch keine Rollen für diesen Mandanten.'}
          </p>
          <button
            className={styles.primaryButton}
            onClick={() => setShowCreateModal(true)}
          >
            <FaPlus /> Erste Rolle erstellen
          </button>
        </div>
      ) : (
        <div className={styles.tableContainer}>
          <FormGeneratorTable
            data={roles}
            columns={columns}
            loading={loading}
            pagination={true}
            pageSize={25}
            searchable={true}
            filterable={true}
            sortable={true}
            selectable={false}
            actionButtons={[
              {
                type: 'edit' as const,
                onAction: handleEditClick,
                title: 'Rolle bearbeiten',
                disabled: (row: Role) => row.isSystemRole ? { disabled: true, message: 'System-Rollen können nicht bearbeitet werden' } : false
              },
              {
                type: 'delete' as const,
                title: 'Rolle löschen',
                disabled: (row: Role) => row.isSystemRole ? { disabled: true, message: 'System-Rollen können nicht gelöscht werden' } : false
              }
            ]}
            onDelete={handleDeleteRole}
            hookData={{
              refetch: refetchWithParams,
              pagination: pagination,
              handleDelete: handleDeleteRole,
            }}
            emptyMessage="Keine Rollen gefunden"
          />
        </div>
      )}

      {/* Create Role Modal */}
      {showCreateModal && (
        <div className={styles.modalOverlay} onClick={() => setShowCreateModal(false)}>
          <div className={styles.modal} onClick={e => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>Neue Rolle erstellen</h2>
              <button
                className={styles.modalClose}
                onClick={() => setShowCreateModal(false)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              {createFields.length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>Lade Formular...</span>
                </div>
              ) : (
                <FormGeneratorForm
                  attributes={createFields}
                  mode="create"
                  onSubmit={handleCreateRole}
                  onCancel={() => setShowCreateModal(false)}
                  submitButtonText={isSubmitting ? 'Erstelle...' : 'Rolle erstellen'}
                  cancelButtonText="Abbrechen"
                />
              )}
            </div>
          </div>
        </div>
      )}

      {/* Edit Role Modal */}
      {editingRole && (
        <div className={styles.modalOverlay} onClick={() => setEditingRole(null)}>
          <div className={styles.modal} onClick={e => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>Rolle bearbeiten: {editingRole.roleLabel}</h2>
              <button
                className={styles.modalClose}
                onClick={() => setEditingRole(null)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              {editFields.length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>Lade Formular...</span>
                </div>
              ) : (
                <>
                  <div className={styles.infoBox} style={{ marginBottom: '1rem' }}>
                    <FaUserShield style={{ marginRight: 8 }} />
                    <span>
                      Geltungsbereich: <strong>{editingRole.mandateId ? 'Mandant-spezifisch' : 'Global'}</strong>
                      {' '}(kann nicht geändert werden)
                    </span>
                  </div>
                  <FormGeneratorForm
                    attributes={editFields}
                    data={editingRole}
                    mode="edit"
                    onSubmit={handleEditRole}
                    onCancel={() => setEditingRole(null)}
                    submitButtonText={isSubmitting ? 'Speichern...' : 'Speichern'}
                    cancelButtonText="Abbrechen"
                  />
                </>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default AdminMandateRolesPage;
