import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import * as teamsbotApi from '../../../api/teamsbotApi';
import type { TeamsbotSession, StartSessionRequest, TeamsbotJoinMode, UserAccountStatus, MfaChallengeEvent } from '../../../api/teamsbotApi';
import { getUserDataCache } from '../../../utils/userCache';
import styles from './Teamsbot.module.css';

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

/**
 * TeamsbotDashboardView - Overview of all Teams Bot sessions.
 * Allows starting new sessions and viewing active/past sessions.
 * Supports "Mein Account" login with saved credentials and MFA relay.
 */
export const TeamsbotDashboardView: React.FC = () => {
    const { t } = useLanguage();

  const { instance, mandateId, featureCode } = useCurrentInstance();
  const instanceId = instance?.id || '';
  const navigate = useNavigate();

  const cachedUser = getUserDataCache();
  const _isSysAdmin = cachedUser?.isSysAdmin === true;

  const [sessions, setSessions] = useState<TeamsbotSession[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // New session form
  const [meetingLink, setMeetingLink] = useState('');
  const [botName, setBotName] = useState('');
  const [joinMode, setJoinMode] = useState<TeamsbotJoinMode>('anonymous');
  const [sessionContext, setSessionContext] = useState('');
  const [isStarting, setIsStarting] = useState(false);

  // User Account (Mein Account) state
  const [userAccount, setUserAccount] = useState<UserAccountStatus | null>(null);
  const [showCredentialForm, setShowCredentialForm] = useState(false);
  const [credEmail, setCredEmail] = useState('');
  const [credPassword, setCredPassword] = useState('');
  const [savingCredentials, setSavingCredentials] = useState(false);

  // MFA state
  const [mfaChallenge, setMfaChallenge] = useState<MfaChallengeEvent | null>(null);
  const [mfaCode, setMfaCode] = useState('');
  const [mfaSessionId, setMfaSessionId] = useState<string | null>(null);
  const [mfaWaitingPush, setMfaWaitingPush] = useState(false);
  const sseRef = useRef<EventSource | null>(null);

  const _loadSessions = useCallback(async () => {
    if (!instanceId) return;
    try {
      setLoading(true);
      const result = await teamsbotApi.listSessions(instanceId);
      setSessions(result.sessions || []);
      setError(null);
    } catch (err: any) {
      setError(err.message || t('Fehler beim Laden der Sitzungen'));
    } finally {
      setLoading(false);
    }
  }, [instanceId, t]);

  useEffect(() => {
    _loadSessions();
  }, [_loadSessions]);

  // Load user account status when joinMode changes to userAccount
  useEffect(() => {
    if (joinMode === 'userAccount' && instanceId) {
      teamsbotApi.getUserAccount(instanceId).then(setUserAccount).catch(() => setUserAccount(null));
    }
  }, [joinMode, instanceId]);

  // Adaptive polling: 3s with active sessions, 30s otherwise
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
  useEffect(() => {
    const hasActiveSessions = sessions.some(s => ['pending', 'joining', 'active'].includes(s.status));
    const interval = hasActiveSessions ? 3000 : 30000;
    if (instanceId) {
      pollRef.current = setInterval(() => {
        teamsbotApi.listSessions(instanceId).then(r => setSessions(r.sessions || [])).catch(() => {});
      }, interval);
    }
    return () => { if (pollRef.current) clearInterval(pollRef.current); };
  }, [sessions, instanceId]);

  // Cleanup SSE on unmount
  useEffect(() => {
    return () => { sseRef.current?.close(); };
  }, []);

  const _startMfaListener = useCallback((sessionId: string) => {
    sseRef.current?.close();
    const es = teamsbotApi.createSessionStream(instanceId, sessionId);
    sseRef.current = es;
    setMfaSessionId(sessionId);

    es.onmessage = (event) => {
      try {
        const parsed = JSON.parse(event.data);
        if (parsed.type === 'mfaChallenge') {
          const data = parsed.data as MfaChallengeEvent;
          if (data.mfaType === 'timeout') {
            setMfaChallenge(null);
            setMfaWaitingPush(false);
            setError(t('MFA-Zeitlimit überschritten, bitte erneut versuchen'));
          } else {
            setMfaChallenge(data);
            setMfaCode('');
            setMfaWaitingPush(data.mfaType === 'pushApproval' || data.mfaType === 'numberMatch');
          }
        } else if (parsed.type === 'mfaResolved') {
          setMfaChallenge(null);
          setMfaWaitingPush(false);
          setMfaSessionId(null);
          es.close();
          sseRef.current = null;
          _loadSessions();
        }
      } catch { /* ignore parse errors */ }
    };
  }, [instanceId, _loadSessions, t]);

  const _handleStartSession = async () => {
    if (!meetingLink.trim()) return;

    // For userAccount: need credentials (saved or entered now)
    if (joinMode === 'userAccount' && !userAccount?.hasSavedCredentials && !credEmail) {
      setShowCredentialForm(true);
      return;
    }

    // userAccount with new/unsaved credentials: save to DB before starting
    const needsSave = joinMode === 'userAccount' && !userAccount?.hasSavedCredentials && credEmail && credPassword;
    const needsUpdate = joinMode === 'userAccount' && showCredentialForm && credEmail && credPassword;
    if (needsSave || needsUpdate) {
      try {
        setSavingCredentials(true);
        await teamsbotApi.saveUserAccount(instanceId, credEmail, credPassword);
        setUserAccount({ hasSavedCredentials: true, email: credEmail });
      } catch (err: any) {
        setError(err.message || t('Fehler beim Speichern der Zugangsdaten'));
        setSavingCredentials(false);
        return;
      } finally {
        setSavingCredentials(false);
      }
      setShowCredentialForm(false);
    }

    setIsStarting(true);
    setError(null);

    try {
      const request: StartSessionRequest = {
        meetingLink: meetingLink.trim(),
        botName: botName.trim() || undefined,
        joinMode: joinMode,
        sessionContext: sessionContext.trim() || undefined,
      };

      const result = await teamsbotApi.startSession(instanceId, request);
      const newSessionId = result.session?.id;
      setMeetingLink('');
      setBotName('');

      // Start SSE listener for MFA events if userAccount mode
      if (joinMode === 'userAccount' && newSessionId) {
        _startMfaListener(newSessionId);
      }

      await _loadSessions();
    } catch (err: any) {
      setError(err.message || t('Fehler beim Starten der Sitzung'));
    } finally {
      setIsStarting(false);
    }
  };

  const _handleSubmitMfaCode = async () => {
    if (!mfaSessionId || !instanceId) return;
    const needsCode = mfaChallenge?.mfaType === 'totpCode' || mfaChallenge?.mfaType === 'smsCode';
    try {
      await teamsbotApi.submitMfaCode(
        instanceId,
        mfaSessionId,
        needsCode ? mfaCode : '',
        needsCode ? 'code' : 'confirmed',
      );
      if (!needsCode) {
        setMfaWaitingPush(true);
      }
    } catch (err: any) {
      setError(err.message || t('Fehler beim Senden des MFA-Codes'));
    }
  };

  const _handleDeleteUserAccount = async () => {
    try {
      await teamsbotApi.deleteUserAccount(instanceId);
      setUserAccount({ hasSavedCredentials: false });
      setCredEmail('');
      setCredPassword('');
    } catch (err: any) {
      setError(err.message || t('Fehler beim Löschen der Zugangsdaten'));
    }
  };

  const _handleStopSession = async (sessionId: string) => {
    try {
      await teamsbotApi.stopSession(instanceId, sessionId);
      await _loadSessions();
    } catch (err: any) {
      setError(err.message || t('Fehler beim Stoppen der Sitzung'));
    }
  };

  const _handleDeleteSession = async (sessionId: string) => {
    try {
      await teamsbotApi.deleteSession(instanceId, sessionId);
      await _loadSessions();
    } catch (err: any) {
      setError(err.message || t('Fehler beim Löschen der Sitzung'));
    }
  };

  const _getStatusBadgeClass = (status: string) => {
    switch (status) {
      case 'active': return styles.statusActive;
      case 'joining': return styles.statusJoining;
      case 'pending': return styles.statusPending;
      case 'ended': return styles.statusEnded;
      case 'error': return styles.statusError;
      case 'leaving': return styles.statusLeaving;
      default: return '';
    }
  };

  const _getStatusLabel = (status: string) => {
    const labels: Record<string, string> = {
      pending: 'Wartend',
      joining: 'Beitritt...',
      active: 'Aktiv',
      leaving: 'Verlassen...',
      ended: 'Beendet',
      error: 'Fehler',
    };
    return labels[status] || status;
  };

  const activeSessions = sessions.filter(s => ['pending', 'joining', 'active'].includes(s.status));
  const pastSessions = sessions.filter(s => ['ended', 'error', 'leaving'].includes(s.status));

  const _needsCodeInput = mfaChallenge?.mfaType === 'totpCode' || mfaChallenge?.mfaType === 'smsCode';

  return (
    <div className={styles.dashboardContainer}>
      {/* MFA Challenge Dialog */}
      {mfaChallenge && (
        <div className={styles.mfaOverlay}>
          <div className={styles.mfaDialog}>
            <div className={styles.mfaTitle}>Multi-Faktor-Authentifizierung</div>

            {mfaChallenge.displayNumber && (
              <div className={styles.mfaNumber}>{mfaChallenge.displayNumber}</div>
            )}

            <div className={styles.mfaPrompt}>{mfaChallenge.prompt}</div>

            {_needsCodeInput ? (
              <>
                <input
                  type="text"
                  className={styles.mfaCodeInput}
                  placeholder={t('Code eingeben')}
                  value={mfaCode}
                  onChange={(e) => setMfaCode(e.target.value)}
                  autoFocus
                  onKeyDown={(e) => e.key === 'Enter' && _handleSubmitMfaCode()}
                />
                <button className={styles.startButton} onClick={_handleSubmitMfaCode} disabled={!mfaCode.trim()}>
                  Bestaetigen
                </button>
              </>
            ) : mfaWaitingPush ? (
              <>
                <div className={styles.mfaSpinner} />
                <p style={{ fontSize: '0.85rem', color: '#888' }}>
                  Warte auf Bestaetigung in der Authenticator App...
                </p>
              </>
            ) : (
              <button className={styles.startButton} onClick={_handleSubmitMfaCode}>
                Ich habe bestaetigt
              </button>
            )}
          </div>
        </div>
      )}

      {/* Start New Session Card */}
      <div className={styles.startSessionCard}>
        <h3 className={styles.cardTitle}>{t('Neue Botsitzung starten')}</h3>
        <p className={styles.cardDescription}>
          Fuege den Teams Meeting-Link ein, um den AI-Bot in ein Meeting einzuschleusen.
        </p>
        
        <div className={styles.formGroup}>
          <label className={styles.label}>{t('Teams-Meetinglink')}</label>
          <input
            type="url"
            className={styles.input}
            placeholder="https://teams.microsoft.com/l/meetup-join/..."
            value={meetingLink}
            onChange={(e) => setMeetingLink(e.target.value)}
            disabled={isStarting}
          />
        </div>

        <div className={styles.formGroup}>
          <label className={styles.label}>Join-Modus</label>
          <select
            className={styles.select || styles.input}
            value={joinMode}
            onChange={(e) => setJoinMode(e.target.value as TeamsbotJoinMode)}
            disabled={isStarting}
          >
            {_isSysAdmin && <option value="systemBot">{t('Systembot authentifiziert')}</option>}
            <option value="anonymous">{t('Anonymer Gast')}</option>
            <option value="userAccount">{t('Mein Account')}</option>
          </select>
        </div>

        {/* User Account: saved credentials info or credential form */}
        {joinMode === 'userAccount' && (
          <div className={styles.credentialsCard}>
            {userAccount?.hasSavedCredentials && !showCredentialForm ? (
              <div className={styles.credentialsInfo}>
                <span>
                  Gespeichert: <span className={styles.credentialsEmail}>{userAccount.email}</span>
                </span>
                <div style={{ display: 'flex', gap: '0.5rem' }}>
                  <button
                    className={styles.viewButton}
                    onClick={() => { setShowCredentialForm(true); setCredEmail(userAccount.email || ''); }}
                  >
                    Aendern
                  </button>
                  <button className={styles.deleteButton} onClick={_handleDeleteUserAccount}>
                    Entfernen
                  </button>
                </div>
              </div>
            ) : (
              <>
                <div className={styles.formGroup}>
                  <label className={styles.label}>{t('Microsoft E-Mail')}</label>
                  <input
                    type="email"
                    className={styles.input}
                    placeholder="name@example.com"
                    value={credEmail}
                    onChange={(e) => setCredEmail(e.target.value)}
                    disabled={savingCredentials}
                  />
                </div>
                <div className={styles.formGroup}>
                  <label className={styles.label}>{t('Passwort')}</label>
                  <input
                    type="password"
                    className={styles.input}
                    placeholder="Microsoft-Passwort"
                    value={credPassword}
                    onChange={(e) => setCredPassword(e.target.value)}
                    disabled={savingCredentials}
                  />
                </div>
                <span style={{ fontSize: '12px', color: '#888', marginTop: '4px', display: 'block' }}>
                  Zugangsdaten werden verschluesselt gespeichert.
                </span>
                {userAccount?.hasSavedCredentials && (
                  <button
                    className={styles.viewButton}
                    style={{ marginTop: '0.5rem' }}
                    onClick={() => setShowCredentialForm(false)}
                  >
                    Abbrechen
                  </button>
                )}
              </>
            )}
          </div>
        )}

        <div className={styles.formGroup}>
          <label className={styles.label}>{t('Botname (optional)')}</label>
          <input
            type="text"
            className={styles.input}
            placeholder={t('KI-Assistent')}
            value={botName}
            onChange={(e) => setBotName(e.target.value)}
            disabled={isStarting}
          />
        </div>

        <div className={styles.formGroup}>
          <label className={styles.label}>{t('Sitzungskontext (optional)')}</label>
          <textarea
            className={styles.textarea || styles.input}
            placeholder={t('Agenda, Hintergrundinfos, Dokumente oder …')}
            value={sessionContext}
            onChange={(e) => setSessionContext(e.target.value)}
            disabled={isStarting}
            rows={4}
            style={{ resize: 'vertical', minHeight: '80px' }}
          />
          <span style={{ fontSize: '12px', color: '#888' }}>
            Kontext den der Bot waehrend der Sitzung nutzen kann (z.B. Meeting-Agenda, Projektinfos).
            {sessionContext.length > 0 && ` (${sessionContext.length} Zeichen)`}
          </span>
        </div>

        <button
          className={styles.startButton}
          onClick={_handleStartSession}
          disabled={isStarting || !meetingLink.trim() || (joinMode === 'userAccount' && showCredentialForm && (!credEmail || !credPassword))}
        >
          {isStarting ? t('Wird gestartet') : t('Bot ins Meeting senden')}
        </button>
      </div>

      {error && <div className={styles.errorBanner}>{error}</div>}

      {/* Active Sessions */}
      {activeSessions.length > 0 && (
        <div className={styles.sectionContainer}>
          <h3 className={styles.sectionTitle}>{t('Aktive Sitzungen')}</h3>
          <div className={styles.sessionList}>
            {activeSessions.map((session) => (
              <div key={session.id} className={styles.sessionCard}>
                <div className={styles.sessionHeader}>
                  <span className={styles.sessionBotName}>{session.botName}</span>
                  <span className={`${styles.statusBadge} ${_getStatusBadgeClass(session.status)}`}>
                    {_getStatusLabel(session.status)}
                  </span>
                </div>
                <div className={styles.sessionMeta}>
                  <span>{session.transcriptSegmentCount} Segmente</span>
                  <span>{session.botResponseCount} Antworten</span>
                  {session.startedAt && <span>Seit: {new Date(session.startedAt).toLocaleTimeString('de-CH')}</span>}
                </div>
                <div className={styles.sessionActions}>
                  <button className={styles.viewButton} onClick={() => navigate(`/mandates/${mandateId}/${featureCode}/${instanceId}/sessions?sessionId=${session.id}`)}>{t('Live ansehen')}</button>
                  {session.status === 'active' && (
                    <button className={styles.stopButton} onClick={() => _handleStopSession(session.id)}>
                      Stoppen
                    </button>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Past Sessions */}
      <div className={styles.sectionContainer}>
        <h3 className={styles.sectionTitle}>
          {loading ? 'Lade Sitzungen...' : `Vergangene Sitzungen (${pastSessions.length})`}
        </h3>
        {pastSessions.length === 0 && !loading && (
          <p className={styles.emptyState}>{t('Noch keine vergangenen Sitzungen')}</p>
        )}
        <div className={styles.sessionList}>
          {pastSessions.map((session) => (
            <div key={session.id} className={styles.sessionCard}>
              <div className={styles.sessionHeader}>
                <span className={styles.sessionBotName}>{session.botName}</span>
                <span className={`${styles.statusBadge} ${_getStatusBadgeClass(session.status)}`}>
                  {_getStatusLabel(session.status)}
                </span>
              </div>
              <div className={styles.sessionMeta}>
                <span>{session.transcriptSegmentCount} Segmente</span>
                <span>{session.botResponseCount} Antworten</span>
                {session.startedAt && <span>{new Date(session.startedAt).toLocaleDateString('de-CH')}</span>}
              </div>
              {session.summary && (
                <div className={styles.sessionSummary}>{session.summary.substring(0, 200)}...</div>
              )}
              {session.errorMessage && (
                <div className={styles.sessionError}>{session.errorMessage}</div>
              )}
              <div className={styles.sessionActions}>
                <button className={styles.viewButton} onClick={() => navigate(`/mandates/${mandateId}/${featureCode}/${instanceId}/sessions?sessionId=${session.id}`)}>Details</button>
                <button className={styles.deleteButton} onClick={() => _handleDeleteSession(session.id)}>
                  Loeschen
                </button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

export default TeamsbotDashboardView;
