/**
 * WorkspaceRagInsightsPage — Aggregierte, nicht personenbezogene Kennzahlen zum
 * Knowledge Store / RAG dieser Workspace-Instanz (Präsentationen, Monitoring).
 */

import React, { useCallback, useEffect, useState } from 'react';
import {
  ResponsiveContainer,
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  BarChart,
  Bar,
  PieChart,
  Pie,
  Cell,
} from 'recharts';
import { useInstanceId } from '../../../hooks/useCurrentInstance';
import { useApiRequest } from '../../../hooks/useApi';
import styles from './WorkspaceRagInsightsPage.module.css';
import { formatBinaryDataSizeBytes } from '../../../utils/formatDataSize';

import { useLanguage } from '../../../providers/language/LanguageContext';

function _mimeLabel(key: string, t: (k: string) => string): string {
  switch (key) {
    case 'pdf': return t('PDF');
    case 'office_doc': return t('Office (Text)');
    case 'office_sheet': return t('Office (Tabellen)');
    case 'office_slides': return t('Office (Folien)');
    case 'text': return t('Text');
    case 'image': return t('Bild');
    case 'html': return t('HTML');
    case 'other': return t('Sonstige');
    default: return key;
  }
}

const CHART_COLORS = ['#1976d2', '#00897b', '#6a1b9a', '#e65100', '#5d4037', '#455a64', '#c62828'];

function _formatTimestamp(ts: number | null | undefined): string {
  if (ts == null || ts <= 0) return '–';
  try {
    const d = new Date(ts * 1000);
    return d.toLocaleString('de-CH', {
      day: '2-digit', month: '2-digit', year: 'numeric',
      hour: '2-digit', minute: '2-digit',
    });
  } catch {
    return '–';
  }
}

function _shortMime(mime: string): string {
  const m = (mime || '').toLowerCase();
  if (m.includes('pdf')) return 'PDF';
  if (m.includes('wordprocessing') || m.includes('msword')) return 'Word';
  if (m.includes('spreadsheet') || m.includes('excel')) return 'Excel';
  if (m.includes('presentation') || m.includes('powerpoint')) return 'PowerPoint';
  if (m.startsWith('text/')) return 'Text';
  if (m.startsWith('image/')) return 'Bild';
  if (m.includes('html')) return 'HTML';
  return mime || '–';
}

const _STATUS_COLORS: Record<string, string> = {
  indexed: '#2e7d32',
  extracted: '#1565c0',
  embedding: '#6a1b9a',
  pending: '#e65100',
  failed: '#c62828',
};

interface RagKpis {
  indexedDocuments: number;
  indexedBytesTotal: number;
  contributorUsers: number;
  contentChunks: number;
  chunksWithEmbedding: number;
  embeddingCoveragePercent: number;
  workflowEntities: number;
}

interface RecentlyIndexedDoc {
  fileName: string;
  mimeType: string;
  status: string;
  extractedAt: number | null;
  totalSize: number;
}

interface RagStatsResponse {
  error?: string;
  scope?: {
    featureInstanceId?: string;
    mandateScopedShared?: boolean;
    workspaceFileIdsResolved?: number;
  };
  kpis?: RagKpis;
  indexedDocumentsByStatus?: Record<string, number>;
  documentsByMimeCategory?: Record<string, number>;
  chunksByContentType?: Record<string, number>;
  timelineIndexedDocuments?: Array<{ date: string; indexedDocuments: number }>;
  recentlyIndexedDocuments?: RecentlyIndexedDoc[];
  generatedAtUtc?: string;
}

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

  const instanceId = useInstanceId();
  const { request } = useApiRequest();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [stats, setStats] = useState<RagStatsResponse | null>(null);

  const load = useCallback(async () => {
    if (!instanceId) return;
    setLoading(true);
    setError(null);
    try {
      const data = (await request({
        url: `/api/workspace/${instanceId}/rag-statistics`,
        method: 'get',
      })) as RagStatsResponse;
      if (data?.error) {
        setError(String(data.error));
        setStats(null);
      } else {
        setStats(data ?? null);
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : t('Laden fehlgeschlagen'));
      setStats(null);
    } finally {
      setLoading(false);
    }
  }, [instanceId, request, t]);

  useEffect(() => {
    void load();
  }, [load]);

  if (!instanceId) {
    return (
      <div style={{ padding: 32, textAlign: 'center', color: '#999' }}>
        {t('Keine Workspace-Instanz ausgewählt.')}
      </div>
    );
  }

  if (loading) {
    return <div className={styles.wrap} style={{ padding: 24 }}>{t('Lade Kennzahlen')}</div>;
  }

  if (error) {
    return <div className={styles.error}>{error}</div>;
  }

  const kpis = stats?.kpis;
  const timeline = stats?.timelineIndexedDocuments ?? [];
  const mimeRows = Object.entries(stats?.documentsByMimeCategory ?? {}).map(([key, value]) => ({
    name: _mimeLabel(key, t),
    value,
  }));
  const statusRows = Object.entries(stats?.indexedDocumentsByStatus ?? {}).map(([name, value]) => ({
    name,
    value,
  }));
  const chunkTypeRows = Object.entries(stats?.chunksByContentType ?? {}).map(([name, value]) => ({
    name,
    value,
  }));

  return (
    <div className={styles.wrap}>
      <p className={styles.disclaimer}>
        {t(
          'Dargestellt sind ausschliesslich aggregierte technische Masszahlen dieser Instanz (Anzahl Dokumente, Fragmente, Speicherumfang, Verteilungen). Es werden keine Inhalte, Dateinamen oder personenbezogene Angaben ausgewiesen. Geeignet für interne Berichte und Präsentationen.',
        )}
      </p>

      {stats?.scope?.workspaceFileIdsResolved !== undefined && (
        <p className={styles.meta} style={{ marginTop: 0 }}>
          {t(
            'Zuordnung Knowledge ↔ Dateien: {workspaceFileIdsResolved} Datei-ID(s) mit dieser Feature-Instanz in der Dateiverwaltung. Neu indexierte Uploads erhalten die Instanz automatisch; ältere Einträge ohne Zuordnung erscheinen erst nach erneuter Indexierung.',
            { workspaceFileIdsResolved: stats.scope.workspaceFileIdsResolved },
          )}
        </p>
      )}

      {kpis && (
        <div className={styles.kpiGrid}>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>{kpis.indexedDocuments}</p>
            <p className={styles.kpiLabel}>{t('Indexierte Dokumente')}</p>
          </div>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>{formatBinaryDataSizeBytes(kpis.indexedBytesTotal)}</p>
            <p className={styles.kpiLabel}>{t('Indexiertes Datenvolumen (geschätzt)')}</p>
          </div>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>{kpis.contentChunks}</p>
            <p className={styles.kpiLabel}>{t('Inhaltsfragmente (Chunks)')}</p>
          </div>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>
              {kpis.embeddingCoveragePercent}%
            </p>
            <p className={styles.kpiLabel}>{t('Anteil Fragmente mit Embedding')}</p>
          </div>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>{kpis.contributorUsers}</p>
            <p className={styles.kpiLabel}>{t('Beitragende Benutzeranzahl')}</p>
          </div>
          <div className={styles.kpiCard}>
            <p className={styles.kpiValue}>{kpis.workflowEntities}</p>
            <p className={styles.kpiLabel}>{t('Workflowentitäten-Cache')}</p>
          </div>
        </div>
      )}

      {(stats?.recentlyIndexedDocuments ?? []).length > 0 && (
        <div className={styles.chartBlock}>
          <h3 className={styles.chartTitle}>{t('Zuletzt indexierte Dokumente')}</h3>
          <div style={{ overflowX: 'auto' }}>
            <table className={styles.recentTable}>
              <thead>
                <tr>
                  <th>{t('Dateiname')}</th>
                  <th>{t('Format')}</th>
                  <th>{t('Grösse')}</th>
                  <th>{t('Status')}</th>
                  <th>{t('Indexiert am')}</th>
                </tr>
              </thead>
              <tbody>
                {(stats?.recentlyIndexedDocuments ?? []).map((doc, i) => (
                  <tr key={i}>
                    <td title={doc.fileName} style={{ maxWidth: 280, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {doc.fileName || '–'}
                    </td>
                    <td>{_shortMime(doc.mimeType)}</td>
                    <td style={{ whiteSpace: 'nowrap' }}>{formatBinaryDataSizeBytes(doc.totalSize)}</td>
                    <td>
                      <span style={{
                        color: _STATUS_COLORS[doc.status] ?? '#666',
                        fontWeight: 500,
                      }}>
                        {doc.status}
                      </span>
                    </td>
                    <td style={{ whiteSpace: 'nowrap' }}>{_formatTimestamp(doc.extractedAt)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <div className={styles.chartBlock}>
        <h3 className={styles.chartTitle}>{t('Neu indexierte Dokumente pro Tag')}</h3>
        {timeline.length === 0 ? (
          <p className={styles.meta}>{t('Keine Zeitreihendaten für den gewählten')}</p>
        ) : (
          <ResponsiveContainer width="100%" height={240}>
            <LineChart data={timeline}>
              <CartesianGrid strokeDasharray="3 3" />
              <XAxis dataKey="date" tick={{ fontSize: 11 }} />
              <YAxis allowDecimals={false} tick={{ fontSize: 11 }} />
              <Tooltip />
              <Line type="monotone" dataKey="indexedDocuments" name={t('Dokumente')} stroke="#1976d2" dot={false} strokeWidth={2} />
            </LineChart>
          </ResponsiveContainer>
        )}
      </div>

      <div className={styles.row2}>
        <div className={styles.chartBlock}>
          <h3 className={styles.chartTitle}>{t('Dokumente nach Formatkategorie')}</h3>
          {mimeRows.length === 0 ? (
            <p className={styles.meta}>{t('Keine Daten')}</p>
          ) : (
            <ResponsiveContainer width="100%" height={260}>
              <BarChart data={mimeRows} layout="vertical" margin={{ left: 8, right: 16 }}>
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis type="number" allowDecimals={false} />
                <YAxis type="category" dataKey="name" width={120} tick={{ fontSize: 11 }} />
                <Tooltip />
                <Bar dataKey="value" name={t('Anzahl')} fill="#00897b" radius={[0, 4, 4, 0]} />
              </BarChart>
            </ResponsiveContainer>
          )}
        </div>

        <div className={styles.chartBlock}>
          <h3 className={styles.chartTitle}>{t('Index-Status')}</h3>
          {statusRows.length === 0 ? (
            <p className={styles.meta}>{t('Keine Daten')}</p>
          ) : (
            <ResponsiveContainer width="100%" height={260}>
              <PieChart>
                <Pie
                  data={statusRows}
                  dataKey="value"
                  nameKey="name"
                  cx="50%"
                  cy="50%"
                  outerRadius={88}
                  label={({ name, percent }) =>
                    `${name ?? ''} ${percent != null ? (percent * 100).toFixed(0) : '0'}%`}
                >
                  {statusRows.map((_, i) => (
                    <Cell key={`st-${i}`} fill={CHART_COLORS[i % CHART_COLORS.length]} />
                  ))}
                </Pie>
                <Tooltip />
              </PieChart>
            </ResponsiveContainer>
          )}
        </div>
      </div>

      <div className={styles.chartBlock}>
        <h3 className={styles.chartTitle}>{t('Fragmente nach Inhaltstyp')}</h3>
        {chunkTypeRows.length === 0 ? (
          <p className={styles.meta}>{t('Keine Chunkdaten')}</p>
        ) : (
          <ResponsiveContainer width="100%" height={240}>
            <BarChart data={chunkTypeRows}>
              <CartesianGrid strokeDasharray="3 3" />
              <XAxis dataKey="name" tick={{ fontSize: 11 }} />
              <YAxis allowDecimals={false} tick={{ fontSize: 11 }} />
              <Tooltip />
              <Bar dataKey="value" name={t('Fragmente')} fill="#6a1b9a" radius={[4, 4, 0, 0]} />
            </BarChart>
          </ResponsiveContainer>
        )}
      </div>

      {stats?.generatedAtUtc && (
        <p className={styles.meta}>
          {t('Stand (UTC):')} {stats.generatedAtUtc}
        </p>
      )}
    </div>
  );
};
