/**
 * AdminInvitationsPage
 * 
 * Admin page for managing invitations within a mandate.
 * Allows creating, viewing, and revoking invitations.
 */

import React, { useState, useEffect, useMemo } from 'react';
import { useInvitations, type Invitation, type InvitationCreate } from '../../hooks/useInvitations';
import { useUserMandates, type Mandate, type Role } from '../../hooks/useUserMandates';
import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable';
import { FormGeneratorForm, type AttributeDefinition } from '../../components/FormGenerator/FormGeneratorForm';
import { FaPlus, FaSync, FaEnvelopeOpenText, FaBuilding, FaCopy, FaLink } from 'react-icons/fa';
import { useToast } from '../../contexts/ToastContext';
import api from '../../api';
import styles from './Admin.module.css';

export const AdminInvitationsPage: React.FC = () => {
  const { showError } = useToast();
  const {
    invitations,
    loading,
    error,
    pagination,
    fetchInvitations,
    createInvitation,
    revokeInvitation,
  } = useInvitations();

  const { fetchMandates, fetchRoles } = useUserMandates();

  // State
  const [mandates, setMandates] = useState<Mandate[]>([]);
  const [selectedMandateId, setSelectedMandateId] = useState<string>('');
  const [roles, setRoles] = useState<Role[]>([]);
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [showUrlModal, setShowUrlModal] = useState<Invitation | null>(null);
  const [showExpired, setShowExpired] = useState(false);
  const [showUsed, setShowUsed] = useState(false);
  const [_isSubmitting, setIsSubmitting] = useState(false); // Prefixed with _ to suppress warning
  const [copySuccess, setCopySuccess] = useState(false);
  const [backendAttributes, setBackendAttributes] = useState<AttributeDefinition[]>([]);

  // 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 Invitation attributes from backend
    api.get('/api/attributes/Invitation').then(response => {
      const attrs = response.data?.attributes || response.data || [];
      setBackendAttributes(Array.isArray(attrs) ? attrs : []);
    }).catch(() => setBackendAttributes([]));
  }, [fetchMandates]);

  // Load invitations and roles when mandate changes (same roles as AdminUserMandatesPage: user, viewer, admin)
  useEffect(() => {
    if (selectedMandateId) {
      fetchInvitations(selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed });
      fetchRoles(selectedMandateId).then(setRoles);
    }
  }, [selectedMandateId, showExpired, showUsed, fetchInvitations, fetchRoles]);

  // Format timestamp
  const formatDate = (timestamp: number) => {
    if (!timestamp) return '-';
    const date = new Date(timestamp * 1000);
    return date.toLocaleString('de-CH', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  };

  // Table columns
  const columns = useMemo(() => [
    { 
      key: 'targetUsername', 
      label: 'Benutzername', 
      type: 'string' as const, 
      sortable: true, 
      filterable: true, 
      searchable: true, 
      width: 150,
    },
    { 
      key: 'email', 
      label: 'E-Mail', 
      type: 'string' as const, 
      sortable: true, 
      filterable: true, 
      width: 180,
      render: (value: string, row: Invitation) => {
        const emailText = value || '-';
        const emailSent = (row as any).emailSent;
        return (
          <span title={emailSent ? 'Email wurde gesendet' : 'Email nicht gesendet'}>
            {emailText} {emailSent && '✓'}
          </span>
        );
      }
    },
    { 
      key: 'roleIds', 
      label: 'Rollen', 
      type: 'string', // Array rendered as string
      sortable: false, 
      filterable: false, 
      width: 150,
      render: (value: string[]) => {
        if (!value || value.length === 0) return '-';
        return value.map(roleId => {
          const role = roles.find(r => r.id === roleId);
          return role?.roleLabel || roleId;
        }).join(', ');
      }
    } as any,
    { 
      key: 'expiresAt', 
      label: 'Gültig bis', 
      type: 'number' as const, 
      sortable: true, 
      width: 150,
      render: (value: number) => {
        const text = formatDate(value);
        const isExpired = value < Date.now() / 1000;
        return (
          <span style={{ color: isExpired ? 'var(--danger-color)' : 'inherit' }}>
            {text} {isExpired && '(abgelaufen)'}
          </span>
        );
      }
    },
    { 
      key: 'currentUses', 
      label: 'Verwendet', 
      type: 'string' as const, 
      sortable: true, 
      width: 100,
      render: (value: number, row: Invitation) => `${value || 0} / ${row.maxUses || 1}`
    },
    { 
      key: 'createdAt', 
      label: 'Erstellt', 
      type: 'number' as const, 
      sortable: true, 
      width: 150,
      render: (value: number) => formatDate(value)
    },
  ], [roles]);

  // Form attributes - same role options as AdminUserMandatesPage (user, viewer, admin)
  const createFields: AttributeDefinition[] = useMemo(() => {
    const excludedFields = ['id', 'mandateId', 'token', 'createdBy', 'createdAt', 'expiresAt', 'currentUses', 'inviteUrl', 'featureInstanceId'];
    
    // Mandate-level roles (user, viewer, admin) - same as when adding mandate members
    const roleOptions = roles
      .filter(r => !r.featureInstanceId)
      .map(r => ({ value: r.id, label: r.roleLabel }));
    
    const fields = backendAttributes
      .filter(attr => !excludedFields.includes(attr.name))
      .map(attr => ({
        ...attr,
        options: attr.name === 'roleIds' ? roleOptions : attr.options,
      })) as AttributeDefinition[];
    
    // Add helper field expiresInHours if not in model but fields exist
    if (fields.length > 0 && !fields.find(f => f.name === 'expiresInHours')) {
      fields.push({ name: 'expiresInHours', label: 'Gültigkeitsdauer (Stunden)', type: 'number', 
        required: true, default: 72 } as any);
    }
    // Override required for targetUsername and email (both required for invitations)
    return fields.map(f => {
      if (f.name === 'targetUsername' || f.name === 'email') {
        return { ...f, required: true };
      }
      return f;
    });
  }, [roles, backendAttributes]);

  // Handle create invitation
  const handleCreateInvitation = async (data: InvitationCreate) => {
    if (!selectedMandateId) return;
    setIsSubmitting(true);
    try {
      const result = await createInvitation(selectedMandateId, data);
      if (result.success && result.data) {
        setShowCreateModal(false);
        setShowUrlModal(result.data);
        fetchInvitations(selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed });
      } else {
        showError('Fehler', result.error || 'Fehler beim Erstellen der Einladung');
      }
    } finally {
      setIsSubmitting(false);
    }
  };

  // Handle delete invitation by ID (for DeleteActionButton)
  // Note: DeleteActionButton handles confirmation UI, so no window.confirm here
  const handleDeleteInvitation = async (invitationId: string): Promise<boolean> => {
    if (!selectedMandateId) return false;
    const result = await revokeInvitation(selectedMandateId, invitationId);
    if (!result.success) {
      showError('Fehler', result.error || 'Fehler beim Widerrufen der Einladung');
    }
    return result.success;
  };

  // Handle show URL
  const handleShowUrl = (invitation: Invitation) => {
    setShowUrlModal(invitation);
  };

  // Copy URL to clipboard
  const handleCopyUrl = async (url: string) => {
    try {
      await navigator.clipboard.writeText(url);
      setCopySuccess(true);
      setTimeout(() => setCopySuccess(false), 2000);
    } catch (err) {
      console.error('Failed to copy:', err);
    }
  };

  // Get mandate name
  const getMandateName = (mandate: Mandate) => {
    if (mandate.label) return mandate.label;
    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}>Einladungen</h1>
          <p className={styles.pageSubtitle}>Erstellen und verwalten Sie Einladungen für neue Benutzer</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.checkboxLabel}>
            <input
              type="checkbox"
              checked={showExpired}
              onChange={(e) => setShowExpired(e.target.checked)}
            />
            Abgelaufene anzeigen
          </label>
          <label className={styles.checkboxLabel}>
            <input
              type="checkbox"
              checked={showUsed}
              onChange={(e) => setShowUsed(e.target.checked)}
            />
            Verwendete anzeigen
          </label>
        </div>
        
        {selectedMandateId && (
          <div className={styles.headerActions}>
            <button
              className={styles.secondaryButton}
              onClick={() => fetchInvitations(selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed })}
              disabled={loading}
            >
              <FaSync className={loading ? 'spinning' : ''} /> Aktualisieren
            </button>
            <button
              className={styles.primaryButton}
              onClick={() => setShowCreateModal(true)}
            >
              <FaPlus /> Neue Einladung
            </button>
          </div>
        )}
      </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 Einladungen zu verwalten.
          </p>
        </div>
      ) : loading && invitations.length === 0 ? (
        <div className={styles.loadingContainer}>
          <div className={styles.spinner} />
          <span>Lade Einladungen...</span>
        </div>
      ) : invitations.length === 0 ? (
        <div className={styles.emptyState}>
          <FaEnvelopeOpenText className={styles.emptyIcon} />
          <h3 className={styles.emptyTitle}>Keine Einladungen</h3>
          <p className={styles.emptyDescription}>
            Es gibt noch keine aktiven Einladungen für diesen Mandanten.
          </p>
          <button
            className={styles.primaryButton}
            onClick={() => setShowCreateModal(true)}
          >
            <FaPlus /> Erste Einladung erstellen
          </button>
        </div>
      ) : (
        <div className={styles.tableContainer}>
          <FormGeneratorTable
            data={invitations}
            columns={columns}
            apiEndpoint="/api/invitations/"
            loading={loading}
            pagination={true}
            pageSize={25}
            searchable={true}
            filterable={true}
            sortable={true}
            selectable={false}
            actionButtons={[
              {
                type: 'delete' as const,
                title: 'Einladung widerrufen',
              }
            ]}
            customActions={[
              {
                id: 'showUrl',
                icon: <FaLink />,
                onClick: handleShowUrl,
                title: 'Einladungs-Link anzeigen',
              }
            ]}
            hookData={{
              handleDelete: handleDeleteInvitation,
              refetch: () => fetchInvitations(selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed }),
              pagination,
            }}
            emptyMessage="Keine Einladungen gefunden"
          />
        </div>
      )}

      {/* Create Invitation 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 Einladung erstellen</h2>
              <button
                className={styles.modalClose}
                onClick={() => setShowCreateModal(false)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              {roles.filter(r => !r.featureInstanceId).length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>Lade Rollen...</span>
                </div>
              ) : createFields.length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>Lade Formular...</span>
                </div>
              ) : (
                <FormGeneratorForm
                  attributes={createFields}
                  mode="create"
                  onSubmit={handleCreateInvitation}
                  onCancel={() => setShowCreateModal(false)}
                  submitButtonText="Einladung erstellen"
                  cancelButtonText="Abbrechen"
                />
              )}
            </div>
          </div>
        </div>
      )}

      {/* URL Display Modal */}
      {showUrlModal && (
        <div className={styles.modalOverlay} onClick={() => setShowUrlModal(null)}>
          <div className={styles.modal} onClick={e => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>Einladungs-Link</h2>
              <button
                className={styles.modalClose}
                onClick={() => setShowUrlModal(null)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              <p style={{ marginBottom: '1rem', color: 'var(--text-secondary)' }}>
                Einladung für Benutzer <strong>{showUrlModal.targetUsername}</strong>:
              </p>
              <div className={styles.urlBox}>
                <input
                  type="text"
                  readOnly
                  value={showUrlModal.inviteUrl}
                  className={styles.urlInput}
                  onClick={(e) => (e.target as HTMLInputElement).select()}
                />
                <button
                  className={styles.copyButton}
                  onClick={() => handleCopyUrl(showUrlModal.inviteUrl)}
                  title="In Zwischenablage kopieren"
                >
                  <FaCopy />
                  {copySuccess ? ' Kopiert!' : ' Kopieren'}
                </button>
              </div>
              <p style={{ marginTop: '1rem', fontSize: '0.875rem', color: 'var(--text-secondary)' }}>
                Dieser Link kann nur von Benutzer <strong>{showUrlModal.targetUsername}</strong> verwendet werden.
              </p>
              {showUrlModal.email && (
                <p style={{ marginTop: '0.5rem', fontSize: '0.875rem', color: showUrlModal.emailSent ? 'var(--success-color)' : 'var(--text-secondary)' }}>
                  {showUrlModal.emailSent 
                    ? `✓ Email wurde an ${showUrlModal.email} gesendet`
                    : `Email-Adresse: ${showUrlModal.email} (nicht gesendet)`}
                </p>
              )}
              <p style={{ marginTop: '0.5rem', fontSize: '0.875rem', color: 'var(--text-secondary)' }}>
                Gültig bis: {formatDate(showUrlModal.expiresAt)}
              </p>
            </div>
            <div className={styles.modalFooter}>
              <button
                className={styles.primaryButton}
                onClick={() => setShowUrlModal(null)}
              >
                Schliessen
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default AdminInvitationsPage;
