/**
 * TrusteeAnalyseView
 *
 * Tab-based analysis page. Each tab maps to a bootstrapped template workflow
 * (created from TEMPLATE_WORKFLOWS when the feature instance was set up).
 * The workflow is loaded from the instance, executed via the workflow engine,
 * and results/status are shown inline with polling.
 */

import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useToast } from '../../../contexts/ToastContext';
import api from '../../../api';
import styles from './TrusteeViews.module.css';
import { useLanguage } from '../../../providers/language/LanguageContext';
import { FaUpload, FaTimes } from 'react-icons/fa';

// ---------------------------------------------------------------------------
// Tab definitions
// ---------------------------------------------------------------------------

interface TabDef {
  id: string;
  templateTag: string;
  icon: string;
  color: string;
}

const _TABS: TabDef[] = [
  { id: 'budget', templateTag: 'template:trustee-budget-comparison', icon: '\uD83D\uDCCA', color: '#2196F3' },
  { id: 'kpi', templateTag: 'template:trustee-kpi-dashboard', icon: '\uD83D\uDCF0', color: '#9C27B0' },
  { id: 'cashflow', templateTag: 'template:trustee-cashflow', icon: '\uD83D\uDCB0', color: '#009688' },
  { id: 'forecast', templateTag: 'template:trustee-forecast', icon: '\uD83D\uDCC8', color: '#E91E63' },
];

function _tabLabel(tabId: string, t: (k: string) => string): string {
  switch (tabId) {
    case 'budget': return t('Budget-Vergleich');
    case 'kpi': return t('KPI-Dashboard');
    case 'cashflow': return t('Cashflow-Rechnung');
    case 'forecast': return t('Prognose');
    default: return tabId;
  }
}

function _tabDescription(tabId: string, t: (k: string) => string): string {
  switch (tabId) {
    case 'budget': return t('Soll/Ist-Vergleich der Buchhaltung mit Budget-Excel');
    case 'kpi': return t('Kennzahlen berechnen und visualisieren');
    case 'cashflow': return t('Cashflow berechnen und analysieren');
    case 'forecast': return t('Trend-Analyse und Prognose der nächsten Monate');
    default: return '';
  }
}

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

interface WorkflowSummary {
  id: string;
  label: string;
  tags: string[];
}

type RunState = 'idle' | 'starting' | 'running' | 'completed' | 'error';

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

export const TrusteeAnalyseView: React.FC = () => {
  const { t } = useLanguage();
  const { instanceId } = useCurrentInstance();
  const { showSuccess, showError } = useToast();
  const [searchParams, setSearchParams] = useSearchParams();

  const activeTab = searchParams.get('tab') || _TABS[0].id;
  const _setActiveTab = useCallback((tab: string) => {
    setSearchParams({ tab }, { replace: true });
  }, [setSearchParams]);

  const [workflows, setWorkflows] = useState<WorkflowSummary[]>([]);
  const [workflowsLoading, setWorkflowsLoading] = useState(true);

  const [runState, setRunState] = useState<RunState>('idle');
  const [runId, setRunId] = useState<string | null>(null);
  const [runSummary, setRunSummary] = useState('');
  const [runError, setRunError] = useState<string | null>(null);
  const pollTimerRef = useRef<number | null>(null);
  const isPollingRef = useRef(false);

  const [resultText, setResultText] = useState<string | null>(null);
  const [resultDocuments, setResultDocuments] = useState<Array<{ id?: string; fileName?: string; mimeType?: string }>>([]);

  const [budgetFileId, setBudgetFileId] = useState<string | null>(null);
  const [budgetFileName, setBudgetFileName] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Load workflows for this instance once
  useEffect(() => {
    if (!instanceId) return;
    const _load = async () => {
      setWorkflowsLoading(true);
      try {
        const res = await api.get(`/api/workflows/${instanceId}/workflows`);
        const items: WorkflowSummary[] = (res.data?.workflows || res.data?.items || []).map((w: any) => ({
          id: w.id,
          label: w.label,
          tags: w.tags || [],
        }));
        setWorkflows(items);
      } catch {
        setWorkflows([]);
      } finally {
        setWorkflowsLoading(false);
      }
    };
    _load();
  }, [instanceId]);

  // Find the workflow for the active tab
  const _findWorkflow = useCallback((tab: string): WorkflowSummary | undefined => {
    const tabDef = _TABS.find((tabItem) => tabItem.id === tab);
    if (!tabDef) return undefined;
    return workflows.find((w) => w.tags.includes(tabDef.templateTag));
  }, [workflows]);

  // Polling
  const _stopPolling = useCallback(() => {
    if (pollTimerRef.current !== null) {
      window.clearInterval(pollTimerRef.current);
      pollTimerRef.current = null;
    }
    isPollingRef.current = false;
  }, []);

  const _pollRun = useCallback(async (rid: string) => {
    if (!instanceId || !rid || isPollingRef.current) return;
    isPollingRef.current = true;
    try {
      const res = await api.get(`/api/workflows/${instanceId}/runs/${rid}/steps`);
      const steps: any[] = Array.isArray(res?.data?.steps) ? res.data.steps : [];
      const completed = steps.filter((s) => s.status === 'completed');
      const failed = steps.filter((s) => s.status === 'failed');
      const running = steps.filter((s) => s.status === 'running');

      setRunSummary(`${completed.length}/${steps.length} ${t('Schritte abgeschlossen')}`);

      if (failed.length > 0) {
        const errMsg = failed[failed.length - 1].error || t('Schritt fehlgeschlagen');
        setRunState('error');
        setRunError(errMsg);
        _stopPolling();
        showError(t('Pipeline-Fehler'), errMsg);
        return;
      }
      if (running.length === 0 && completed.length === steps.length && steps.length > 0) {
        setRunState('completed');
        _stopPolling();
        const lastStep = [...steps].reverse().find((s) => s.status === 'completed' && s.output);
        if (lastStep?.output) {
          setResultText(lastStep.output.response || lastStep.output.context || null);
          const docs = lastStep.output.documents || lastStep.output.documentList || [];
          setResultDocuments(Array.isArray(docs) ? docs : []);
        }
        showSuccess(t('Abgeschlossen'), t('Analyse-Workflow erfolgreich beendet.'));
        return;
      }
      setRunState('running');
    } catch (err: any) {
      if (err?.response?.status === 404) {
        setRunState('running');
        return;
      }
      setRunState('error');
      setRunError(err.message || t('Abfrage fehlgeschlagen'));
      _stopPolling();
    } finally {
      isPollingRef.current = false;
    }
  }, [instanceId, showError, showSuccess, _stopPolling, t]);

  useEffect(() => {
    if (!instanceId || !runId || (runState !== 'running' && runState !== 'starting')) return;
    void _pollRun(runId);
    pollTimerRef.current = window.setInterval(() => { void _pollRun(runId); }, 3000);
    return () => { _stopPolling(); };
  }, [instanceId, runId, runState, _pollRun, _stopPolling]);

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

  const _extractResults = useCallback((nodeOutputs: Record<string, any>) => {
    const analyseOut = nodeOutputs?.analyse || nodeOutputs?.result;
    if (!analyseOut) {
      for (const key of Object.keys(nodeOutputs || {})) {
        const v = nodeOutputs[key];
        if (v && typeof v === 'object' && (v.response || v.documents)) {
          setResultText(v.response || v.context || null);
          const docs = v.documents || v.documentList || [];
          setResultDocuments(Array.isArray(docs) ? docs : []);
          return;
        }
      }
      return;
    }
    setResultText(analyseOut.response || analyseOut.context || null);
    const docs = analyseOut.documents || analyseOut.documentList || [];
    setResultDocuments(Array.isArray(docs) ? docs : []);
  }, []);

  // Reset run state when tab changes
  useEffect(() => {
    _stopPolling();
    setRunState('idle');
    setRunId(null);
    setRunSummary('');
    setRunError(null);
    setResultText(null);
    setResultDocuments([]);
  }, [activeTab, _stopPolling]);

  const _handleBudgetUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file || !instanceId) return;
    setUploading(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('featureInstanceId', instanceId);
      const res = await api.post('/api/files/upload', formData);
      const fileData = res.data?.file || res.data;
      setBudgetFileId(fileData.id);
      setBudgetFileName(fileData.fileName || file.name);
      showSuccess(t('Datei hochgeladen'), file.name);
    } catch (err: any) {
      showError(t('Upload fehlgeschlagen'), err.message || t('Datei konnte nicht hochgeladen werden.'));
    } finally {
      setUploading(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  }, [instanceId, showSuccess, showError, t]);

  const _handleRemoveBudgetFile = useCallback(() => {
    setBudgetFileId(null);
    setBudgetFileName(null);
  }, []);

  // Execute workflow
  const _handleExecute = useCallback(async () => {
    const wf = _findWorkflow(activeTab);
    if (!wf || !instanceId) {
      showError(t('Fehler'), t('Kein Workflow für diesen Tab gefunden.'));
      return;
    }
    if (activeTab === 'budget' && !budgetFileId) {
      showError(t('Budget-Datei fehlt'), t('Bitte laden Sie zuerst die Budget-Excel-Datei hoch.'));
      return;
    }
    setRunState('starting');
    setRunError(null);
    setRunSummary(t('Workflow wird gestartet…'));
    setResultText(null);
    setResultDocuments([]);
    try {
      const executeBody: Record<string, any> = { workflowId: wf.id };
      if (activeTab === 'budget' && budgetFileId) {
        executeBody.payload = { documentList: [budgetFileId] };
      }
      const res = await api.post(`/api/workflows/${instanceId}/execute`, executeBody);
      const rid = res?.data?.runId;
      if (rid) {
        setRunId(rid);
        setRunState('running');
        setRunSummary(t('Lauf {prefix} gestartet', { prefix: rid.slice(0, 8) }));
      } else if (res?.data?.success) {
        setRunState('completed');
        setRunSummary(t('Workflow synchron abgeschlossen.'));
        if (res.data.nodeOutputs) {
          _extractResults(res.data.nodeOutputs);
        }
        showSuccess(t('Abgeschlossen'), t('Analyse-Workflow erfolgreich beendet.'));
      } else {
        throw new Error(res?.data?.error || t('Unerwartete Antwort'));
      }
    } catch (err: any) {
      const msg = err?.response?.data?.detail || err.message || t('Workflow konnte nicht gestartet werden.');
      setRunState('error');
      setRunError(typeof msg === 'string' ? msg : JSON.stringify(msg));
      showError(t('Fehler'), typeof msg === 'string' ? msg : JSON.stringify(msg));
    }
  }, [activeTab, instanceId, _findWorkflow, budgetFileId, showError, showSuccess, t]);

  const currentTab = _TABS.find((tabItem) => tabItem.id === activeTab) || _TABS[0];
  const currentWorkflow = _findWorkflow(activeTab);

  return (
    <div className={styles.listView}>
      <div className={styles.expenseImportSection}>
        <h3 className={styles.sectionTitle}>{t('Analyse & Reporting')}</h3>

        {/* Tab bar */}
        <div style={{ display: 'flex', gap: '0.25rem', marginBottom: '1.5rem', borderBottom: '2px solid var(--border-color, #e0e0e0)', paddingBottom: 0 }}>
          {_TABS.map((tab) => (
            <button
              key={tab.id}
              onClick={() => _setActiveTab(tab.id)}
              style={{
                padding: '0.625rem 1rem',
                border: 'none',
                borderBottom: activeTab === tab.id ? `3px solid ${tab.color}` : '3px solid transparent',
                background: 'transparent',
                color: activeTab === tab.id ? 'var(--text-primary, #1a1a1a)' : 'var(--text-secondary, #666)',
                fontWeight: activeTab === tab.id ? 600 : 400,
                fontSize: '0.875rem',
                cursor: 'pointer',
                transition: 'all 0.2s',
                marginBottom: '-2px',
              }}
            >
              <span style={{ marginRight: '0.375rem' }}>{tab.icon}</span>
              {_tabLabel(tab.id, t)}
            </button>
          ))}
        </div>

        {/* Tab content */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
          <p className={styles.sectionDescription}>
            {_tabDescription(activeTab, t)}
          </p>

          {workflowsLoading ? (
            <p className={styles.loadingText}>{t('Workflows werden geladen…')}</p>
          ) : !currentWorkflow ? (
            <div className={styles.infoBox}>
              <p>{t('Für diesen Tab wurde kein Workflow in der Instanz gefunden. Der Workflow wird beim Erstellen der Instanz automatisch angelegt.')}</p>
            </div>
          ) : (
            <>
              <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
                <span style={{ fontSize: '2rem' }}>{currentTab.icon}</span>
                <div>
                  <div style={{ fontWeight: 600, color: 'var(--text-primary, #1a1a1a)' }}>{currentWorkflow.label}</div>
                  <div style={{ fontSize: '0.8125rem', color: 'var(--text-secondary, #666)' }}>
                    {t('Workflow-ID:')} {currentWorkflow.id.slice(0, 8)}…
                  </div>
                </div>
              </div>

              {activeTab === 'budget' && (
                <div style={{
                  padding: '1rem',
                  border: '1px dashed var(--border-color, #ccc)',
                  borderRadius: '8px',
                  background: 'var(--bg-secondary, #f9f9f9)',
                }}>
                  <div style={{ fontWeight: 600, marginBottom: '0.5rem', fontSize: '0.875rem' }}>
                    {t('Budget-Excel hochladen')}
                  </div>
                  {budgetFileName ? (
                    <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
                      <span style={{ fontSize: '0.875rem' }}>📄 {budgetFileName}</span>
                      <button
                        onClick={_handleRemoveBudgetFile}
                        style={{
                          background: 'none', border: 'none', cursor: 'pointer',
                          color: 'var(--text-secondary, #666)', padding: '0.25rem',
                        }}
                        title={t('Datei entfernen')}
                      >
                        <FaTimes />
                      </button>
                    </div>
                  ) : (
                    <label style={{
                      display: 'inline-flex', alignItems: 'center', gap: '0.5rem',
                      padding: '0.5rem 1rem', borderRadius: '6px', cursor: uploading ? 'wait' : 'pointer',
                      border: '1px solid var(--border-color, #ccc)', background: 'var(--bg-primary, #fff)',
                      fontSize: '0.875rem', color: 'var(--text-primary, #333)',
                    }}>
                      <FaUpload />
                      {uploading ? t('Wird hochgeladen…') : t('Excel-Datei auswählen')}
                      <input
                        ref={fileInputRef}
                        type="file"
                        accept=".xlsx,.xls,.csv"
                        onChange={_handleBudgetUpload}
                        disabled={uploading}
                        style={{ display: 'none' }}
                      />
                    </label>
                  )}
                </div>
              )}

              <button
                className={styles.primaryButton}
                onClick={_handleExecute}
                disabled={runState === 'starting' || runState === 'running' || (activeTab === 'budget' && !budgetFileId)}
                style={{ alignSelf: 'flex-start' }}
              >
                {runState === 'starting' || runState === 'running'
                  ? t('Läuft…')
                  : t('Ausführen')}
              </button>
            </>
          )}

          {/* Pipeline status */}
          {runState !== 'idle' && (
            <div className={runState === 'error' ? styles.errorMessage : styles.successMessage}>
              <strong>{t('Status')}:</strong>{' '}
              {runState === 'starting' && t('Wird gestartet…')}
              {runState === 'running' && t('Läuft')}
              {runState === 'completed' && t('Abgeschlossen')}
              {runState === 'error' && t('Fehler')}
              {runSummary && <div style={{ marginTop: '0.25rem' }}>{runSummary}</div>}
              {runError && <div style={{ marginTop: '0.25rem' }}>{runError}</div>}
            </div>
          )}

          {/* Results */}
          {runState === 'completed' && (resultText || resultDocuments.length > 0) && (
            <div style={{
              marginTop: '0.5rem',
              border: '1px solid var(--border-color, #e0e0e0)',
              borderRadius: '8px',
              overflow: 'hidden',
            }}>
              {resultDocuments.length > 0 && (
                <div style={{
                  padding: '0.75rem 1rem',
                  background: 'var(--bg-secondary, #f9f9f9)',
                  borderBottom: resultText ? '1px solid var(--border-color, #e0e0e0)' : 'none',
                  display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center',
                }}>
                  <strong style={{ fontSize: '0.8125rem' }}>{t('Generierte Dokumente:')}</strong>
                  {resultDocuments.map((doc, idx) => {
                    const docId = doc.id || (typeof doc === 'string' ? doc : null);
                    const docName = doc.fileName || `Dokument ${idx + 1}`;
                    if (!docId) return null;
                    return (
                      <a
                        key={docId}
                        href={`${api.defaults.baseURL || ''}/api/files/${docId}/download`}
                        target="_blank"
                        rel="noopener noreferrer"
                        style={{
                          display: 'inline-flex', alignItems: 'center', gap: '0.375rem',
                          padding: '0.375rem 0.75rem', borderRadius: '6px',
                          background: 'var(--primary-color, #007bff)', color: '#fff',
                          fontSize: '0.8125rem', textDecoration: 'none', fontWeight: 500,
                        }}
                      >
                        📄 {docName}
                      </a>
                    );
                  })}
                </div>
              )}
              {resultText && (
                <div style={{
                  padding: '1rem',
                  fontSize: '0.875rem',
                  lineHeight: 1.6,
                  whiteSpace: 'pre-wrap',
                  maxHeight: '400px',
                  overflowY: 'auto',
                  background: 'var(--bg-primary, #fff)',
                }}>
                  {resultText}
                </div>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default TrusteeAnalyseView;
