import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import * as teamsbotApi from '../../../api/teamsbotApi';
import type { TeamsbotSession, TeamsbotTranscript, TeamsbotBotResponse, TeamsbotSSEEvent } from '../../../api/teamsbotApi';
import styles from './Teamsbot.module.css';

/**
 * TeamsbotSessionView - Live session view with real-time transcript and bot responses.
 */
export const TeamsbotSessionView: React.FC = () => {
  const { instance } = useCurrentInstance();
  const instanceId = instance?.id || '';
  const [searchParams, setSearchParams] = useSearchParams();
  const sessionId = searchParams.get('sessionId') || '';

  const [session, setSession] = useState<TeamsbotSession | null>(null);
  const [allSessions, setAllSessions] = useState<TeamsbotSession[]>([]);
  const [transcripts, setTranscripts] = useState<TeamsbotTranscript[]>([]);
  const [botResponses, setBotResponses] = useState<TeamsbotBotResponse[]>([]);
  const [loading, setLoading] = useState(true);
  const [noSessions, setNoSessions] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isLive, setIsLive] = useState(false);

  const transcriptEndRef = useRef<HTMLDivElement>(null);
  const eventSourceRef = useRef<EventSource | null>(null);

  // Load session data - if no sessionId given, load the most recent session
  const _loadSession = useCallback(async () => {
    if (!instanceId) return;
    try {
      setLoading(true);
      setNoSessions(false);

      // Always load the full session list for the switcher
      const listResult = await teamsbotApi.listSessions(instanceId, true);
      const sessions = listResult.sessions || [];
      setAllSessions(sessions);

      let targetSessionId = sessionId;

      // No sessionId in URL -> find the most recent active or latest session
      if (!targetSessionId) {
        if (sessions.length === 0) {
          setNoSessions(true);
          setLoading(false);
          return;
        }
        // Prefer active sessions, then most recent
        const activeSession = sessions.find(s => ['active', 'joining', 'pending'].includes(s.status));
        targetSessionId = activeSession ? activeSession.id : sessions[0].id;
        setSearchParams({ sessionId: targetSessionId }, { replace: true });
      }

      const result = await teamsbotApi.getSession(instanceId, targetSessionId);
      setSession(result.session);
      setTranscripts(result.transcripts || []);
      setBotResponses(result.botResponses || []);
      setError(null);
    } catch (err: any) {
      setError(err.message || 'Fehler beim Laden der Sitzung');
    } finally {
      setLoading(false);
    }
  }, [instanceId, sessionId, setSearchParams]);

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

  // SSE Live Stream
  useEffect(() => {
    if (!instanceId || !sessionId || !session) return;
    if (!['active', 'joining', 'pending'].includes(session.status)) return;

    const eventSource = teamsbotApi.createSessionStream(instanceId, sessionId);
    eventSourceRef.current = eventSource;
    setIsLive(true);

    eventSource.onmessage = (event) => {
      try {
        const sseEvent: TeamsbotSSEEvent = JSON.parse(event.data);

        switch (sseEvent.type) {
          case 'transcript':
            setTranscripts(prev => [...prev, sseEvent.data as TeamsbotTranscript]);
            break;

          case 'botResponse':
            setBotResponses(prev => [...prev, sseEvent.data as TeamsbotBotResponse]);
            break;

          case 'statusChange':
            setSession(prev => prev ? { ...prev, status: sseEvent.data.status } : null);
            if (['ended', 'error'].includes(sseEvent.data.status)) {
              setIsLive(false);
              eventSource.close();
            }
            break;

          case 'analysis':
            // Debug info - could show in UI
            break;

          case 'suggestedResponse':
            // Manual mode: show suggested response
            break;

          case 'ping':
            break;
        }
      } catch (err) {
        console.error('SSE parse error:', err);
      }
    };

    eventSource.onerror = () => {
      setIsLive(false);
    };

    return () => {
      eventSource.close();
      eventSourceRef.current = null;
      setIsLive(false);
    };
  }, [instanceId, sessionId, session?.status]);

  // Polling fallback: refresh session data every 5s when session is active (in case SSE fails)
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const isActive = useMemo(() => session && ['pending', 'joining', 'active'].includes(session.status), [session]);
  useEffect(() => {
    if (isActive && instanceId && sessionId && !isLive) {
      pollRef.current = setInterval(async () => {
        try {
          const result = await teamsbotApi.getSession(instanceId, sessionId);
          setSession(result.session);
          if (result.transcripts) setTranscripts(result.transcripts);
          if (result.botResponses) setBotResponses(result.botResponses);
        } catch {}
      }, 5000);
    }
    return () => { if (pollRef.current) clearInterval(pollRef.current); };
  }, [isActive, instanceId, sessionId, isLive]);

  // Auto-scroll transcript
  useEffect(() => {
    transcriptEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [transcripts]);

  const _handleStop = async () => {
    if (!instanceId || !sessionId) return;
    try {
      await teamsbotApi.stopSession(instanceId, sessionId);
    } catch (err: any) {
      setError(err.message);
    }
  };

  const _formatTime = (timestamp: string) => {
    try {
      return new Date(timestamp).toLocaleTimeString('de-CH', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
    } catch {
      return '';
    }
  };

  const _getSpeakerColor = (speaker: string) => {
    const colors = ['#4A90D9', '#D94A4A', '#4AD99A', '#D9A84A', '#9A4AD9', '#4AD9D9'];
    let hash = 0;
    for (let i = 0; i < speaker.length; i++) {
      hash = speaker.charCodeAt(i) + ((hash << 5) - hash);
    }
    return colors[Math.abs(hash) % colors.length];
  };

  if (loading) return <div className={styles.loading}>Lade Sitzung...</div>;
  if (noSessions) return (
    <div className={styles.emptyState || styles.loading}>
      <p>Keine Sitzungen vorhanden.</p>
      <p>Starte eine neue Sitzung im <strong>Dashboard</strong>.</p>
    </div>
  );
  if (!session) return <div className={styles.errorBanner}>Sitzung nicht gefunden</div>;

  const _switchSession = (newSessionId: string) => {
    setSearchParams({ sessionId: newSessionId });
  };

  return (
    <div className={styles.sessionContainer}>
      {/* Session Switcher (if multiple sessions exist) */}
      {allSessions.length > 1 && (
        <div style={{ display: 'flex', gap: '8px', marginBottom: '12px', flexWrap: 'wrap' }}>
          {allSessions.map((s) => (
            <button
              key={s.id}
              onClick={() => _switchSession(s.id)}
              style={{
                padding: '6px 12px',
                borderRadius: '6px',
                border: s.id === sessionId ? '2px solid #4A90D9' : '1px solid #ddd',
                background: s.id === sessionId ? '#EBF3FC' : '#fff',
                cursor: 'pointer',
                fontSize: '13px',
                fontWeight: s.id === sessionId ? 600 : 400,
              }}
            >
              {s.botName}
              {['active', 'joining', 'pending'].includes(s.status) && ' (aktiv)'}
              {s.status === 'ended' && ' (beendet)'}
            </button>
          ))}
        </div>
      )}

      {/* Session Header */}
      <div className={styles.sessionViewHeader}>
        <div className={styles.sessionInfo}>
          <h3 className={styles.sessionTitle}>{session.botName}</h3>
          <span className={`${styles.statusBadge} ${styles[`status${session.status.charAt(0).toUpperCase() + session.status.slice(1)}`] || ''}`}>
            {session.status}
          </span>
          {isLive && <span className={styles.liveBadge}>LIVE</span>}
        </div>
        <div className={styles.sessionControls}>
          {['active', 'joining'].includes(session.status) && (
            <button className={styles.stopButton} onClick={_handleStop}>Sitzung beenden</button>
          )}
        </div>
      </div>

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

      {/* Main Content: Transcript + Responses */}
      <div className={styles.sessionContent}>
        {/* Left: Transcript */}
        <div className={styles.transcriptPanel}>
          <h4 className={styles.panelTitle}>Transkript ({transcripts.length} Segmente)</h4>
          <div className={styles.transcriptList}>
            {transcripts.map((t) => (
              <div key={t.id} className={styles.transcriptItem}>
                <span className={styles.transcriptTime}>{_formatTime(t.timestamp)}</span>
                <span
                  className={styles.transcriptSpeaker}
                  style={{ color: _getSpeakerColor(t.speaker || 'Unknown') }}
                >
                  {t.speaker || 'Unknown'}:
                </span>
                <span className={styles.transcriptText}>{t.text}</span>
              </div>
            ))}
            <div ref={transcriptEndRef} />
            {transcripts.length === 0 && (
              <div className={styles.emptyState}>Noch kein Transkript vorhanden.</div>
            )}
          </div>
        </div>

        {/* Right: Bot Responses */}
        <div className={styles.responsesPanel}>
          <h4 className={styles.panelTitle}>Bot-Antworten ({botResponses.length})</h4>
          <div className={styles.responseList}>
            {botResponses.map((r) => (
              <div key={r.id} className={styles.responseItem}>
                <div className={styles.responseHeader}>
                  <span className={styles.responseIntent}>{r.detectedIntent}</span>
                  <span className={styles.responseTime}>{_formatTime(r.timestamp || '')}</span>
                </div>
                <div className={styles.responseText}>{r.responseText}</div>
                {r.reasoning && (
                  <div className={styles.responseReasoning}>
                    <em>Reasoning: {r.reasoning}</em>
                  </div>
                )}
                <div className={styles.responseMeta}>
                  <span>{r.modelName}</span>
                  <span>{r.processingTime.toFixed(1)}s</span>
                  <span>{r.priceCHF.toFixed(4)} CHF</span>
                </div>
              </div>
            ))}
            {botResponses.length === 0 && (
              <div className={styles.emptyState}>Noch keine Bot-Antworten.</div>
            )}
          </div>
        </div>
      </div>

      {/* Summary (for ended sessions) */}
      {session.summary && (
        <div className={styles.summaryCard}>
          <h4 className={styles.panelTitle}>Meeting-Zusammenfassung</h4>
          <div className={styles.summaryText}>{session.summary}</div>
        </div>
      )}
    </div>
  );
};

export default TeamsbotSessionView;
