/**
 * InstanceDetailModal
 *
 * Modal for a feature instance: Benutzer (PermissionMatrix), Rollen (sync), Einstellungen.
 */

import React, { useState, useEffect, useMemo } from 'react';
import { useFeatureAccess, type FeatureInstance, type FeatureAccessUser } from '../../hooks/useFeatureAccess';
import { FormGeneratorForm, type AttributeDefinition } from '../../components/FormGenerator/FormGeneratorForm';
import { Tabs } from '../../components/UiComponents/Tabs';
import { FaSync } from 'react-icons/fa';
import { useToast } from '../../contexts/ToastContext';
import api from '../../api';
import { PermissionMatrix } from './PermissionMatrix';
import styles from './Admin.module.css';
import modalStyles from './InstanceDetailModal.module.css';

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

export interface InstanceDetailModalProps {
  instance: FeatureInstance;
  mandateId: string;
  mandateName: string;
  featureLabel: string;
  onClose: () => void;
  onSaved: () => void;
}

export const InstanceDetailModal: React.FC<InstanceDetailModalProps> = ({ instance,
  mandateId,
  mandateName,
  featureLabel,
  onClose,
  onSaved,
}) => {
  const {
    fetchInstanceUsers,
    fetchInstanceRoles,
    addUserToInstance,
    removeUserFromInstance,
    updateInstanceUserRoles,
    syncInstanceRoles,
    updateInstance,
  } = useFeatureAccess();
  const { showSuccess, showError } = useToast();
  const { t } = useLanguage();

  const [users, setUsers] = useState<FeatureAccessUser[]>([]);
  const [roles, setRoles] = useState<Array<{ id: string; roleLabel: string }>>([]);
  const [allUsers, setAllUsers] = useState<Array<{ id: string; username: string; email?: string }>>([]);
  const [loading, setLoading] = useState(true);
  const [showAddModal, setShowAddModal] = useState(false);
  const [editingUser, setEditingUser] = useState<FeatureAccessUser | null>(null);
  const [syncing, setSyncing] = useState(false);
  const [roleOptions, setRoleOptions] = useState<AttributeDefinition['options']>([]);

  const loadData = () => {
    setLoading(true);
    Promise.all([
      fetchInstanceUsers(mandateId, instance.id),
      fetchInstanceRoles(mandateId, instance.id),
    ])
      .then(([userList, roleList]) => {
        setUsers(Array.isArray(userList) ? userList : []);
        setRoles(Array.isArray(roleList) ? roleList : []);
        setRoleOptions(
          (Array.isArray(roleList) ? roleList : []).map((r) => ({
            value: r.id,
            label: r.roleLabel,
          }))
        );
      })
      .catch(() => {
        setUsers([]);
        setRoles([]);
        setRoleOptions([]);
      })
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    loadData();
  }, [mandateId, instance.id]);

  useEffect(() => {
    api
      .get(`/api/mandates/${mandateId}/users`)
      .then((res) => {
        const data = res.data?.items || res.data || [];
        setAllUsers(
          Array.isArray(data)
            ? data.map((u: { userId: string; username: string; email?: string }) => ({
                id: u.userId,
                username: u.username,
                email: u.email,
              }))
            : []
        );
      })
      .catch(() => setAllUsers([]));
  }, [mandateId]);

  const availableUsers = useMemo(() => {
    const ids = new Set(users.map((u) => u.userId));
    return allUsers.filter((u) => !ids.has(u.id));
  }, [allUsers, users]);

  const handleAddUser = async (data: { userId: string; roleIds: string[] }) => {
    const result = await addUserToInstance(mandateId, instance.id, {
      userId: data.userId,
      roleIds: data.roleIds,
    });
    if (result.success) {
      setShowAddModal(false);
      loadData();
      onSaved();
      showSuccess(t('Benutzer hinzugefügt'), t('Der Benutzer wurde der Instanz hinzugefügt.'));
    } else {
      showError(t('Fehler'), result.error || t('Fehler beim Hinzufügen'));
    }
  };

  const handleRemoveUser = async (user: FeatureAccessUser) => {
    const result = await removeUserFromInstance(mandateId, instance.id, user.userId);
    if (result.success) {
      loadData();
      onSaved();
      showSuccess(t('Benutzer entfernt'), t('"{name}" wurde entfernt.', { name: user.username }));
    } else {
      showError(t('Fehler'), result.error || t('Fehler beim Entfernen'));
    }
  };

  const handleEditUser = (user: FeatureAccessUser) => {
    setEditingUser(user);
  };

  const handleUpdateRoles = async (data: { roleIds: string[]; enabled?: boolean }) => {
    if (!editingUser) return;
    const result = await updateInstanceUserRoles(mandateId, instance.id, editingUser.userId, {
      roleIds: data.roleIds,
      enabled: data.enabled,
    });
    if (result.success) {
      setEditingUser(null);
      loadData();
      onSaved();
      showSuccess(t('Aktualisiert'), t('Rollen und Status wurden gespeichert.'));
    } else {
      showError(t('Fehler'), result.error || t('Fehler beim Speichern'));
    }
  };

  const handleSyncRoles = async () => {
    setSyncing(true);
    try {
      const result = await syncInstanceRoles(mandateId, instance.id, true);
      if (result.success && result.data) {
        loadData();
        onSaved();
        showSuccess(
          t('Rollen synchronisiert'),
          t('Hinzugefügt: {added}, Entfernt: {removed}', { added: result.data.added, removed: result.data.removed })
        );
      } else {
        showError(t('Fehler'), result.error || t('Synchronisierung fehlgeschlagen'));
      }
    } finally {
      setSyncing(false);
    }
  };

  const handleUpdateInstance = async (data: { label?: string; enabled?: boolean }) => {
    const result = await updateInstance(mandateId, instance.id, data);
    if (result.success) {
      onSaved();
      showSuccess(t('Instanz aktualisiert'), t('Einstellungen wurden gespeichert.'));
    } else {
      showError(t('Fehler'), result.error || t('Fehler beim Speichern'));
    }
  };

  const addUserFields: AttributeDefinition[] = useMemo(
    () => [
      {
        name: 'userId',
        label: t('Benutzer'),
        type: 'enum' as const,
        required: true,
        options: availableUsers.map((u) => ({
          value: u.id,
          label: `${u.username}${u.email ? ` (${u.email})` : ''}`,
        })),
      },
      {
        name: 'roleIds',
        label: t('Rollen'),
        type: 'multiselect' as const,
        required: true,
        options: roleOptions as AttributeDefinition['options'],
      },
    ],
    [availableUsers, roleOptions, t]
  );

  const editRolesFields: AttributeDefinition[] = useMemo(
    () => [
      {
        name: 'roleIds',
        label: t('Rollen'),
        type: 'multiselect' as const,
        required: true,
        options: roleOptions as AttributeDefinition['options'],
      },
      {
        name: 'enabled',
        label: t('Aktiv'),
        type: 'checkbox' as const,
        required: false,
      },
    ],
    [roleOptions, t]
  );

  const tabs = [
    {
      id: 'users',
      label: t('Benutzer'),
      content: (
        <div className={modalStyles.tabContent}>
          {loading ? (
            <div className={styles.loadingContainer}>
              <div className={styles.spinner} />
              <span>{t('Lade Benutzer')}</span>
            </div>
          ) : (
            <PermissionMatrix
              users={users}
              roles={roles}
              onEditUser={handleEditUser}
              onRemoveUser={handleRemoveUser}
              onAddUser={() => setShowAddModal(true)}
            />
          )}
        </div>
      ),
    },
    {
      id: 'roles',
      label: t('Rollen'),
      content: (
        <div className={modalStyles.tabContent}>
          <p className={modalStyles.rolesIntro}>
            {t('Rollen werden von der Feature-Vorlage übernommen. Mit „Synchronisieren“ können Sie fehlende Rollen nachziehen.')}
          </p>
          <ul className={modalStyles.rolesList}>
            {roles.map((r) => (
              <li key={r.id}>{r.roleLabel}</li>
            ))}
          </ul>
          <button
            type="button"
            className={styles.secondaryButton}
            onClick={handleSyncRoles}
            disabled={syncing || roles.length === 0}
          >
            <FaSync className={syncing ? 'spinning' : ''} /> {t('Rollen synchronisieren')}
          </button>
        </div>
      ),
    },
    {
      id: 'settings',
      label: t('Einstellungen'),
      content: (
        <div className={modalStyles.tabContent}>
          <FormGeneratorForm
            attributes={[
              { name: 'label', type: 'string' as const, label: t('Bezeichnung'), required: true, editable: true },
              { name: 'enabled', type: 'boolean' as const, label: t('Aktiviert'), required: false, editable: true },
            ]}
            data={instance}
            mode="edit"
            onSubmit={handleUpdateInstance}
            submitButtonText={t('Speichern')}
            cancelButtonText={t('Abbrechen')}
            onCancel={() => {}}
          />
        </div>
      ),
    },
  ];

  return (
    <div className={styles.modalOverlay} onClick={onClose}>
      <div className={`${styles.modal} ${modalStyles.modal}`} onClick={(e) => e.stopPropagation()}>
        <div className={styles.modalHeader}>
          <div>
            <h2 className={styles.modalTitle}>{instance.label}</h2>
            <p className={modalStyles.subtitle}>
              {mandateName} · {featureLabel}
            </p>
          </div>
          <button type="button" className={styles.modalClose} onClick={onClose} aria-label={t('Schließen')}>
            ✕
          </button>
        </div>
        <div className={styles.modalContent}>
          <Tabs tabs={tabs} defaultTabId="users" />
        </div>
      </div>

      {showAddModal && (
        <div className={styles.modalOverlay} onClick={() => setShowAddModal(false)}>
          <div className={styles.modal} onClick={(e) => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>{t('Benutzer hinzufügen')}</h2>
              <button type="button" className={styles.modalClose} onClick={() => setShowAddModal(false)}>
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              {availableUsers.length === 0 ? (
                <p>{t('Alle Mandantenbenutzer haben bereits Zugriff')}</p>
              ) : addUserFields.length < 2 || !roleOptions?.length ? (
                <p>{t('Laden')}</p>
              ) : (
                <FormGeneratorForm
                  attributes={addUserFields}
                  mode="create"
                  onSubmit={handleAddUser}
                  onCancel={() => setShowAddModal(false)}
                  submitButtonText={t('Hinzufügen')}
                  cancelButtonText={t('Abbrechen')}
                />
              )}
            </div>
          </div>
        </div>
      )}

      {editingUser && (
        <div className={styles.modalOverlay} onClick={() => setEditingUser(null)}>
          <div className={styles.modal} onClick={(e) => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>
                {t('Rollen')}: {editingUser.username}
              </h2>
              <button type="button" className={styles.modalClose} onClick={() => setEditingUser(null)}>
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              <FormGeneratorForm
                attributes={editRolesFields}
                data={{ roleIds: editingUser.roleIds, enabled: editingUser.enabled }}
                mode="edit"
                onSubmit={handleUpdateRoles}
                onCancel={() => setEditingUser(null)}
                submitButtonText={t('Speichern')}
                cancelButtonText={t('Abbrechen')}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default InstanceDetailModal;
