/**
 * 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, FaBuilding, FaCopy, FaLink } 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 AdminInvitationsPage: React.FC = () => {
    const { t } = useLanguage();

  const { showError } = useToast();
  const { request } = useApiRequest();
  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();
    fetchAttributes(request, 'Invitation')
      .then(setBackendAttributes)
      .catch(() => setBackendAttributes([]));
  }, [fetchMandates, request]);

  // 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 (used by URL modal only).
  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'
    });
  };

  const _rawColumns: ColumnConfig[] = useMemo(() => [
    { key: 'targetUsername', sortable: true, filterable: true, searchable: true, width: 150 },
    { key: 'email', sortable: true, filterable: true, width: 180 },
    { key: 'emailSentFlag', sortable: true, filterable: true, width: 90 },
    { key: 'emailSentAt', sortable: true, filterable: true, width: 150 },
    {
      key: 'roleIds',
      sortable: false,
      filterable: false,
      width: 150,
      formatter: (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(', ');
      },
    },
    { key: 'expiresAt', sortable: true, filterable: true, width: 150 },
    { key: 'expiredFlag', sortable: true, filterable: true, width: 90 },
    {
      key: 'currentUses',
      sortable: true,
      filterable: true,
      width: 100,
      formatter: (value: number, row: Invitation) => `${value || 0} / ${row.maxUses || 1}`,
    },
    { key: 'usedUpFlag', sortable: true, filterable: true, width: 90 },
    { key: 'sysCreatedAt', sortable: true, filterable: true, width: 150 },
  ], [roles]);

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

  // Form attributes - same role options as AdminUserMandatesPage (user, viewer, admin)
  const createFields: AttributeDefinition[] = useMemo(() => {
    const excludedFields = ['id', 'mandateId', 'token', 'sysCreatedBy', 'sysCreatedAt', 'sysUpdatedAt', 'sysUpdatedBy', '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: t('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, t]);

  // 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(t('Fehler'), result.error || t('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(t('Fehler'), result.error || t('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);
    }
  };


  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('Einladungen')}</h1>
          <p className={styles.pageSubtitle}>{t('Erstellen und verwalten Sie Einladungen')}</p>
        </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.checkboxLabel}>
            <input
              type="checkbox"
              checked={showExpired}
              onChange={(e) => setShowExpired(e.target.checked)}
            />
            {t('Abgelaufene anzeigen')}
          </label>
          <label className={styles.checkboxLabel}>
            <input
              type="checkbox"
              checked={showUsed}
              onChange={(e) => setShowUsed(e.target.checked)}
            />
            {t('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' : ''} /> {t('Aktualisieren')}
            </button>
            <button
              className={styles.primaryButton}
              onClick={() => setShowCreateModal(true)}
            >
              <FaPlus /> {t('Neue Einladung')}
            </button>
          </div>
        )}
      </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 Einladungen zu verwalten.')}
          </p>
        </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={true}
            actionButtons={[
              {
                type: 'delete' as const,
                title: t('Einladung widerrufen'),
              }
            ]}
            customActions={[
              {
                id: 'showUrl',
                icon: <FaLink />,
                onClick: handleShowUrl,
                title: t('Einladungslink anzeigen'),
              }
            ]}
            hookData={{
              handleDelete: handleDeleteInvitation,
              refetch: (params?: any) => fetchInvitations(params || selectedMandateId, { includeExpired: showExpired, includeUsed: showUsed }),
              pagination,
            }}
            emptyMessage={t('Keine Einladungen gefunden')}
          />
        </div>
      )}

      {/* Create Invitation Modal */}
      {showCreateModal && (
        <div className={styles.modalOverlay}>
          <div className={styles.modal}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>{t('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>{t('Rollen laden')}</span>
                </div>
              ) : createFields.length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>{t('Formular laden')}</span>
                </div>
              ) : (
                <FormGeneratorForm
                  attributes={createFields}
                  mode="create"
                  onSubmit={handleCreateInvitation}
                  onCancel={() => setShowCreateModal(false)}
                  submitButtonText={t('Einladung erstellen')}
                  cancelButtonText={t('Abbrechen')}
                />
              )}
            </div>
          </div>
        </div>
      )}

      {/* URL Display Modal */}
      {showUrlModal && (
        <div className={styles.modalOverlay}>
          <div className={styles.modal}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>{t('Einladungs-Link')}</h2>
              <button
                className={styles.modalClose}
                onClick={() => setShowUrlModal(null)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              <p style={{ marginBottom: '1rem', color: 'var(--text-secondary)' }}>
                {t('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={t('In Zwischenablage kopieren')}
                >
                  <FaCopy />
                  {copySuccess ? ` ${t('Kopiert!')}` : ` ${t('Kopieren')}`}
                </button>
              </div>
              <p style={{ marginTop: '1rem', fontSize: '0.875rem', color: 'var(--text-secondary)' }}>
                {t('Dieser Link kann nur von Benutzer')} <strong>{showUrlModal.targetUsername}</strong>{' '}
                {t('verwendet werden.')}
              </p>
              {showUrlModal.email && (
                <p style={{ marginTop: '0.5rem', fontSize: '0.875rem', color: showUrlModal.emailSentFlag ? 'var(--success-color)' : 'var(--text-secondary)' }}>
                  {showUrlModal.emailSentFlag
                    ? `✓ ${t('E-Mail wurde an {email} gesendet', { email: showUrlModal.email })}`
                    : `${t('E-Mail-Adresse')}: ${showUrlModal.email} (${t('nicht gesendet')})`}
                </p>
              )}
              <p style={{ marginTop: '0.5rem', fontSize: '0.875rem', color: 'var(--text-secondary)' }}>
                {t('Gültig bis')}: {formatDate(showUrlModal.expiresAt)}
              </p>
            </div>
            <div className={styles.modalFooter}>
              <button
                className={styles.primaryButton}
                onClick={() => setShowUrlModal(null)}
              >
                {t('Schliessen')}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default AdminInvitationsPage;
