/**
 * InvitePage
 * 
 * Public page for accepting invitations via email link.
 * URL: /invite/:token
 * 
 * This page is primarily used for NEW users who receive an invitation email
 * and need to register first.
 * 
 * Flow for NEW users (via email link):
 * 1. User opens email link → lands here
 * 2. Token is validated and stored in localStorage
 * 3. User clicks "Registrieren" → redirects to /register
 * 4. After registration, user logs in
 * 5. Login page checks localStorage, redirects back here
 * 6. User clicks "Einladung annehmen"
 * 
 * For EXISTING users:
 * The in-app notification system handles invitations directly.
 * When an invitation is created for an existing user, a notification
 * appears in their notification bell with accept/decline buttons.
 */

import React, { useState, useEffect } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import { useInvitations, type InvitationValidation } from '../hooks/useInvitations';
import api from '../api';
import { getUserDataCache } from '../utils/userCache';
import { FaCheckCircle, FaTimesCircle, FaSpinner, FaSignInAlt, FaUserPlus } from 'react-icons/fa';
import styles from './InvitePage.module.css';

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

// Key for storing pending invitation token
export const PENDING_INVITATION_KEY = 'pendingInvitationToken';

export const InvitePage: React.FC = () => {
    const { t } = useLanguage();

  const { token } = useParams<{ token: string }>();
  const navigate = useNavigate();
  const { validateInvitation, acceptInvitation } = useInvitations();
  
  // Check if user has an active session
  const isAuthenticated = !!sessionStorage.getItem('auth_authority');

  // State
  const [validation, setValidation] = useState<InvitationValidation | null>(null);
  const [validating, setValidating] = useState(true);
  const [accepting, setAccepting] = useState(false);
  const [success, setSuccess] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [userMismatch, setUserMismatch] = useState(false);
  const [userExists, setUserExists] = useState<boolean | null>(null);

  // Validate token on mount
  useEffect(() => {
    const validate = async () => {
      if (!token) {
        setError(t('Kein Einladungstoken angegeben'));
        setValidating(false);
        return;
      }

      const result = await validateInvitation(token);
      setValidation(result);

      // If invitation is valid but user is not authenticated,
      // store the token for later use after login/registration
      // Use localStorage instead of sessionStorage to persist across tabs
      // (e.g., when user opens password reset email in a new tab)
      if (result.valid && !isAuthenticated) {
        localStorage.setItem(PENDING_INVITATION_KEY, token);

        // No targetUsername = new-user invitation (email only) -> only show "Neues Konto erstellen"
        if (!result.targetUsername) {
          setUserExists(false); // Treat as new user, show only register
        } else {
          // Check if the target username already has an account
          try {
            const resp = await api.get(`/api/local/available`, {
              params: { username: result.targetUsername }
            });
            // available=true means username is free -> user does NOT exist
            setUserExists(!resp.data.available);
          } catch {
            // On error, default to showing both options
            setUserExists(null);
          }
        }
      }

      if (result.valid && isAuthenticated && result.targetUsername) {
        const cachedUser = getUserDataCache();
        if (cachedUser?.username && cachedUser.username.toLowerCase() !== result.targetUsername.toLowerCase()) {
          localStorage.removeItem(PENDING_INVITATION_KEY);
          setUserMismatch(true);
        }
      }

      setValidating(false);
    };

    validate();
  }, [token, validateInvitation, isAuthenticated]);

  // Accept invitation (for authenticated users)
  const handleAccept = async () => {
    if (!token) return;
    
    setAccepting(true);
    setError(null);
    
    const result = await acceptInvitation(token);
    
    if (result.success) {
      // Clear pending invitation token
      localStorage.removeItem(PENDING_INVITATION_KEY);
      setSuccess(true);
      // Redirect to dashboard after 2 seconds
      setTimeout(() => {
        navigate('/');
      }, 2000);
    } else if (result.error?.includes('401') || result.error?.includes('Not authenticated')) {
      // Session expired — clear auth and redirect to login
      sessionStorage.removeItem('auth_authority');
      handleLoginRedirect();
    } else {
      setError(result.error || t('Fehler beim Annehmen der Einladung'));
    }
    
    setAccepting(false);
  };

  // Handle redirect to login (stores token first, passes invitation data for pre-fill)
  const handleLoginRedirect = () => {
    if (token) {
      localStorage.setItem(PENDING_INVITATION_KEY, token);
    }
    navigate('/login', { state: {
      from: { pathname: `/invite/${token}` },
      invitationUsername: validation?.targetUsername || '',
    } });
  };

  // Handle redirect to register (stores token first, passes invitation data for pre-fill)
  const handleRegisterRedirect = () => {
    if (token) {
      localStorage.setItem(PENDING_INVITATION_KEY, token);
    }
    navigate('/register', { state: {
      from: { pathname: `/invite/${token}` },
      pendingInvitation: true,
      invitationUsername: validation?.targetUsername || '',
      invitationEmail: validation?.email || '',
    } });
  };

  // Loading state
  if (validating) {
    return (
      <div className={styles.container}>
        <div className={styles.card}>
          <div className={styles.loading}>
            <FaSpinner className={styles.spinner} />
            <p>{t('Einladung wird überprüft')}</p>
          </div>
        </div>
      </div>
    );
  }

  // Invalid invitation
  if (!validation?.valid) {
    return (
      <div className={styles.container}>
        <div className={styles.card}>
          <div className={styles.errorState}>
            <FaTimesCircle className={styles.errorIcon} />
            <h1>{t('Ungültige Einladung')}</h1>
            <p>{validation?.reason || 'Diese Einladung ist nicht gültig.'}</p>
            <Link to="/login" className={styles.primaryButton}>
              Zur Anmeldung
            </Link>
          </div>
        </div>
      </div>
    );
  }

  // Success state
  if (success) {
    return (
      <div className={styles.container}>
        <div className={styles.card}>
          <div className={styles.successState}>
            <FaCheckCircle className={styles.successIcon} />
            <h1>{t('erfolgreich')}</h1>
            <p>{t('Sie wurden erfolgreich zum Mandanten hinzugefügt')}</p>
            <p className={styles.redirectMessage}>{t('Sie werden weitergeleitet')}</p>
          </div>
        </div>
      </div>
    );
  }

  // Authenticated but invitation is for a different user
  if (userMismatch && validation?.valid) {
    const cachedUser = getUserDataCache();
    return (
      <div className={styles.container}>
        <div className={styles.card}>
          <div className={styles.errorState}>
            <FaTimesCircle className={styles.errorIcon} />
            <h1>{t('Falsche Anmeldung')}</h1>
            <p>
              Diese Einladung ist für <strong>{validation.targetUsername}</strong> bestimmt.
              Sie sind als <strong>{cachedUser?.username || 'anderer Benutzer'}</strong> angemeldet.
            </p>
            <p>{t('Bitte melden Sie sich ab')}</p>
            <Link to="/" className={styles.primaryButton}>
              Zum Dashboard
            </Link>
          </div>
        </div>
      </div>
    );
  }

  // Already authenticated - show accept button
  const isFeatureInvite = !!validation.featureInstanceId;
  const introText = isFeatureInvite
    ? t('Sie wurden eingeladen, einem Mandanten beizutreten')
    : t('Sie wurden eingeladen, einem Mandanten beizutreten');
  const rolesLabel = isFeatureInvite ? t('Features mit zugewiesenen Rollen') : t('Zugewiesene Rollen');
  const rolesValue = validation.featureInstanceName && validation.roleLabels?.length
    ? `${validation.featureInstanceName} (${validation.roleLabels.join(', ')})`
    : validation.roleLabels?.join(', ') || '';

  if (isAuthenticated) {
    return (
      <div className={styles.container}>
        <div className={styles.card}>
          <div className={styles.header}>
            <h1>{t('Einladung annehmen')}</h1>
            <p>{introText}</p>
          </div>

          <div className={styles.inviteInfo}>
            {validation.targetUsername && (
              <div className={styles.infoRow}>
                <span className={styles.infoLabel}>Eingeladen:</span>
                <span className={styles.infoValue}><strong>{validation.targetUsername}</strong></span>
              </div>
            )}
            {validation.mandateName && (
              <div className={styles.infoRow}>
                <span className={styles.infoLabel}>{t('Mandant')}</span>
                <span className={styles.infoValue}>{validation.mandateName}</span>
              </div>
            )}
            <div className={styles.infoRow}>
              <span className={styles.infoLabel}>{t('Status')}</span>
              <span className={styles.infoValue}>Angemeldet</span>
            </div>
            {rolesValue && (
              <div className={styles.infoRow}>
                <span className={styles.infoLabel}>{rolesLabel}:</span>
                <span className={styles.infoValue}>{rolesValue}</span>
              </div>
            )}
          </div>

          {error && (
            <div className={styles.errorMessage}>
              <FaTimesCircle /> {error}
            </div>
          )}

          <div className={styles.actions}>
            <button
              className={styles.primaryButton}
              onClick={handleAccept}
              disabled={accepting}
            >
              {accepting ? (
                <>
                  <FaSpinner className={styles.spinner} /> Wird verarbeitet...
                </>
              ) : (
                'Einladung annehmen'
              )}
            </button>
            <Link to="/" className={styles.secondaryButton}>
              Abbrechen
            </Link>
          </div>
        </div>
      </div>
    );
  }

  // Not authenticated - show create account / link to existing
  return (
    <div className={styles.container}>
      <div className={styles.card}>
        <div className={styles.header}>
          <h1>{t('Einladung annehmen')}</h1>
          <p>{introText}</p>
        </div>

        <div className={styles.inviteInfo}>
          {validation.targetUsername && (
            <div className={styles.infoRow}>
              <span className={styles.infoLabel}>Eingeladen:</span>
              <span className={styles.infoValue}><strong>{validation.targetUsername}</strong></span>
            </div>
          )}
          {validation.mandateName && (
            <div className={styles.infoRow}>
              <span className={styles.infoLabel}>{t('Mandant')}</span>
              <span className={styles.infoValue}>{validation.mandateName}</span>
            </div>
          )}
          {rolesValue && (
            <div className={styles.infoRow}>
              <span className={styles.infoLabel}>{rolesLabel}:</span>
              <span className={styles.infoValue}>{rolesValue}</span>
            </div>
          )}
        </div>

        <div className={styles.authPrompt}>
          <p>
            {userExists === true && validation.targetUsername
              ? `Sie haben bereits ein Konto (${validation.targetUsername}). Melden Sie sich an oder erstellen Sie ein neues Konto.`
              : 'Erstellen Sie ein neues Konto mit Ihrem Benutzernamen oder verlinken Sie die Einladung mit Ihrem bestehenden Account.'}
          </p>
        </div>

        {error && (
          <div className={styles.errorMessage}>
            <FaTimesCircle /> {error}
          </div>
        )}

        <div className={styles.authActions}>
          <button
            className={styles.primaryButton}
            onClick={handleRegisterRedirect}
          >
            <FaUserPlus /> Neues Konto erstellen
          </button>
          <div className={styles.divider}>
            <span>oder</span>
          </div>
          <button
            className={styles.secondaryButton}
            onClick={handleLoginRedirect}
          >
            <FaSignInAlt /> Mit bestehendem Konto verlinken
          </button>
        </div>

        <div className={styles.authInfo}>
          <p>
            Neues Konto: E-Mail wird vorausgefüllt, Benutzername legen Sie selbst fest. Bestehendes Konto: Die Einladung wird nach der Anmeldung automatisch an Ihr Konto verknüpft.
          </p>
        </div>
      </div>
    </div>
  );
};

export default InvitePage;
