import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { userApi } from '../../services/api';
import { useAuth } from '../../context/AuthContext';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Input from '../../components/ui/Input';
import Modal from '../../components/ui/Modal';
import Badge from '../../components/ui/Badge';
import { Plus, Edit, Trash2, Search, Code, Shield, AlertTriangle, ArrowLeft, Info } from 'lucide-react';
import { Link } from 'react-router-dom';
import type { User, Role } from '../../types';

export default function UserList() {
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(1);
  const [showModal, setShowModal] = useState(false);
  const [editingUser, setEditingUser] = useState<User | null>(null);
  const queryClient = useQueryClient();
  const { refreshUser } = useAuth();

  const { data, isLoading } = useQuery({
    queryKey: ['users', search, page],
    queryFn: () => userApi.getAll({ search: search || undefined, page, limit: 20 }),
  });

  const { data: rolesData } = useQuery({
    queryKey: ['roles'],
    queryFn: () => userApi.getRoles(),
  });

  const deleteMutation = useMutation({
    mutationFn: userApi.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
    },
    onError: (error: any) => {
      alert(error?.message || 'Fehler beim Löschen des Benutzers');
    },
  });

  // Check if user is admin (has Admin role)
  const isUserAdmin = (user: User) => {
    return user.roles?.some((role: any) => role.name === 'Admin');
  };

  // Count active admins
  const activeAdminCount = data?.data?.filter(
    (u) => (u as any).isActive && isUserAdmin(u)
  ).length || 0;

  const handleEdit = (user: User) => {
    setEditingUser(user);
    setShowModal(true);
  };

  const handleClose = () => {
    setShowModal(false);
    setEditingUser(null);
  };

  return (
    <div>
      <div className="flex items-center gap-4 mb-6">
        <Link to="/settings">
          <Button variant="ghost" size="sm">
            <ArrowLeft className="w-4 h-4" />
          </Button>
        </Link>
        <h1 className="text-2xl font-bold flex-1">Benutzer</h1>
        <Button onClick={() => setShowModal(true)}>
          <Plus className="w-4 h-4 mr-2" />
          Neuer Benutzer
        </Button>
      </div>

      <Card className="mb-6">
        <div className="flex gap-4">
          <div className="flex-1">
            <Input
              placeholder="Suchen..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
          </div>
          <Button variant="secondary">
            <Search className="w-4 h-4" />
          </Button>
        </div>
      </Card>

      <div className="mb-6 bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start gap-3">
        <Info className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
        <div className="text-sm text-blue-800">
          <strong>Hinweis:</strong> Bei Änderungen an Rollen oder Berechtigungen wird der betroffene Benutzer automatisch ausgeloggt und muss sich erneut anmelden.
        </div>
      </div>

      <Card>
        {isLoading ? (
          <div className="text-center py-8 text-gray-500">Laden...</div>
        ) : data?.data && data.data.length > 0 ? (
          <>
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead>
                  <tr className="border-b">
                    <th className="text-left py-3 px-4 font-medium text-gray-600">Name</th>
                    <th className="text-left py-3 px-4 font-medium text-gray-600">E-Mail</th>
                    <th className="text-left py-3 px-4 font-medium text-gray-600">Rollen</th>
                    <th className="text-left py-3 px-4 font-medium text-gray-600">Status</th>
                    <th className="text-right py-3 px-4 font-medium text-gray-600">Aktionen</th>
                  </tr>
                </thead>
                <tbody>
                  {data.data.map((user) => (
                    <tr key={user.id} className="border-b hover:bg-gray-50">
                      <td className="py-3 px-4">
                        {user.firstName} {user.lastName}
                      </td>
                      <td className="py-3 px-4">{user.email}</td>
                      <td className="py-3 px-4">
                        <div className="flex gap-1 flex-wrap">
                          {user.roles?.filter((role: any) => !['Developer', 'Kunde', 'DSGVO', 'Audit-Betrieb'].includes(role.name)).map((role: any) => (
                            <Badge key={role.id || role.name} variant="info">
                              {role.name}
                            </Badge>
                          ))}
                        </div>
                      </td>
                      <td className="py-3 px-4">
                        <div className="flex gap-2">
                          <Badge variant={(user as any).isActive ? 'success' : 'danger'}>
                            {(user as any).isActive ? 'Aktiv' : 'Inaktiv'}
                          </Badge>
                          {(user as any).hasDeveloperAccess && (
                            <Badge variant="warning" className="flex items-center gap-1">
                              <Code className="w-3 h-3" />
                              Dev
                            </Badge>
                          )}
                          {(user as any).hasGdprAccess && (
                            <Badge variant="info" className="flex items-center gap-1">
                              <Shield className="w-3 h-3" />
                              DSGVO
                            </Badge>
                          )}
                        </div>
                      </td>
                      <td className="py-3 px-4 text-right">
                        <div className="flex justify-end gap-2">
                          <Button variant="ghost" size="sm" onClick={() => handleEdit(user)}>
                            <Edit className="w-4 h-4" />
                          </Button>
                          {(() => {
                            const isLastAdmin = isUserAdmin(user) && (user as any).isActive && activeAdminCount <= 1;
                            return (
                              <Button
                                variant="ghost"
                                size="sm"
                                disabled={isLastAdmin}
                                title={isLastAdmin ? 'Letzter Administrator kann nicht gelöscht werden' : undefined}
                                onClick={() => {
                                  if (confirm('Benutzer wirklich löschen?')) {
                                    deleteMutation.mutate(user.id);
                                  }
                                }}
                              >
                                <Trash2 className={`w-4 h-4 ${isLastAdmin ? 'text-gray-300' : 'text-red-500'}`} />
                              </Button>
                            );
                          })()}
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            {data.pagination && data.pagination.totalPages > 1 && (
              <div className="mt-4 flex items-center justify-between">
                <p className="text-sm text-gray-500">
                  Seite {data.pagination.page} von {data.pagination.totalPages}
                </p>
                <div className="flex gap-2">
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => setPage((p) => Math.max(1, p - 1))}
                    disabled={page === 1}
                  >
                    Zurück
                  </Button>
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => setPage((p) => p + 1)}
                    disabled={page >= data.pagination.totalPages}
                  >
                    Weiter
                  </Button>
                </div>
              </div>
            )}
          </>
        ) : (
          <div className="text-center py-8 text-gray-500">Keine Benutzer gefunden.</div>
        )}
      </Card>

      <UserModal
        isOpen={showModal}
        onClose={handleClose}
        user={editingUser}
        roles={rolesData?.data || []}
        onUserUpdated={refreshUser}
      />
    </div>
  );
}

function UserModal({
  isOpen,
  onClose,
  user,
  roles,
  onUserUpdated,
}: {
  isOpen: boolean;
  onClose: () => void;
  user: User | null;
  roles: Role[];
  onUserUpdated: () => Promise<void>;
}) {
  const queryClient = useQueryClient();
  const [error, setError] = useState<string | null>(null);
  const [formData, setFormData] = useState({
    email: '',
    password: '',
    // Pentest 47.3: bei Passwort-Änderung muss der aufrufende Admin sein
    // eigenes Passwort zur Bestätigung mitsenden (Re-Auth gegen Token-Klau).
    currentPassword: '',
    firstName: '',
    lastName: '',
    roleIds: [] as number[],
    isActive: true,
    hasDeveloperAccess: false,
    hasAuditOpsAccess: false,
    hasGdprAccess: false,
    isServiceAccount: false,
    whatsappNumber: '',
    telegramUsername: '',
    signalNumber: '',
  });

  // Reset form when modal opens or user changes
  useEffect(() => {
    if (isOpen) {
      setError(null);
      if (user) {
        setFormData({
          email: user.email,
          password: '',
          currentPassword: '',
          firstName: user.firstName,
          lastName: user.lastName,
          roleIds: user.roles?.filter((r: any) => !['Developer', 'Kunde', 'DSGVO', 'Audit-Betrieb'].includes(r.name)).map((r: any) => r.id) || [],
          isActive: (user as any).isActive ?? true,
          hasDeveloperAccess: (user as any).hasDeveloperAccess ?? false,
          hasAuditOpsAccess: (user as any).hasAuditOpsAccess ?? false,
          hasGdprAccess: (user as any).hasGdprAccess ?? false,
          isServiceAccount: (user as any).isServiceAccount ?? false,
          whatsappNumber: (user as any).whatsappNumber || '',
          telegramUsername: (user as any).telegramUsername || '',
          signalNumber: (user as any).signalNumber || '',
        });
      } else {
        setFormData({
          email: '',
          password: '',
          currentPassword: '',
          firstName: '',
          lastName: '',
          roleIds: [],
          isActive: true,
          hasDeveloperAccess: false,
    hasAuditOpsAccess: false,
          hasGdprAccess: false,
          isServiceAccount: false,
          whatsappNumber: '',
          telegramUsername: '',
          signalNumber: '',
        });
      }
    }
  }, [isOpen, user]);

  const createMutation = useMutation({
    mutationFn: userApi.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
      onClose();
    },
    onError: (err: any) => {
      setError(err?.message || 'Fehler beim Erstellen des Benutzers');
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: any) => userApi.update(user!.id, data),
    onSuccess: async () => {
      queryClient.invalidateQueries({ queryKey: ['users'] });
      await onUserUpdated(); // Refresh current user's permissions and wait for it
      onClose();
    },
    onError: (err: any) => {
      setError(err?.message || 'Fehler beim Aktualisieren des Benutzers');
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (user) {
      const updateData: any = {
        email: formData.email,
        firstName: formData.firstName,
        lastName: formData.lastName,
        roleIds: formData.roleIds,
        isActive: formData.isActive,
        hasDeveloperAccess: formData.hasDeveloperAccess,
        hasAuditOpsAccess: formData.hasAuditOpsAccess,
        hasGdprAccess: formData.hasGdprAccess,
        isServiceAccount: formData.isServiceAccount,
        // Das Kennzeichen senkt die Alarmstufe der Anmeldungen dieses Kontos.
        // Der Server verlangt dafür eine ausdrückliche Bestätigung; der Haken
        // im Formular IST diese Bestätigung.
        // Das Kennzeichen senkt bzw. hebt die Bewertung der Anmeldungen dieses
        // Kontos. Der Server verlangt in BEIDE Richtungen eine ausdrückliche
        // Bestätigung; der Haken im Formular ist diese Bestätigung.
        confirm: 'SERVICE_ACCOUNT',
        whatsappNumber: formData.whatsappNumber || undefined,
        telegramUsername: formData.telegramUsername || undefined,
        signalNumber: formData.signalNumber || undefined,
      };
      // Passwort-Setzen ist serverseitig ein eigener Endpoint (separater
      // Audit-Eintrag). Wenn beides gefragt: erst Daten, dann PW.
      if (formData.password) {
        if (!formData.currentPassword) {
          setError('Bitte das eigene Passwort zur Bestätigung eingeben.');
          return;
        }
        updateMutation.mutate(updateData, {
          onSuccess: () => {
            // Der axios-Response-Interceptor wirft `.response` weg und
            // legt die Backend-Meldung nach `err.message` – deshalb hier
            // nicht `err.response.data.error` lesen, sonst sieht der
            // Admin nur den Fallback und weiß nicht, dass Staff-
            // Passwörter min. 25 Zeichen + Sonderzeichen brauchen.
            userApi.setPassword(user.id, formData.password, formData.currentPassword).catch((err) => {
              alert(err?.message || 'Passwort konnte nicht gesetzt werden');
            });
          },
        });
      } else {
        updateMutation.mutate(updateData);
      }
    } else {
      createMutation.mutate({
        email: formData.email,
        password: formData.password,
        firstName: formData.firstName,
        lastName: formData.lastName,
        roleIds: formData.roleIds,
        hasDeveloperAccess: formData.hasDeveloperAccess,
        hasAuditOpsAccess: formData.hasAuditOpsAccess,
        hasGdprAccess: formData.hasGdprAccess,
        isServiceAccount: formData.isServiceAccount,
        // Das Kennzeichen senkt die Alarmstufe der Anmeldungen dieses Kontos.
        // Der Server verlangt dafür eine ausdrückliche Bestätigung; der Haken
        // im Formular IST diese Bestätigung.
        // Das Kennzeichen senkt bzw. hebt die Bewertung der Anmeldungen dieses
        // Kontos. Der Server verlangt in BEIDE Richtungen eine ausdrückliche
        // Bestätigung; der Haken im Formular ist diese Bestätigung.
        confirm: 'SERVICE_ACCOUNT',
        whatsappNumber: formData.whatsappNumber || undefined,
        telegramUsername: formData.telegramUsername || undefined,
        signalNumber: formData.signalNumber || undefined,
      });
    }
  };

  const handleRoleToggle = (roleId: number) => {
    setFormData((prev) => ({
      ...prev,
      roleIds: prev.roleIds.includes(roleId)
        ? prev.roleIds.filter((id) => id !== roleId)
        : [...prev.roleIds, roleId],
    }));
  };

  const isLoading = createMutation.isPending || updateMutation.isPending;

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={user ? 'Benutzer bearbeiten' : 'Neuer Benutzer'}
    >
      <form onSubmit={handleSubmit} className="space-y-4">
        {error && (
          <div className="bg-red-50 border border-red-200 rounded-lg p-3 flex items-start gap-2">
            <AlertTriangle className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5" />
            <p className="text-red-700 text-sm">{error}</p>
          </div>
        )}
        <div className="grid grid-cols-2 gap-4">
          <Input
            label="Vorname *"
            value={formData.firstName}
            onChange={(e) => setFormData({ ...formData, firstName: e.target.value })}
            required
          />
          <Input
            label="Nachname *"
            value={formData.lastName}
            onChange={(e) => setFormData({ ...formData, lastName: e.target.value })}
            required
          />
        </div>

        <Input
          label="E-Mail *"
          type="email"
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
          required
        />

        <div>
          <Input
            label={user ? 'Neues Passwort (leer = unverändert)' : 'Passwort *'}
            type="password"
            value={formData.password}
            onChange={(e) => setFormData({ ...formData, password: e.target.value })}
            required={!user}
          />
          <p className="text-xs text-gray-500 mt-1">
            Mind. 25 Zeichen, Groß-/Kleinbuchstabe, Ziffer, Sonderzeichen.
          </p>
        </div>

        {user && formData.password && (
          <div>
            <Input
              label="Eigenes Passwort zur Bestätigung *"
              type="password"
              value={formData.currentPassword}
              onChange={(e) => setFormData({ ...formData, currentPassword: e.target.value })}
              required
              autoComplete="current-password"
            />
            <p className="text-xs text-gray-500 mt-1">
              Sicherheitsmaßnahme: bestätige mit deinem eigenen Login-Passwort,
              dass diese Änderung wirklich von dir kommt.
            </p>
          </div>
        )}

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">Messaging-Kanäle (für Datenschutz-Versand)</label>
          <div className="space-y-3">
            <Input
              label="WhatsApp-Nummer"
              placeholder="+49..."
              value={formData.whatsappNumber}
              onChange={(e) => setFormData({ ...formData, whatsappNumber: e.target.value })}
            />
            <Input
              label="Telegram-Benutzername"
              placeholder="@username"
              value={formData.telegramUsername}
              onChange={(e) => setFormData({ ...formData, telegramUsername: e.target.value })}
            />
            <Input
              label="Signal-Nummer"
              placeholder="+49..."
              value={formData.signalNumber}
              onChange={(e) => setFormData({ ...formData, signalNumber: e.target.value })}
            />
          </div>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-2">Rollen</label>
          <div className="space-y-2">
            {roles.filter((role) => !['Developer', 'Kunde', 'DSGVO', 'Audit-Betrieb'].includes(role.name)).map((role) => (
              <label key={role.id} className="flex items-center gap-2">
                <input
                  type="checkbox"
                  checked={formData.roleIds.includes(role.id)}
                  onChange={() => handleRoleToggle(role.id)}
                  className="rounded"
                />
                <span>{role.name}</span>
                {role.description && (
                  <span className="text-sm text-gray-500">({role.description})</span>
                )}
              </label>
            ))}
          </div>
          <label className="block text-sm font-medium text-gray-700 mt-4 mb-2">Zusätzliche Berechtigungen</label>
          <div className="space-y-2">
            <label className="flex items-start gap-2">
              <input
                type="checkbox"
                checked={formData.isServiceAccount}
                onChange={(e) => setFormData({ ...formData, isServiceAccount: e.target.checked })}
                className="mt-1 rounded border-blue-300 text-blue-600 focus:ring-blue-500"
              />
              <span>
                <span className="font-medium">Dienstkonto</span>
                <span className="block text-sm text-gray-500">
                  Für Konten, die sich planmäßig und regelmäßig anmelden – etwa das Gegenbuch.
                  Ihre Anmeldungen erscheinen im Audit-Log als Routine statt als kritisches
                  Ereignis. Dafür wird gemeldet, wenn ein solches Konto <em>ausbleibt</em>.
                </span>
              </span>
            </label>
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={formData.hasGdprAccess}
                onChange={(e) => setFormData({ ...formData, hasGdprAccess: e.target.checked })}
                className="rounded border-blue-300 text-blue-600 focus:ring-blue-500"
              />
              <span className="flex items-center gap-1">
                <Shield className="w-4 h-4 text-blue-600" />
                DSGVO-Zugriff
              </span>
              <span className="text-sm text-gray-500">(Audit-Protokoll lesen, Datenschutz)</span>
            </label>
            <label className="flex items-start gap-2">
              <input
                type="checkbox"
                checked={formData.hasAuditOpsAccess}
                onChange={(e) => setFormData({ ...formData, hasAuditOpsAccess: e.target.checked })}
                className="mt-1 rounded border-amber-300 text-amber-600 focus:ring-amber-500"
              />
              <span>
                <span className="flex items-center gap-1">
                  <Shield className="w-4 h-4 text-amber-600" />
                  Audit-Betrieb
                  <span className="text-sm text-gray-500">(versiegeln, aufräumen, Aufbewahrung)</span>
                </span>
                <span className="block text-sm text-gray-500 mt-0.5">
                  Erlaubt Eingriffe am Audit-Protokoll: Bestandssiegel setzen oder
                  ersetzen, aufräumen, Aufbewahrungsfristen ändern. Bewusst getrennt
                  vom DSGVO-Zugriff – wer das Protokoll beaufsichtigt, soll seine
                  eigene Beweisgrundlage nicht ersetzen können.
                </span>
              </span>
            </label>
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={formData.hasDeveloperAccess}
                onChange={(e) => setFormData({ ...formData, hasDeveloperAccess: e.target.checked })}
                className="rounded border-purple-300 text-purple-600 focus:ring-purple-500"
              />
              <span className="flex items-center gap-1">
                <Code className="w-4 h-4 text-purple-600" />
                Entwicklerzugriff
              </span>
              <span className="text-sm text-gray-500">(Datenbanktools)</span>
            </label>
          </div>
          {user && (
            <p className="mt-2 text-xs text-amber-600 flex items-center gap-1">
              <AlertTriangle className="w-3 h-3" />
              Bei Rollenänderung wird der Benutzer automatisch ausgeloggt.
            </p>
          )}
        </div>

        {user && (
          <div className="space-y-3 pt-3 border-t">
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={formData.isActive}
                onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
                className="rounded"
              />
              Aktiv
            </label>
          </div>
        )}

        <div className="flex justify-end gap-2">
          <Button type="button" variant="secondary" onClick={onClose}>
            Abbrechen
          </Button>
          <Button type="submit" disabled={isLoading}>
            {isLoading ? 'Speichern...' : 'Speichern'}
          </Button>
        </div>
      </form>
    </Modal>
  );
}
