/**
 * 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 { useNavigate } from 'react-router-dom';
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, FaShieldAlt, FaCube } from 'react-icons/fa';
import { useToast } from '../../contexts/ToastContext';
import { useApiRequest } from '../../hooks/useApi';
import { fetchAttributes } from '../../api/attributesApi';
import { resolveColumnTypes } from '../../utils/columnTypeResolver';
import type { ColumnConfig } from '../../components/FormGenerator/FormGeneratorTable';
import styles from './Admin.module.css';

import { useLanguage } from '../../providers/language/LanguageContext';
import { mandateDisplayLabel } from '../../utils/mandateDisplayUtils';

export const AdminMandateRolesPage: React.FC = () => {
    const { t, currentLanguage } = useLanguage();

  const navigate = useNavigate();
  const { request } = useApiRequest();
  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'>('mandate');
  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();
    fetchAttributes(request, 'RoleView')
      .then(setBackendAttributes)
      .catch(() => setBackendAttributes([]));
  }, [fetchMandates, request]);

  // 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]);

  const getDescriptionText = (desc: any) => {
    if (!desc) return '-';
    if (typeof desc === 'string') return desc;
    if (typeof desc === 'object') {
      return desc[currentLanguage] || desc['xx'] || Object.values(desc).find((v: any) => typeof v === 'string' && v.trim()) || '-';
    }
    return String(desc);
  };

  const _rawColumns: ColumnConfig[] = useMemo(() => [
    { key: 'roleLabel', sortable: true, filterable: true, searchable: true, width: 150 },
    {
      key: 'description',
      sortable: false,
      filterable: false,
      width: 250,
      formatter: (value: string) => getDescriptionText(value),
    },
    { key: 'scopeType', sortable: true, filterable: true, width: 160 },
    { key: 'userCount', sortable: true, filterable: true, width: 100 },
  ], []);

  const columns = useMemo(
    () => resolveColumnTypes(_rawColumns, backendAttributes),
    [_rawColumns, backendAttributes],
  );

  // 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: t('Geltungsbereich'),
        type: 'enum' as any,
        required: true,
        default: 'mandate',
        options: [
          { value: 'mandate', label: t('Nur dieser Mandant') },
          { value: 'global', label: t('Template bei neuen Mandanten') },
        ]
      });
    }
    return fields;
  }, [backendAttributes, t]);

  // 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?: Record<string, string>; scope: 'mandate' | 'global' }) => {
    if (!selectedMandateId) return;
    setIsSubmitting(true);
    try {
      const roleData: RoleCreate = {
        roleLabel: data.roleLabel.toLowerCase().replace(/\s+/g, '_'),
        description: data.description,
        mandateId: data.scope === 'mandate' ? selectedMandateId : undefined
      };
      
      const result = await createRole(roleData, selectedMandateId);
      
      if (result.success) {
        setShowCreateModal(false);
        await fetchRoles(selectedMandateId, { scopeFilter });
      } else {
        showError(t('Fehler'), result.error || t('Fehler beim Erstellen der Rolle'));
      }
    } catch (err: any) {
      console.error('Create role error:', err);
      showError(t('Fehler'), err.message || t('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 {
      // 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: data.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(t('Fehler'), result.error || t('Fehler beim Aktualisieren der Rolle'));
      }
    } catch (err: any) {
      console.error('Update role error:', err);
      showError(t('Fehler'), err.message || t('Fehler beim Aktualisieren der Rolle'));
    } finally {
      setIsSubmitting(false);
    }
  };

  // Handle delete role (confirmation handled by DeleteActionButton)
  const handleDeleteRole = async (role: Role) => {
    if (role.isSystemRole) {
      showWarning(t('Nicht erlaubt'), t('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(t('Fehler'), result.error || t('Fehler beim Löschen der Rolle'));
    }
  };

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

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

  return (
    <div className={`${styles.adminPage} ${styles.adminPageFill}`}>
      <div className={styles.pageHeader}>
        <div>
          <h1 className={styles.pageTitle}>{t('Rollen')}</h1>
          <p className={styles.pageSubtitle}>{t('Verwalten Sie systemweite und globale')}</p>
        </div>
        <div className={styles.headerActions}>
          <button
            type="button"
            className={styles.secondaryButton}
            onClick={() => navigate('/admin/mandate-role-permissions')}
          >
            <FaShieldAlt /> {t('Rollen-Berechtigungen')}
          </button>
          <button
            type="button"
            className={styles.secondaryButton}
            onClick={() => navigate('/admin/feature-roles')}
          >
            <FaCube /> {t('Feature Rollen & Rechte')}
          </button>
        </div>
      </div>

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

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

      {/* Info Box */}
      {selectedMandateId && (
        <div className={styles.infoBox}>
          <FaUserShield style={{ marginRight: 8 }} />
          <span>
            <strong>{t('System-Templates')}</strong>{' '}
            {t('(admin, user, viewer) werden bei der Mandant-Erstellung automatisch als Mandanten-Instanz-Rollen kopiert. Templates selbst können nicht gelöscht werden.')}{' '}
            <strong>{t('Mandanten-Rollen')}</strong>{' '}
            {t('gelten nur für den ausgewählten Mandanten und sind den Benutzern zuweisbar.')}
          </span>
        </div>
      )}

      {/* Content */}
      {!selectedMandateId ? (
        <div className={styles.emptyState}>
          <FaBuilding className={styles.emptyIcon} />
          <h3 className={styles.emptyTitle}>{t('Kein Mandant ausgewählt')}</h3>
          <p className={styles.emptyDescription}>
            {t('Wählen Sie einen Mandanten aus, um dessen Rollen zu verwalten.')}
          </p>
        </div>
      ) : (
        <div className={styles.tableContainer}>
          <FormGeneratorTable
            data={roles}
            columns={columns}
            apiEndpoint="/api/rbac/roles"
            loading={loading}
            pagination={true}
            pageSize={25}
            searchable={true}
            filterable={true}
            sortable={true}
            selectable={true}
            actionButtons={[
              {
                type: 'edit' as const,
                onAction: handleEditClick,
                title: t('Rolle bearbeiten'),
                disabled: (row: Role) => row.isSystemRole ? { disabled: true, message: t('System-Rollen können nicht bearbeitet werden') } : false
              },
              {
                type: 'delete' as const,
                title: t('Rolle löschen'),
                disabled: (row: Role) => row.isSystemRole ? { disabled: true, message: t('System-Rollen können nicht gelöscht werden') } : false
              }
            ]}
            onDelete={handleDeleteRole}
            hookData={{
              refetch: refetchWithParams,
              pagination: pagination,
              handleDelete: handleDeleteRole,
            }}
            emptyMessage={t('Keine Rollen gefunden')}
          />
        </div>
      )}

      {/* Create Role Modal */}
      {showCreateModal && (
        <div className={styles.modalOverlay}>
          <div className={styles.modal}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>{t('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>{t('Lade Formular')}</span>
                </div>
              ) : (
                <FormGeneratorForm
                  attributes={createFields}
                  mode="create"
                  onSubmit={handleCreateRole}
                  onCancel={() => setShowCreateModal(false)}
                  submitButtonText={isSubmitting ? t('Erstelle…') : t('Rolle erstellen')}
                  cancelButtonText={t('Abbrechen')}
                />
              )}
            </div>
          </div>
        </div>
      )}

      {/* Edit Role Modal */}
      {editingRole && (
        <div className={styles.modalOverlay}>
          <div className={styles.modal}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>
                {t('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>{t('Lade Formular')}</span>
                </div>
              ) : (
                <>
                  <div className={styles.infoBox} style={{ marginBottom: '1rem' }}>
                    <FaUserShield style={{ marginRight: 8 }} />
                    <span>
                      {t('Geltungsbereich')}:{' '}
                      <strong>
                        {editingRole.mandateId ? t('Mandanten-Instanz') : t('Template (global)')}
                      </strong>{' '}
                      ({t('kann nicht geändert werden')})
                    </span>
                  </div>
                  <FormGeneratorForm
                    attributes={editFields}
                    data={editingRole}
                    mode="edit"
                    onSubmit={handleEditRole}
                    onCancel={() => setEditingRole(null)}
                    submitButtonText={isSubmitting ? t('Speichern') : t('Speichern')}
                    cancelButtonText={t('Abbrechen')}
                  />
                </>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default AdminMandateRolesPage;
