import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import * as teamsbotApi from '../../../api/teamsbotApi';
import type { TeamsbotConfig, ConfigUpdateRequest, VoiceOption, AuthTestResults, AuthTestResult } from '../../../api/teamsbotApi';
import { FaPlay, FaSpinner, FaFlask, FaImage, FaChevronDown, FaChevronRight } from 'react-icons/fa';
import styles from './Teamsbot.module.css';

/** Format voice name for display: "de-DE-Wavenet-A" -> "Wavenet A" + gender */
function _formatVoiceName(voice: VoiceOption): string {
  const parts = voice.name.split('-');
  const type = parts[2] || '';   // Wavenet, Neural2, Standard, etc.
  const variant = parts[3] || '';
  const gender = voice.ssmlGender === 'FEMALE' ? 'Frau' : voice.ssmlGender === 'MALE' ? 'Mann' : '';
  return `${gender} ${variant} (${type})`.trim();
}

/**
 * TeamsbotSettingsView - Bot configuration for a feature instance.
 */
export const TeamsbotSettingsView: React.FC = () => {
  const { instance } = useCurrentInstance();
  const instanceId = instance?.id || '';

  const [_config, setConfig] = useState<TeamsbotConfig | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [testingVoice, setTestingVoice] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [successMsg, setSuccessMsg] = useState<string | null>(null);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  // Form state
  const [formData, setFormData] = useState<ConfigUpdateRequest>({});

  // Dynamic voice data from Google TTS API
  const [languages, setLanguages] = useState<string[]>([]);
  const [voices, setVoices] = useState<VoiceOption[]>([]);
  const [loadingVoices, setLoadingVoices] = useState(false);

  // Auth detection test state
  const [testMeetingUrl, setTestMeetingUrl] = useState('');
  const [testBotEmail, setTestBotEmail] = useState('');
  const [testBotPassword, setTestBotPassword] = useState('');
  const [testRunning, setTestRunning] = useState(false);
  const [testResults, setTestResults] = useState<AuthTestResults | null>(null);
  const [testError, setTestError] = useState<string | null>(null);
  const [screenshotPreview, setScreenshotPreview] = useState<{ src: string; caption: string } | null>(null);
  const [expandedLogs, setExpandedLogs] = useState<Set<string>>(new Set());

  const _loadConfig = useCallback(async () => {
    if (!instanceId) return;
    try {
      setLoading(true);
      // Load per-user settings (merged with instance defaults)
      const [settingsResult, languagesResult] = await Promise.all([
        teamsbotApi.getUserSettings(instanceId),
        teamsbotApi.fetchLanguages(),
      ]);
      const effectiveConfig = settingsResult.effectiveConfig;
      setConfig(effectiveConfig);
      setFormData(effectiveConfig);
      setLanguages(languagesResult);
      // Load voices for the current language
      const lang = effectiveConfig.language || 'de-DE';
      const voicesResult = await teamsbotApi.fetchVoices(lang);
      setVoices(voicesResult);
      setError(null);
    } catch (err: any) {
      setError(err.message || 'Fehler beim Laden der Konfiguration');
    } finally {
      setLoading(false);
    }
  }, [instanceId]);

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

  const _handleSave = async () => {
    if (!instanceId) return;
    setSaving(true);
    setError(null);
    setSuccessMsg(null);

    try {
      // Save as per-user settings (not instance config)
      const result = await teamsbotApi.updateUserSettings(instanceId, formData);
      setConfig(result.effectiveConfig);
      setFormData(result.effectiveConfig);
      setSuccessMsg('Einstellungen gespeichert');
      setTimeout(() => setSuccessMsg(null), 3000);
    } catch (err: any) {
      setError(err.message || 'Fehler beim Speichern');
    } finally {
      setSaving(false);
    }
  };

  const _updateField = (field: keyof ConfigUpdateRequest, value: any) => {
    setFormData(prev => ({ ...prev, [field]: value }));
  };

  const _handleLanguageChange = async (language: string) => {
    _updateField('language', language);
    // Load voices for the new language dynamically
    setLoadingVoices(true);
    try {
      const voicesResult = await teamsbotApi.fetchVoices(language);
      setVoices(voicesResult);
      // Auto-select first voice if current voice doesn't match
      if (voicesResult.length > 0 && !voicesResult.find(v => v.name === formData.voiceId)) {
        _updateField('voiceId', voicesResult[0].name);
      }
    } catch {
      setVoices([]);
    } finally {
      setLoadingVoices(false);
    }
  };

  const _handleTestVoice = async () => {
    if (!instanceId) return;
    setTestingVoice(true);
    try {
      const language = formData.language || 'de-DE';
      const botName = formData.botName || 'AI Assistant';
      const result = await teamsbotApi.testVoice(instanceId, botName, language, formData.voiceId);
      
      if (result.success && result.audio) {
        // Play audio from base64
        const audioBlob = new Blob(
          [Uint8Array.from(atob(result.audio), c => c.charCodeAt(0))],
          { type: 'audio/mp3' }
        );
        const audioUrl = URL.createObjectURL(audioBlob);
        if (audioRef.current) {
          audioRef.current.pause();
        }
        const audio = new Audio(audioUrl);
        audioRef.current = audio;
        audio.play();
        audio.onended = () => URL.revokeObjectURL(audioUrl);
      } else {
        setError(result.error || 'Stimmtest fehlgeschlagen');
        setTimeout(() => setError(null), 3000);
      }
    } catch (err: any) {
      setError(err.message || 'Stimmtest fehlgeschlagen');
      setTimeout(() => setError(null), 3000);
    } finally {
      setTestingVoice(false);
    }
  };

  const _handleRunAuthTest = async () => {
    if (!instanceId || !testMeetingUrl.trim()) return;
    setTestRunning(true);
    setTestResults(null);
    setTestError(null);

    try {
      const results = await teamsbotApi.testAuth(
        instanceId,
        testMeetingUrl.trim(),
        testBotEmail.trim() || undefined,
        testBotPassword || undefined,
      );
      setTestResults(results);
    } catch (err: any) {
      setTestError(err.message || 'Auth-Test fehlgeschlagen');
    } finally {
      setTestRunning(false);
    }
  };

  const _getPageTypeBadge = (result: AuthTestResult) => {
    switch (result.pageType) {
      case 'v2':
        return <span className={styles.testBadgeV2}>/v2/</span>;
      case 'lightMeetings':
        return <span className={styles.testBadgeLightMeetings}>light-meetings</span>;
      case 'error':
        return <span className={styles.testBadgeError}>Fehler</span>;
      default:
        return <span className={styles.testBadgeUnknown}>Unbekannt</span>;
    }
  };

  const _getCheckmark = (value: boolean) => {
    return value
      ? <span className={styles.testCheckmark}>&#10003;</span>
      : <span className={styles.testCross}>&#10007;</span>;
  };

  const _formatDuration = (ms: number) => {
    if (ms < 1000) return `${ms}ms`;
    return `${(ms / 1000).toFixed(1)}s`;
  };

  const _toggleLogs = (variantId: string) => {
    setExpandedLogs(prev => {
      const next = new Set(prev);
      if (next.has(variantId)) {
        next.delete(variantId);
      } else {
        next.add(variantId);
      }
      return next;
    });
  };

  const _getLogLevelClass = (log: string): string => {
    if (log.startsWith('[ERROR]') || log.startsWith('[CONSOLE:error]') || log.startsWith('[PAGE_ERROR]')) {
      return styles.testLogError;
    }
    if (log.startsWith('[WARN]') || log.startsWith('[CONSOLE:warning]')) {
      return styles.testLogWarn;
    }
    return styles.testLogInfo;
  };

  if (loading) return <div className={styles.loading}>Lade Konfiguration...</div>;

  return (
    <div className={styles.settingsContainer}>
      <div className={styles.settingsCard}>
        <h3 className={styles.cardTitle}>Bot-Einstellungen</h3>

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

        {/* Auth Detection Test */}
        <div className={styles.testSection}>
          <div className={styles.testSectionHeader}>
            <FaFlask />
            <h4 className={styles.testSectionTitle}>Auth-Erkennung testen</h4>
          </div>
          <span className={styles.hint}>
            Testet 3 Browser-Varianten: Login bei teams.microsoft.com, dann Screenshot wo Teams hinleitet.
            Kein Meeting-Join — nur Auth-Flow-Test.
          </span>

          <div className={styles.testInputRow} style={{ marginTop: '0.75rem' }}>
            <input
              type="url"
              className={styles.input}
              value={testMeetingUrl}
              onChange={(e) => setTestMeetingUrl(e.target.value)}
              placeholder="https://teams.microsoft.com/meet/..."
              disabled={testRunning}
            />
            <button
              className={styles.testButton}
              onClick={_handleRunAuthTest}
              disabled={testRunning || !testMeetingUrl.trim()}
            >
              {testRunning ? <FaSpinner className={styles.spinner} /> : <FaFlask />}
              {testRunning ? 'Teste...' : 'Testen'}
            </button>
          </div>

          <div className={styles.testInputRow} style={{ marginTop: '0.5rem', gap: '0.5rem' }}>
            <input
              type="email"
              className={styles.input}
              value={testBotEmail}
              onChange={(e) => setTestBotEmail(e.target.value)}
              placeholder="Bot-Email (z.B. nyla.larsson@poweron.swiss)"
              disabled={testRunning}
              style={{ flex: 1 }}
            />
            <input
              type="password"
              className={styles.input}
              value={testBotPassword}
              onChange={(e) => setTestBotPassword(e.target.value)}
              placeholder="Bot-Passwort"
              disabled={testRunning}
              style={{ flex: 1 }}
            />
          </div>
          <span className={styles.hint}>
            Optional: Bot-Credentials fuer Auth-Test. Werden beim ersten Test automatisch in der DB gespeichert.
          </span>

          {testRunning && (
            <div className={styles.testProgress}>
              <FaSpinner className={styles.spinner} />
              3 Varianten werden getestet (~2-3 Minuten, je 20s Warten nach Login)...
            </div>
          )}

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

          {testResults && (
            <>
              <table className={styles.testResultsTable}>
                <thead>
                  <tr>
                    <th>Variante</th>
                    <th>Seite</th>
                    <th>Sign-in</th>
                    <th>Name-Input</th>
                    <th>Join</th>
                    <th>Auth</th>
                    <th>Dauer</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                  {testResults.variants.map((result) => (
                    <React.Fragment key={result.variantId}>
                      <tr>
                        <td>
                          <div className={styles.testVariantCell}>
                            {result.logs && result.logs.length > 0 && (
                              <button
                                className={styles.testLogToggle}
                                onClick={() => _toggleLogs(result.variantId)}
                                title="Logs anzeigen/ausblenden"
                              >
                                {expandedLogs.has(result.variantId) ? <FaChevronDown /> : <FaChevronRight />}
                              </button>
                            )}
                            <span className={styles.testVariantName}>{result.variantName}</span>
                          </div>
                          {result.error && (
                            <div className={styles.testErrorText} title={result.error}>
                              {result.error.length > 120 ? result.error.substring(0, 120) + '...' : result.error}
                            </div>
                          )}
                        </td>
                        <td>{_getPageTypeBadge(result)}</td>
                        <td>{result.success ? _getCheckmark(result.hasSignInLink) : <span className={styles.testDash}>—</span>}</td>
                        <td>{result.success ? _getCheckmark(result.hasNameInput) : <span className={styles.testDash}>—</span>}</td>
                        <td>{result.success ? _getCheckmark(result.hasJoinButton) : <span className={styles.testDash}>—</span>}</td>
                        <td>
                          {result.authAttempted
                            ? (result.authSuccess ? <span className={styles.testCheckmark}>Erfolgreich</span> : <span className={styles.testCross}>Fehlgeschlagen</span>)
                            : <span className={styles.testDash}>—</span>
                          }
                        </td>
                        <td><span className={styles.testDuration}>{_formatDuration(result.durationMs)}</span></td>
                        <td>
                          <div className={styles.testScreenshotButtons}>
                            {result.screenshots && result.screenshots.length > 0
                              ? result.screenshots.map((ss, idx) => (
                                <button
                                  key={idx}
                                  className={styles.testScreenshotButton}
                                  onClick={() => setScreenshotPreview({
                                    src: `data:image/jpeg;base64,${ss.data}`,
                                    caption: `${result.variantName} — ${ss.label}`,
                                  })}
                                  title={ss.label}
                                >
                                  <FaImage /> {ss.label}
                                </button>
                              ))
                              : result.screenshot && (
                                <button
                                  className={styles.testScreenshotButton}
                                  onClick={() => setScreenshotPreview({
                                    src: `data:image/jpeg;base64,${result.screenshot}`,
                                    caption: result.variantName,
                                  })}
                                >
                                  <FaImage /> Bild
                                </button>
                              )
                            }
                          </div>
                        </td>
                      </tr>
                      {expandedLogs.has(result.variantId) && result.logs && result.logs.length > 0 && (
                        <tr className={styles.testLogRow}>
                          <td colSpan={8}>
                            <div className={styles.testLogContainer}>
                              {result.logs.map((log, idx) => (
                                <div key={idx} className={`${styles.testLogLine} ${_getLogLevelClass(log)}`}>
                                  {log}
                                </div>
                              ))}
                            </div>
                          </td>
                        </tr>
                      )}
                    </React.Fragment>
                  ))}
                </tbody>
              </table>

              {(testResults.credentialsReceived || testResults.credentialDebug) && (
                <div className={styles.testLogContainer} style={{ margin: '0.5rem 0' }}>
                  <div className={`${styles.testLogLine} ${styles.testLogInfo}`}>
                    <strong>Credential-Debug:</strong>
                  </div>
                  {testResults.credentialsReceived && (
                    <div className={`${styles.testLogLine} ${testResults.credentialsReceived.hasEmail ? styles.testLogInfo : styles.testLogError}`}>
                      Bot empfangen: Email={testResults.credentialsReceived.hasEmail ? 'ja' : 'NEIN'} | Passwort={testResults.credentialsReceived.hasPassword ? 'ja' : 'NEIN'}
                    </div>
                  )}
                  {testResults.credentialDebug && (
                    <>
                      <div className={`${styles.testLogLine} ${styles.testLogInfo}`}>
                        Suche: mandateId={testResults.credentialDebug.mandateId} | Strategie={testResults.credentialDebug.searchStrategy}
                      </div>
                      <div className={`${styles.testLogLine} ${testResults.credentialDebug.botFound ? styles.testLogInfo : styles.testLogError}`}>
                        Bot gefunden: {testResults.credentialDebug.botFound ? 'ja' : 'NEIN'}
                        {testResults.credentialDebug.botEmail && ` | ${testResults.credentialDebug.botEmail}`}
                        {testResults.credentialDebug.botMandateId && ` | bot-mandate=${testResults.credentialDebug.botMandateId}`}
                        {testResults.credentialDebug.allBotsCount !== undefined && ` | total=${testResults.credentialDebug.allBotsCount}`}
                      </div>
                      {testResults.credentialDebug.passwordDecrypted !== undefined && (
                        <div className={`${styles.testLogLine} ${testResults.credentialDebug.passwordDecrypted ? styles.testLogInfo : styles.testLogError}`}>
                          Passwort entschluesselt: {testResults.credentialDebug.passwordDecrypted ? 'ja' : 'NEIN'}
                          {testResults.credentialDebug.passwordError && ` | Fehler: ${testResults.credentialDebug.passwordError}`}
                        </div>
                      )}
                    </>
                  )}
                </div>
              )}

              {testResults.recommendation && (
                <div className={styles.testRecommendation}>
                  <strong>Empfehlung:</strong> {testResults.recommendation}
                </div>
              )}
            </>
          )}
        </div>

        {/* Screenshot Overlay */}
        {screenshotPreview && (
          <div
            className={styles.testScreenshotOverlay}
            onClick={() => setScreenshotPreview(null)}
          >
            <img
              src={screenshotPreview.src}
              alt={screenshotPreview.caption}
              className={styles.testScreenshotImage}
            />
            <div className={styles.testScreenshotCaption}>
              {screenshotPreview.caption} — Klicken zum Schliessen
            </div>
          </div>
        )}

        {/* Bot Identity */}
        <div className={styles.settingsSection}>
          <h4 className={styles.sectionTitle}>Bot-Identitaet</h4>

          <div className={styles.formGroup}>
            <label className={styles.label}>Bot-Name</label>
            <input
              type="text"
              className={styles.input}
              value={formData.botName || ''}
              onChange={(e) => _updateField('botName', e.target.value)}
              placeholder="AI Assistant"
            />
            <span className={styles.hint}>Wird als Teilnehmer-Name im Meeting angezeigt</span>
          </div>

          <div className={styles.formGroup}>
            <label className={styles.label}>Hintergrundbild-URL</label>
            <input
              type="url"
              className={styles.input}
              value={formData.backgroundImageUrl || ''}
              onChange={(e) => _updateField('backgroundImageUrl', e.target.value)}
              placeholder="https://example.com/background.jpg"
            />
            <span className={styles.hint}>Hintergrundbild fuer den Video-Feed des Bots</span>
          </div>
        </div>

        {/* AI Behavior */}
        <div className={styles.settingsSection}>
          <h4 className={styles.sectionTitle}>AI-Verhalten</h4>

          <div className={styles.formGroup}>
            <label className={styles.label}>System-Prompt</label>
            <textarea
              className={styles.textarea}
              value={formData.aiSystemPrompt || ''}
              onChange={(e) => _updateField('aiSystemPrompt', e.target.value)}
              rows={6}
              placeholder="Beschreibe, wie sich der Bot im Meeting verhalten soll..."
            />
            <span className={styles.hint}>Instruktionen fuer den AI-Bot: Wann und wie soll er antworten?</span>
          </div>

          <div className={styles.formGroup}>
            <label className={styles.label}>Antwort-Modus</label>
            <select
              className={styles.select}
              value={formData.responseMode || 'auto'}
              onChange={(e) => _updateField('responseMode', e.target.value)}
            >
              <option value="auto">Automatisch - AI entscheidet selbst</option>
              <option value="manual">Manuell - Antworten muessen bestaetigt werden</option>
              <option value="transcribeOnly">Nur Transkription - Keine AI-Antworten</option>
            </select>
          </div>

          <div className={styles.formGroup}>
            <label className={styles.label}>Antwort-Kanal</label>
            <select
              className={styles.select}
              value={formData.responseChannel || 'voice'}
              onChange={(e) => _updateField('responseChannel', e.target.value)}
            >
              <option value="voice">Nur Sprache - Bot antwortet per Audio</option>
              <option value="chat">Nur Chat - Bot antwortet per Textnachricht</option>
              <option value="both">Sprache + Chat - Bot antwortet per Audio und Text</option>
            </select>
            <span className={styles.hint}>Wie soll der Bot im Meeting antworten?</span>
          </div>
        </div>

        {/* Voice Settings */}
        <div className={styles.settingsSection}>
          <h4 className={styles.sectionTitle}>Sprach-Einstellungen</h4>

          <div className={styles.formGroup}>
            <label className={styles.label}>Sprache</label>
            <select
              className={styles.select}
              value={formData.language || 'de-DE'}
              onChange={(e) => _handleLanguageChange(e.target.value)}
            >
              {languages.length > 0 ? (
                languages.map((langCode, idx) => (
                  <option key={`${langCode}-${idx}`} value={langCode}>{langCode}</option>
                ))
              ) : (
                <>
                  <option value="de-DE">Deutsch (Deutschland)</option>
                  <option value="en-US">English (US)</option>
                  <option value="fr-FR">Francais</option>
                </>
              )}
            </select>
            <span className={styles.hint}>Sprache fuer Captions und Sprachausgabe ({languages.length} Sprachen verfuegbar)</span>
          </div>

          <div className={styles.formGroup}>
            <label className={styles.label}>Stimme</label>
            <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
              <select
                className={styles.select}
                style={{ flex: 1 }}
                value={formData.voiceId || ''}
                onChange={(e) => _updateField('voiceId', e.target.value)}
                disabled={loadingVoices}
              >
                <option value="">Standard-Stimme</option>
                {voices.map(voice => (
                  <option key={voice.name} value={voice.name}>
                    {_formatVoiceName(voice)} - {voice.name}
                  </option>
                ))}
              </select>
              <button
                className={styles.testButton || styles.saveButton}
                onClick={_handleTestVoice}
                disabled={testingVoice || loadingVoices}
                title="Stimme testen"
                style={{ minWidth: '44px', padding: '8px 12px', display: 'flex', alignItems: 'center', gap: '6px' }}
              >
                {testingVoice ? <FaSpinner className={styles.spinner} /> : <FaPlay />}
                Test
              </button>
            </div>
            <span className={styles.hint}>
              {loadingVoices ? 'Lade Stimmen...' : `${voices.length} Stimmen verfuegbar - klicke Test fuer Vorschau`}
            </span>
          </div>
        </div>

        {/* Bot Account - managed by admin, read-only display */}
        <div className={styles.settingsSection}>
          <h4 className={styles.sectionTitle}>Bot-Account (Microsoft)</h4>
          <span className={styles.hint}>
            System-Bot-Accounts werden vom Administrator verwaltet und sind nicht direkt editierbar.
            Waehle beim Session-Start den gewuenschten Join-Modus.
          </span>
        </div>

        {/* Advanced Settings */}
        <div className={styles.settingsSection}>
          <h4 className={styles.sectionTitle}>Erweiterte Einstellungen</h4>

          <div className={styles.formRow}>
            <div className={styles.formGroup}>
              <label className={styles.label}>Analyse-Intervall (Sek.)</label>
              <input
                type="number"
                className={styles.input}
                value={formData.triggerIntervalSeconds || 10}
                onChange={(e) => _updateField('triggerIntervalSeconds', parseInt(e.target.value))}
                min={3}
                max={60}
              />
              <span className={styles.hint}>Periodisches Analyse-Intervall</span>
            </div>

            <div className={styles.formGroup}>
              <label className={styles.label}>Cooldown (Sek.)</label>
              <input
                type="number"
                className={styles.input}
                value={formData.triggerCooldownSeconds || 3}
                onChange={(e) => _updateField('triggerCooldownSeconds', parseInt(e.target.value))}
                min={1}
                max={30}
              />
              <span className={styles.hint}>Min. Abstand zwischen AI-Calls</span>
            </div>

            <div className={styles.formGroup}>
              <label className={styles.label}>Kontext-Fenster (Segmente)</label>
              <input
                type="number"
                className={styles.input}
                value={formData.contextWindowSegments || 20}
                onChange={(e) => _updateField('contextWindowSegments', parseInt(e.target.value))}
                min={5}
                max={100}
              />
              <span className={styles.hint}>Anzahl Transkript-Segmente fuer AI-Kontext</span>
            </div>
          </div>

          <div className={styles.formGroup}>
            <label className={styles.label}>Browser Bot URL (optional)</label>
            <input
              type="url"
              className={styles.input}
              value={formData.browserBotUrl || ''}
              onChange={(e) => _updateField('browserBotUrl', e.target.value)}
              placeholder="Automatisch aus Umgebungskonfiguration"
            />
            <span className={styles.hint}>URL des Browser Bot Service. Leer lassen fuer Standard-Konfiguration.</span>
          </div>
        </div>

        {/* Save Button */}
        <div className={styles.settingsActions}>
          <button
            className={styles.saveButton}
            onClick={_handleSave}
            disabled={saving}
          >
            {saving ? 'Speichern...' : 'Konfiguration speichern'}
          </button>
        </div>
      </div>
    </div>
  );
};

export default TeamsbotSettingsView;
