/**
 * AddConnectionWizard
 *
 * Multi-step modal for adding a new connector with optional knowledge
 * ingestion consent and per-connection preferences (§2.6).
 *
 * Steps:
 *   0 — Connector wählen
 *   1 — Consent (Wissensdatenbank Ja/Nein)
 *   2 — Präferenzen (nur wenn Ja)
 *   3 — Zusammenfassung + OAuth starten
 */

import React, { useState } from 'react';
import { Modal } from '../UiComponents/Modal/Modal';
import { FaGoogle, FaMicrosoft, FaTasks, FaDatabase, FaShieldAlt, FaCheck, FaArrowRight, FaInfoCircle } from 'react-icons/fa';
import type { KnowledgePreferences } from '../../api/connectionApi';
import styles from './AddConnectionWizard.module.css';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export type ConnectorType = 'google' | 'msft' | 'clickup';

interface WizardState {
  step: 0 | 1 | 2 | 3;
  connector: ConnectorType | null;
  knowledgeEnabled: boolean;
  prefs: KnowledgePreferences;
}

const DEFAULT_PREFS: KnowledgePreferences = {
  schemaVersion: 1,
  neutralizeBeforeEmbed: false,
  mailContentDepth: 'full',
  mailIndexAttachments: false,
  filesIndexBinaries: true,
  clickupScope: 'title_description',
  clickupIndexAttachments: false,
  maxAgeDays: 90,
};

const CONNECTOR_LABELS: Record<ConnectorType, string> = {
  google: 'Google',
  msft: 'Microsoft 365',
  clickup: 'ClickUp',
};

const CONNECTOR_ICONS: Record<ConnectorType, React.ReactNode> = {
  google: <FaGoogle style={{ color: '#4285f4' }} />,
  msft: <FaMicrosoft style={{ color: '#00a4ef' }} />,
  clickup: <FaTasks style={{ color: '#7b68ee' }} />,
};

// ---------------------------------------------------------------------------
// Cost estimate helper
// ---------------------------------------------------------------------------

/**
 * Returns a cost estimate broken into two lines:
 *
 * 1. Embedding (OpenAI text-embedding-3-small, $0.02 / 1M tokens) — always tiny.
 * 2. Neutralization (Private LLM / qwen2.5 on-premise, CHF 0.01 per LLM call)
 *    — this is the DOMINANT cost when enabled.  One call per email/task for
 *    short content; several calls for long threads or files.
 *
 * Numbers are conservative ranges.  Subsequent syncs are cheaper because
 * unchanged content is deduplicated before any LLM/embedding call.
 */
function computeCostEstimate(
  connector: ConnectorType | null,
  prefs: KnowledgePreferences,
): {
  embeddingLow: string;
  embeddingHigh: string;
  neutralizationLow: string | null;
  neutralizationHigh: string | null;
  note: string;
} | null {
  if (!connector) return null;

  // ---- Embedding (OpenAI, USD) ----
  const EMBED_USD_PER_M = 0.02;
  const tokensPerMail: Record<string, number> = { metadata: 30, snippet: 120, full: 500 };
  const depth = prefs.mailContentDepth ?? 'full';
  const maxAge = prefs.maxAgeDays ?? 90;
  const mailCount = Math.min(500, Math.round((maxAge / 90) * 500));
  const taskCount = Math.min(500, Math.round((maxAge / 90) * 300));

  let embedLowTokens = 0;
  let embedHighTokens = 0;

  if (connector === 'google' || connector === 'msft') {
    const mailTokens = mailCount * tokensPerMail[depth];
    embedLowTokens += mailTokens * 0.6;
    embedHighTokens += mailTokens * 1.5 + 500_000; // Drive/SharePoint
    if (prefs.mailIndexAttachments) embedHighTokens += 200_000;
  } else if (connector === 'clickup') {
    const scope = prefs.clickupScope ?? 'title_description';
    const tpt = scope === 'titles' ? 30 : scope === 'title_description' ? 200 : 400;
    embedLowTokens += taskCount * tpt * 0.6;
    embedHighTokens += taskCount * tpt * 1.5;
  }

  const fmtUsd = (tokens: number) => {
    const usd = (tokens / 1_000_000) * EMBED_USD_PER_M;
    if (usd < 0.001) return '< 0.01 $';
    if (usd < 0.10) return `~${usd.toFixed(3)} $`;
    return `~${usd.toFixed(2)} $`;
  };

  // ---- Neutralization (Private LLM, CHF 0.01/call) ----
  // Each item (email / task / file) = 1 LLM call for short content,
  // 2-4 for long threads/documents.
  const NEUT_CHF_PER_CALL = 0.01;
  let neutLow: string | null = null;
  let neutHigh: string | null = null;

  if (prefs.neutralizeBeforeEmbed) {
    let lowCalls = 0;
    let highCalls = 0;

    if (connector === 'google' || connector === 'msft') {
      lowCalls += mailCount * 1;     // 1 call / short email
      highCalls += mailCount * 3;    // up to 3 calls / long thread
      lowCalls += 20;                // Drive/SharePoint files (low)
      highCalls += 200;              // Drive/SharePoint files (high, large PDFs)
    } else if (connector === 'clickup') {
      lowCalls += taskCount * 1;
      highCalls += taskCount * 2;
    }

    const fmtChf = (calls: number) => {
      const chf = calls * NEUT_CHF_PER_CALL;
      if (chf < 0.01) return '< 0.01 CHF';
      return `~${chf.toFixed(2)} CHF`;
    };

    neutLow = fmtChf(lowCalls);
    neutHigh = fmtChf(highCalls);
  }

  return {
    embeddingLow: fmtUsd(embedLowTokens),
    embeddingHigh: fmtUsd(embedHighTokens),
    neutralizationLow: neutLow,
    neutralizationHigh: neutHigh,
    note: 'Einmalig beim ersten Sync. Folge-Syncs kosten weniger (nur neue Inhalte).',
  };
}

// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------

interface AddConnectionWizardProps {
  open: boolean;
  onClose: () => void;
  onConnect: (
    type: ConnectorType,
    knowledgeEnabled: boolean,
    prefs: KnowledgePreferences | null,
  ) => Promise<void>;
  isConnecting?: boolean;
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export const AddConnectionWizard: React.FC<AddConnectionWizardProps> = ({
  open,
  onClose,
  onConnect,
  isConnecting = false,
}) => {
  const [state, setState] = useState<WizardState>({
    step: 0,
    connector: null,
    knowledgeEnabled: false,
    prefs: { ...DEFAULT_PREFS },
  });

  const reset = () =>
    setState({ step: 0, connector: null, knowledgeEnabled: false, prefs: { ...DEFAULT_PREFS } });

  const handleClose = () => {
    reset();
    onClose();
  };

  const setStep = (step: WizardState['step']) => setState(s => ({ ...s, step }));
  const setConnector = (connector: ConnectorType) =>
    setState(s => ({ ...s, connector, step: 1 }));
  const setKnowledgeEnabled = (v: boolean) =>
    setState(s => ({ ...s, knowledgeEnabled: v, step: v ? 2 : 3 }));
  const updatePref = <K extends keyof KnowledgePreferences>(key: K, value: KnowledgePreferences[K]) =>
    setState(s => ({ ...s, prefs: { ...s.prefs, [key]: value } }));

  const handleConnect = async () => {
    if (!state.connector) return;
    await onConnect(
      state.connector,
      state.knowledgeEnabled,
      state.knowledgeEnabled ? state.prefs : null,
    );
    reset();
    onClose();
  };

  const visibleSteps = state.knowledgeEnabled
    ? [0, 1, 2, 3]
    : [0, 1, 3];

  return (
    <Modal
      open={open}
      onClose={handleClose}
      title="Verbindung hinzufügen"
      size="md"
      closeOnEscape
    >
      {/* Stepper */}
      <div className={styles.stepper}>
        {[0, 1, 2, 3].map(i => (
          <div
            key={i}
            className={[
              styles.stepDot,
              state.step === i ? styles.stepDotActive : '',
              state.step > i ? styles.stepDotDone : '',
              !visibleSteps.includes(i) ? styles.stepDotHidden : '',
            ].join(' ')}
          >
            {state.step > i ? <FaCheck size={10} /> : i + 1}
          </div>
        ))}
      </div>

      <div className={styles.body}>
        {/* ---- Step 0: Connector ---- */}
        {state.step === 0 && (
          <div className={styles.stepContent}>
            <h3 className={styles.stepTitle}>Anbieter wählen</h3>
            <p className={styles.stepHint}>Welchen Dienst möchtest du verbinden?</p>
            <div className={styles.connectorGrid}>
              {(['google', 'msft', 'clickup'] as ConnectorType[]).map(type => (
                <button
                  key={type}
                  type="button"
                  className={styles.connectorCard}
                  onClick={() => setConnector(type)}
                >
                  <span className={styles.connectorIcon}>{CONNECTOR_ICONS[type]}</span>
                  <span className={styles.connectorLabel}>{CONNECTOR_LABELS[type]}</span>
                </button>
              ))}
            </div>
          </div>
        )}

        {/* ---- Step 1: Consent ---- */}
        {state.step === 1 && (
          <div className={styles.stepContent}>
            <div className={styles.consentIcon}><FaDatabase size={32} /></div>
            <h3 className={styles.stepTitle}>Wissensdatenbank</h3>
            <p className={styles.stepBody}>
              Möchtest du Inhalte aus dieser Verbindung in deine persönliche
              Wissensdatenbank aufnehmen, damit die KI beim Antworten auf Informationen
              aus{' '}
              {state.connector ? CONNECTOR_LABELS[state.connector] : 'diesem Dienst'}{' '}
              zurückgreifen kann?
            </p>
            <p className={styles.stepHint}>
              Du kannst diese Einstellung später in den Verbindungsdetails ändern.
            </p>
            <div className={styles.consentButtons}>
              <button
                type="button"
                className={styles.consentButtonYes}
                onClick={() => setKnowledgeEnabled(true)}
              >
                <FaCheck /> Ja, aufnehmen
              </button>
              <button
                type="button"
                className={styles.consentButtonNo}
                onClick={() => setKnowledgeEnabled(false)}
              >
                Nein, überspringen
              </button>
            </div>
            <div className={styles.stepNavLeft}>
              <button type="button" className={styles.navBack} onClick={() => setStep(0)}>
                Zurück
              </button>
            </div>
          </div>
        )}

        {/* ---- Step 2: Preferences ---- */}
        {state.step === 2 && (
          <div className={styles.stepContent}>
            <h3 className={styles.stepTitle}>Einstellungen</h3>
            <p className={styles.stepHint}>
              Steuere, welche Inhalte und in welcher Form sie indexiert werden.
            </p>

            <div className={styles.prefGroup}>
              <label className={styles.prefLabel}>
                <FaShieldAlt className={styles.prefIcon} />
                Anonymisierung vor dem Indexieren
                <input
                  type="checkbox"
                  checked={!!state.prefs.neutralizeBeforeEmbed}
                  onChange={e => updatePref('neutralizeBeforeEmbed', e.target.checked)}
                  className={styles.prefCheck}
                />
              </label>
              <p className={styles.prefHint}>
                Persönliche Daten (Namen, E-Mail-Adressen) werden vor dem Speichern ersetzt.
              </p>
            </div>

            {(state.connector === 'google' || state.connector === 'msft') && (
              <>
                <div className={styles.prefGroup}>
                  <label className={styles.prefLabelRow}>
                    E-Mail-Inhalt
                    <select
                      value={state.prefs.mailContentDepth ?? 'full'}
                      onChange={e => updatePref('mailContentDepth', e.target.value as any)}
                      className={styles.prefSelect}
                    >
                      <option value="metadata">Nur Metadaten (Betreff, Absender, Datum)</option>
                      <option value="snippet">Vorschautext (ca. 250 Zeichen)</option>
                      <option value="full">Vollständiger Text</option>
                    </select>
                  </label>
                </div>
                <div className={styles.prefGroup}>
                  <label className={styles.prefLabel}>
                    E-Mail-Anhänge indexieren
                    <input
                      type="checkbox"
                      checked={!!state.prefs.mailIndexAttachments}
                      onChange={e => updatePref('mailIndexAttachments', e.target.checked)}
                      className={styles.prefCheck}
                    />
                  </label>
                </div>
              </>
            )}

            {state.connector === 'clickup' && (
              <div className={styles.prefGroup}>
                <label className={styles.prefLabelRow}>
                  Aufgaben-Inhalt
                  <select
                    value={state.prefs.clickupScope ?? 'title_description'}
                    onChange={e => updatePref('clickupScope', e.target.value as any)}
                    className={styles.prefSelect}
                  >
                    <option value="titles">Nur Aufgabentitel</option>
                    <option value="title_description">Titel + Beschreibung</option>
                    <option value="with_comments">Titel + Beschreibung + Kommentare</option>
                  </select>
                </label>
              </div>
            )}

            <div className={styles.prefGroup}>
              <label className={styles.prefLabelRow}>
                Zeitfenster (Tage)
                <input
                  type="number"
                  min={0}
                  max={3650}
                  value={state.prefs.maxAgeDays ?? 90}
                  onChange={e => updatePref('maxAgeDays', parseInt(e.target.value, 10) || 0)}
                  className={styles.prefNumber}
                />
              </label>
              <p className={styles.prefHint}>0 = kein Limit</p>
            </div>

            <div className={styles.stepNav}>
              <button type="button" className={styles.navBack} onClick={() => setStep(1)}>
                Zurück
              </button>
              <button type="button" className={styles.navNext} onClick={() => setStep(3)}>
                Weiter <FaArrowRight size={12} />
              </button>
            </div>
          </div>
        )}

        {/* ---- Step 3: Summary ---- */}
        {state.step === 3 && (
          <div className={styles.stepContent}>
            <h3 className={styles.stepTitle}>Zusammenfassung</h3>
            <div className={styles.summary}>
              <div className={styles.summaryRow}>
                <span className={styles.summaryKey}>Anbieter</span>
                <span className={styles.summaryVal}>
                  {CONNECTOR_ICONS[state.connector!]}&nbsp;
                  {state.connector ? CONNECTOR_LABELS[state.connector] : '—'}
                </span>
              </div>
              <div className={styles.summaryRow}>
                <span className={styles.summaryKey}>Wissensdatenbank</span>
                <span className={styles.summaryVal}>
                  {state.knowledgeEnabled ? '✓ Aktiv' : '✗ Nicht aktiv'}
                </span>
              </div>
              {state.knowledgeEnabled && (
                <>
                  <div className={styles.summaryRow}>
                    <span className={styles.summaryKey}>Anonymisierung</span>
                    <span className={styles.summaryVal}>
                      {state.prefs.neutralizeBeforeEmbed ? 'Ja' : 'Nein'}
                    </span>
                  </div>
                  {(state.connector === 'google' || state.connector === 'msft') && (
                    <div className={styles.summaryRow}>
                      <span className={styles.summaryKey}>E-Mail-Tiefe</span>
                      <span className={styles.summaryVal}>
                        {{ metadata: 'Nur Metadaten', snippet: 'Vorschautext', full: 'Volltext' }[
                          state.prefs.mailContentDepth ?? 'full'
                        ] ?? state.prefs.mailContentDepth}
                      </span>
                    </div>
                  )}
                  {state.connector === 'clickup' && (
                    <div className={styles.summaryRow}>
                      <span className={styles.summaryKey}>Aufgaben-Inhalt</span>
                      <span className={styles.summaryVal}>
                        {{
                          titles: 'Nur Titel',
                          title_description: 'Titel + Beschreibung',
                          with_comments: 'Titel + Beschreibung + Kommentare',
                        }[state.prefs.clickupScope ?? 'title_description'] ?? state.prefs.clickupScope}
                      </span>
                    </div>
                  )}
                  <div className={styles.summaryRow}>
                    <span className={styles.summaryKey}>Zeitfenster</span>
                    <span className={styles.summaryVal}>
                      {state.prefs.maxAgeDays ? `${state.prefs.maxAgeDays} Tage` : 'Unbegrenzt'}
                    </span>
                  </div>
                </>
              )}
            </div>

            {/* Cost estimate — only shown when knowledge ingestion is enabled */}
            {state.knowledgeEnabled && (() => {
              const est = computeCostEstimate(state.connector, state.prefs);
              if (!est) return null;
              return (
                <div className={styles.costHint}>
                  <FaInfoCircle className={styles.costHintIcon} />
                  <div>
                    <span className={styles.costHintTitle}>Geschätzte Kosten (erster Sync)</span>
                    <table className={styles.costTable}>
                      <tbody>
                        <tr>
                          <td className={styles.costLabel}>Embedding</td>
                          <td className={styles.costVal}>
                            {est.embeddingLow} – {est.embeddingHigh}
                          </td>
                        </tr>
                        {est.neutralizationLow && (
                          <tr className={styles.costRowNeut}>
                            <td className={styles.costLabel}>Anonymisierung (Private LLM)</td>
                            <td className={styles.costVal}>
                              {est.neutralizationLow} – {est.neutralizationHigh}
                            </td>
                          </tr>
                        )}
                      </tbody>
                    </table>
                    {est.neutralizationLow && (
                      <span className={styles.costHintWarn}>
                        ⚠ Anonymisierung ist der Hauptkostentreiber (CHF 0.01 pro LLM-Aufruf, on-premise).
                      </span>
                    )}
                    <span className={styles.costHintNote}>{est.note}</span>
                  </div>
                </div>
              );
            })()}

            <div className={styles.stepNav}>
              <button
                type="button"
                className={styles.navBack}
                onClick={() => setStep(state.knowledgeEnabled ? 2 : 1)}
              >
                Zurück
              </button>
              <button
                type="button"
                className={styles.navConnect}
                onClick={handleConnect}
                disabled={isConnecting}
              >
                {isConnecting ? 'Verbinden…' : `Mit ${state.connector ? CONNECTOR_LABELS[state.connector] : '…'} verbinden`}
                {!isConnecting && <FaArrowRight size={12} />}
              </button>
            </div>
          </div>
        )}
      </div>
    </Modal>
  );
};

export default AddConnectionWizard;
