/**
 * AutomationsDashboardPage
 *
 * System-level automation page with two tabs:
 * - Dashboard: Metrics + workflow runs table (backend-paginated)
 * - Workflows: Central management of all RBAC-accessible workflows across instances
 */

import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { FaSync, FaPlay, FaCog, FaChartBar, FaDownload, FaCheck, FaBan, FaPen, FaEye } from 'react-icons/fa';
import { FormGeneratorTable, type ColumnConfig } from '../components/FormGenerator';
import { Tabs } from '../components/UiComponents/Tabs';
import { useToast } from '../contexts/ToastContext';
import { usePrompt } from '../hooks/usePrompt';
import { useApiRequest } from '../hooks/useApi';
import { formatUnixTimestamp } from '../utils/time';
import { updateWorkflow, executeGraph, deleteWorkflow } from '../api/workflowApi';
import api from '../api';
import { useLanguage } from '../providers/language/LanguageContext';
import styles from './admin/Admin.module.css';

// ---------------------------------------------------------------------------
// Shared types & helpers
// ---------------------------------------------------------------------------

interface WorkflowRunMetrics {
  totalRuns: number;
  runsByStatus: Record<string, number>;
  totalTokens: number;
  totalCredits: number;
  workflowCount: number;
  activeWorkflows: number;
}

interface WorkflowRun {
  id: string;
  workflowId: string;
  workflowLabel?: string;
  mandateId?: string;
  ownerId?: string;
  status: string;
  costTokens?: number;
  costCredits?: number;
  sysCreatedAt?: number;
  sysModifiedAt?: number;
}

interface SystemWorkflow {
  id: string;
  mandateId: string;
  featureInstanceId: string;
  label: string;
  active: boolean;
  isRunning?: boolean;
  stuckAtNodeLabel?: string;
  stuckAtNodeId?: string;
  createdAt?: number;
  sysCreatedAt?: number;
  lastStartedAt?: number;
  runCount?: number;
  mandateLabel?: string;
  instanceLabel?: string;
  canEdit?: boolean;
  canDelete?: boolean;
  canExecute?: boolean;
  invocations?: Array<{ id: string; enabled: boolean; kind: string }>;
  graph?: Record<string, any>;
}

function _formatTs(ts?: number): string {
  if (ts == null || ts <= 0) return '—';
  const sec = ts < 1e12 ? ts : ts / 1000;
  const { time } = formatUnixTimestamp(sec, undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
  return time;
}

const _STATUS_COLORS: Record<string, string> = {
  completed: 'var(--success-color, #28a745)',
  failed: 'var(--danger-color, #dc3545)',
  running: 'var(--primary-color, #007bff)',
  paused: 'var(--warning-color, #ffc107)',
  cancelled: 'var(--text-secondary, #666)',
};

// ---------------------------------------------------------------------------
// MetricCard
// ---------------------------------------------------------------------------

interface MetricCardProps {
  icon: React.ReactNode;
  label: string;
  value: string | number;
  color?: string;
}

const MetricCard: React.FC<MetricCardProps> = ({ icon, label, value, color }) => (
  <div
    style={{
      background: 'var(--bg-primary, #fff)',
      border: '1px solid var(--border-color, #e0e0e0)',
      borderRadius: 8,
      padding: '16px 20px',
      display: 'flex',
      alignItems: 'center',
      gap: 14,
      minWidth: 180,
      flex: '1 1 180px',
    }}
  >
    <div style={{ fontSize: 22, color: color || 'var(--primary-color, #007bff)', display: 'flex', alignItems: 'center' }}>
      {icon}
    </div>
    <div>
      <div style={{ fontSize: '0.8rem', color: 'var(--text-secondary, #666)', marginBottom: 2 }}>{label}</div>
      <div style={{ fontSize: '1.3rem', fontWeight: 700 }}>{value}</div>
    </div>
  </div>
);

// ===========================================================================
// DashboardTab — Metrics + Runs table with backend pagination
// ===========================================================================

const _DashboardTab: React.FC = () => {
  const { t } = useLanguage();
  const { showError } = useToast();

  const [metrics, setMetrics] = useState<WorkflowRunMetrics | null>(null);
  const [runs, setRuns] = useState<WorkflowRun[]>([]);
  const [loading, setLoading] = useState(true);
  const [paginationMeta, setPaginationMeta] = useState<any>(null);

  const _loadMetrics = useCallback(async () => {
    try {
      const resp = await api.get('/api/system/workflow-runs/metrics');
      setMetrics(resp.data);
    } catch (e) {
      console.error('[automations] metrics load failed', e);
    }
  }, []);

  const _loadRuns = useCallback(async (paginationParams?: any) => {
    setLoading(true);
    try {
      const params: Record<string, any> = { limit: paginationParams?.pageSize || 25 };
      if (paginationParams?.page) {
        params.offset = ((paginationParams.page - 1) * (paginationParams.pageSize || 25));
      }
      if (paginationParams?.search) {
        params.search = paginationParams.search;
      }
      const resp = await api.get('/api/system/workflow-runs', { params });
      const data = resp.data;
      setRuns(data?.runs || []);
      const total = data?.total ?? 0;
      const pageSize = params.limit;
      setPaginationMeta({
        currentPage: paginationParams?.page || 1,
        pageSize,
        totalItems: total,
        totalPages: Math.ceil(total / pageSize),
      });
    } catch (e) {
      console.error('[automations] runs load failed', e);
      showError(t('Fehler beim Laden der Workflow-Runs'));
    } finally {
      setLoading(false);
    }
  }, [showError, t]);

  useEffect(() => {
    _loadMetrics();
    _loadRuns();
  }, [_loadMetrics, _loadRuns]);

  const _downloadRunTracing = useCallback(async (run: WorkflowRun) => {
    if (!run.id) return;
    try {
      const resp = await api.get(`/api/system/workflow-runs/${run.id}/steps`);
      const steps = resp.data?.steps || [];
      const report = {
        runId: run.id,
        workflowId: run.workflowId,
        workflowLabel: run.workflowLabel,
        status: run.status,
        startedAt: _formatTs(run.sysCreatedAt),
        endedAt: _formatTs(run.sysModifiedAt),
        steps,
      };
      const blob = new Blob([JSON.stringify(report, null, 2)], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `run-tracing-${run.id.slice(0, 8)}.json`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (e) {
      console.error('[automations] download tracing failed', e);
      showError(t('Download fehlgeschlagen'));
    }
  }, [showError, t]);

  const _runColumns: ColumnConfig[] = useMemo(() => [
    {
      key: 'workflowLabel',
      label: t('Workflow'),
      type: 'string',
      width: 200,
      sortable: true,
      formatter: (v: string, row: WorkflowRun) => v || row.workflowId || t('—'),
    },
    {
      key: 'mandateId',
      label: t('Mandant'),
      type: 'string',
      width: 120,
      sortable: true,
      filterable: true,
      formatter: (v: string) => v ? v.slice(0, 8) + '…' : t('—'),
    },
    {
      key: 'status',
      label: t('Status'),
      type: 'string',
      width: 110,
      sortable: true,
      filterable: true,
      formatter: (v: string) => (
        <span style={{ color: _STATUS_COLORS[v] || 'inherit', fontWeight: 600 }}>
          {v === 'completed' ? t('Abgeschlossen') : v === 'failed' ? t('Fehlgeschlagen') : v === 'running' ? t('Laufend') : v}
        </span>
      ),
    },
    {
      key: 'sysCreatedAt',
      label: t('Gestartet'),
      type: 'number',
      width: 150,
      sortable: true,
      formatter: (v: number) => _formatTs(v),
    },
    {
      key: 'sysModifiedAt',
      label: t('Beendet'),
      type: 'number',
      width: 150,
      formatter: (v: number) => _formatTs(v),
    },
    {
      key: 'id',
      label: '',
      type: 'string',
      width: 50,
      sortable: false,
      formatter: (_v: string, row: WorkflowRun) => (
        <button
          onClick={(e) => { e.stopPropagation(); _downloadRunTracing(row); }}
          title={t('Tracing-Protokoll herunterladen')}
          style={{
            border: 'none', background: 'transparent', cursor: 'pointer',
            color: 'var(--text-secondary, #666)', fontSize: 14, padding: 4,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}
        >
          <FaDownload />
        </button>
      ),
    },
  ], [t, _downloadRunTracing]);

  const _hookData = useMemo(() => ({
    refetch: _loadRuns,
    pagination: paginationMeta,
  }), [_loadRuns, paginationMeta]);

  return (
    <>
      <div className={styles.pageHeader}>
        <div>
          <p className={styles.pageSubtitle}>{t('Workflow-Runs über alle Features und Mandanten')}</p>
        </div>
        <div className={styles.headerActions}>
          <button className={styles.secondaryButton} onClick={() => { _loadMetrics(); _loadRuns(); }} disabled={loading}>
            <FaSync className={loading ? 'spinning' : ''} /> {t('Aktualisieren')}
          </button>
        </div>
      </div>

      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginBottom: 24 }}>
        <MetricCard icon={<FaCog />} label={t('Workflows')} value={metrics?.workflowCount ?? t('—')} />
        <MetricCard icon={<FaPlay />} label={t('Aktive Workflows')} value={metrics?.activeWorkflows ?? t('—')} color="var(--success-color, #28a745)" />
        <MetricCard icon={<FaChartBar />} label={t('Runs gesamt')} value={metrics?.totalRuns ?? t('—')} />
      </div>

      {metrics?.runsByStatus && Object.keys(metrics.runsByStatus).length > 0 && (
        <div style={{ marginBottom: 24 }}>
          <h3 style={{ fontSize: '0.95rem', fontWeight: 600, marginBottom: 8 }}>{t('Läufe nach Status')}</h3>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {Object.entries(metrics.runsByStatus).map(([status, count]) => (
              <span
                key={status}
                style={{
                  padding: '4px 12px',
                  borderRadius: 12,
                  fontSize: '0.85rem',
                  fontWeight: 600,
                  background: 'var(--bg-secondary, #f5f5f5)',
                  color: _STATUS_COLORS[status] || 'inherit',
                }}
              >
                {status}: {count}
              </span>
            ))}
          </div>
        </div>
      )}

      {metrics && (metrics.totalTokens > 0 || metrics.totalCredits > 0) && (
        <div style={{ marginBottom: 24, display: 'flex', gap: 24 }}>
          {metrics.totalTokens > 0 && (
            <div>
              <span style={{ fontSize: '0.8rem', color: 'var(--text-secondary, #666)' }}>{t('Tokens gesamt:')} </span>
              <strong>{metrics.totalTokens.toLocaleString('de-DE')}</strong>
            </div>
          )}
          {metrics.totalCredits > 0 && (
            <div>
              <span style={{ fontSize: '0.8rem', color: 'var(--text-secondary, #666)' }}>{t('Credits gesamt:')} </span>
              <strong>{metrics.totalCredits.toLocaleString('de-DE', { minimumFractionDigits: 2 })}</strong>
            </div>
          )}
        </div>
      )}

      <h3 style={{ fontSize: '0.95rem', fontWeight: 600, marginBottom: 8 }}>{t('Letzte Runs')}</h3>
      <div className={styles.tableContainer}>
        <FormGeneratorTable<WorkflowRun>
          data={runs}
          columns={_runColumns}
          loading={loading}
          pagination={true}
          pageSize={25}
          searchable={true}
          filterable={true}
          sortable={true}
          selectable={false}
          hookData={_hookData}
          emptyMessage={t('Noch keine Workflow-Runs vorhanden.')}
        />
      </div>
    </>
  );
};

// ===========================================================================
// WorkflowsTab — Central workflow management across all instances
// ===========================================================================

const _WorkflowsTab: React.FC = () => {
  const { t } = useLanguage();
  const navigate = useNavigate();
  const { request } = useApiRequest();
  const { showSuccess, showError } = useToast();
  const { prompt: promptInput, PromptDialog } = usePrompt();

  const [workflows, setWorkflows] = useState<SystemWorkflow[]>([]);
  const [loading, setLoading] = useState(true);
  const [executingId, setExecutingId] = useState<string | null>(null);
  const [togglingId, setTogglingId] = useState<string | null>(null);
  const [activeFilter, setActiveFilter] = useState<'all' | 'active' | 'inactive'>('all');
  const [paginationMeta, setPaginationMeta] = useState<any>(null);

  const _load = useCallback(async (paginationParams?: any) => {
    setLoading(true);
    try {
      const params: Record<string, any> = {};
      if (activeFilter === 'active') params.active = true;
      if (activeFilter === 'inactive') params.active = false;

      const pag = {
        page: paginationParams?.page || 1,
        pageSize: paginationParams?.pageSize || 25,
        ...(paginationParams?.sort ? { sort: paginationParams.sort } : {}),
        ...(paginationParams?.search ? { search: paginationParams.search } : {}),
        ...(paginationParams?.filters ? { filters: paginationParams.filters } : {}),
      };
      params.pagination = JSON.stringify(pag);

      const resp = await api.get('/api/system/workflow-runs/workflows', { params });
      const data = resp.data;
      setWorkflows(data?.items || []);
      setPaginationMeta(data?.pagination || null);
    } catch (e) {
      console.error('[automations] load system workflows failed', e);
      showError(t('Fehler beim Laden der Workflows'));
    } finally {
      setLoading(false);
    }
  }, [activeFilter, showError, t]);

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

  const _handleEdit = useCallback((row: SystemWorkflow) => {
    if (!row.mandateId || !row.featureInstanceId) return;
    navigate(`/mandates/${row.mandateId}/graphicalEditor/${row.featureInstanceId}/editor?workflowId=${row.id}`);
  }, [navigate]);

  const _handleDelete = useCallback(async (workflowId: string): Promise<boolean> => {
    const wf = workflows.find(w => w.id === workflowId);
    if (!wf?.featureInstanceId) return false;
    try {
      await deleteWorkflow(request, wf.featureInstanceId, workflowId);
      showSuccess(t('Workflow gelöscht'));
      await _load();
      return true;
    } catch (e: any) {
      showError(t('Fehler: {msg}', { msg: e?.message || t('Löschen fehlgeschlagen') }));
      return false;
    }
  }, [workflows, request, showSuccess, showError, _load, t]);

  const _handleToggleActive = useCallback(async (row: SystemWorkflow) => {
    if (!row.featureInstanceId) return;
    const next = !(row.active !== false);
    setTogglingId(row.id);
    try {
      await updateWorkflow(request, row.featureInstanceId, row.id, { active: next });
      showSuccess(next ? t('Workflow aktiviert') : t('Workflow deaktiviert'));
      await _load();
    } catch (e: any) {
      showError(t('Fehler: {msg}', { msg: e?.message || t('Status-Update fehlgeschlagen') }));
    } finally {
      setTogglingId(null);
    }
  }, [request, showSuccess, showError, _load, t]);

  const _handleRename = useCallback(async (row: SystemWorkflow) => {
    if (!row.featureInstanceId) return;
    const newLabel = await promptInput(t('Neuer Name:'), {
      title: t('Workflow umbenennen'),
      defaultValue: row.label,
      placeholder: t('Workflow-Name'),
    });
    if (!newLabel || newLabel.trim() === row.label) return;
    try {
      await updateWorkflow(request, row.featureInstanceId, row.id, { label: newLabel.trim() });
      showSuccess(t('Workflow umbenannt'));
      await _load();
    } catch (e: any) {
      showError(t('Fehler: {msg}', { msg: e?.message || t('Umbenennen fehlgeschlagen') }));
    }
  }, [request, promptInput, showSuccess, showError, _load, t]);

  const _handleExecute = useCallback(async (row: SystemWorkflow) => {
    if (!row.featureInstanceId || !row.graph) return;
    setExecutingId(row.id);
    try {
      const invs = row.invocations || [];
      const primary =
        invs.find((i) => i.enabled && i.kind === 'manual') ||
        invs.find((i) => i.enabled && (i.kind === 'form' || i.kind === 'api'));
      const result = await executeGraph(request, row.featureInstanceId, row.graph, row.id, {
        ...(primary ? { entryPointId: primary.id } : {}),
      });
      if (result?.success) {
        showSuccess(result?.paused
          ? t('Workflow gestartet und bei Human Task pausiert. Öffne Workflows & Tasks.')
          : t('Workflow ausgeführt'));
        await _load();
      } else {
        showError(result?.error || t('Ausführung fehlgeschlagen'));
      }
    } catch (e: any) {
      showError(t('Fehler: {msg}', { msg: e?.message || t('Ausführung fehlgeschlagen') }));
    } finally {
      setExecutingId(null);
    }
  }, [request, showSuccess, showError, _load, t]);

  const _hasManualTrigger = useCallback((row: SystemWorkflow): boolean => {
    const invs = row.invocations || [];
    return invs.some((i) => i.enabled && (i.kind === 'manual' || i.kind === 'api'));
  }, []);

  const _columns: ColumnConfig[] = useMemo(() => [
    { key: 'label', label: t('Workflow'), type: 'string', width: 200, sortable: true },
    { key: 'mandateLabel', label: t('Mandant'), type: 'string', width: 140, sortable: true, filterable: true },
    { key: 'instanceLabel', label: t('Instanz'), type: 'string', width: 140, sortable: true, filterable: true },
    {
      key: 'active',
      label: t('Aktiv (Spalte)'),
      type: 'boolean',
      width: 80,
      formatter: (value: boolean) =>
        value !== false
          ? <span style={{ color: 'var(--success-color, #28a745)', fontWeight: 600 }}>{t('Ja')}</span>
          : <span style={{ color: 'var(--text-secondary, #666)' }}>{t('Nein')}</span>,
    },
    {
      key: 'isRunning',
      label: t('läuft'),
      type: 'boolean',
      width: 80,
      formatter: (value: boolean) =>
        value
          ? <span style={{ color: 'var(--success-color, #28a745)', fontWeight: 600 }}>{t('Ja')}</span>
          : <span style={{ color: 'var(--text-secondary, #666)' }}>{t('Nein')}</span>,
    },
    {
      key: 'sysCreatedAt',
      label: t('Erstellt'),
      type: 'number',
      width: 140,
      sortable: true,
      formatter: (v: number) => _formatTs(v),
    },
    {
      key: 'lastStartedAt',
      label: t('zuletzt gestartet'),
      type: 'number',
      width: 160,
      formatter: (v: number) => _formatTs(v),
    },
    {
      key: 'runCount',
      label: t('Läufe'),
      type: 'number',
      width: 80,
      formatter: (v: number) => (v != null ? String(v) : '0'),
    },
  ], [t]);

  const _hookData = useMemo(() => ({
    refetch: _load,
    handleDelete: (id: string) => _handleDelete(id),
    pagination: paginationMeta,
  }), [_load, _handleDelete, paginationMeta]);

  return (
    <>
      <div className={styles.pageHeader}>
        <div>
          <p className={styles.pageSubtitle}>
            {t('Alle Workflows über alle Features und Mandanten')}
          </p>
        </div>
        <div className={styles.headerActions} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ display: 'flex', gap: 4 }}>
            {(['all', 'active', 'inactive'] as const).map((f) => (
              <button
                key={f}
                className={activeFilter === f ? styles.primaryButton : styles.secondaryButton}
                onClick={() => setActiveFilter(f)}
                disabled={loading}
              >
                {f === 'all' ? t('Alle') : f === 'active' ? t('Aktiv') : t('Inaktiv')}
              </button>
            ))}
          </div>
          <button className={styles.secondaryButton} onClick={() => _load()} disabled={loading}>
            <FaSync className={loading ? 'spinning' : ''} /> {t('Aktualisieren')}
          </button>
        </div>
      </div>

      <div className={styles.tableContainer}>
        <FormGeneratorTable<SystemWorkflow>
          data={workflows}
          columns={_columns}
          loading={loading}
          pagination={true}
          pageSize={25}
          searchable={true}
          filterable={true}
          sortable={true}
          selectable={false}
          actionButtons={[
            {
              type: 'edit',
              title: t('bearbeiten'),
              onAction: _handleEdit,
              visible: (row: SystemWorkflow) => row.canEdit === true,
            },
            {
              type: 'delete',
              title: t('löschen'),
              visible: (row: SystemWorkflow) => row.canDelete === true,
            },
          ]}
          customActions={[
            {
              id: 'view',
              icon: <FaEye />,
              title: t('anzeigen'),
              onClick: (row) => _handleEdit(row),
              visible: (row) => row.canEdit !== true,
            },
            {
              id: 'rename',
              icon: <FaPen />,
              title: t('umbenennen'),
              onClick: (row) => _handleRename(row),
              visible: (row) => row.canEdit === true,
            },
            {
              id: 'activate',
              icon: <FaCheck />,
              title: t('aktivieren'),
              onClick: (row) => _handleToggleActive(row),
              loading: (row) => togglingId === row.id,
              visible: (row) => row.canEdit === true && row.active === false,
            },
            {
              id: 'deactivate',
              icon: <FaBan />,
              title: t('deaktivieren'),
              onClick: (row) => _handleToggleActive(row),
              loading: (row) => togglingId === row.id,
              visible: (row) => row.canEdit === true && row.active !== false,
            },
            {
              id: 'execute',
              icon: <FaPlay />,
              title: t('ausführen'),
              onClick: (row) => _handleExecute(row),
              loading: (row) => executingId === row.id,
              visible: (row) => row.canExecute === true && _hasManualTrigger(row),
            },
          ]}
          onDelete={(row) => _handleDelete(row.id)}
          hookData={_hookData}
          emptyMessage={t('Keine Workflows gefunden.')}
        />
      </div>
      <PromptDialog />
    </>
  );
};

// ===========================================================================
// Main page with Tabs
// ===========================================================================

export const AutomationsDashboardPage: React.FC = () => {
  const { t } = useLanguage();

  const tabs = useMemo(() => [
    {
      id: 'dashboard',
      label: t('Dashboard'),
      content: <_DashboardTab />,
    },
    {
      id: 'workflows',
      label: t('Workflows'),
      content: <_WorkflowsTab />,
    },
  ], [t]);

  return (
    <div className={`${styles.adminPage} ${styles.adminPageFill}`}>
      <h1 className={styles.pageTitle}>{t('Automatisierung')}</h1>
      <Tabs tabs={tabs} defaultTabId="dashboard" />
    </div>
  );
};

export default AutomationsDashboardPage;
