/**
 * SET 33b.3 — "Your install" aggregate stats, extracted from AdminView into
 * its own sidebar-opened panel. Local-only (never shown to anyone else);
 * installHash stays plumbing-only — it is used inside export file CONTENTS
 * (statsAggregate JSON/CSV) but never rendered or put in a filename here.
 */
import React, { useEffect, useMemo, useState } from 'react';
import {
  buildMetricsGrid,
  formatUsd,
  metricsGridToCsv,
  metricsGridToJson,
  type InstallStatsSummary,
} from '../../src/tier1/statsAggregate';
import { exportInstallMetricsFiles } from './exportMetrics';
import { MetricsGridTable } from './MetricsGridTable';

export type LocalStatsPayload = InstallStatsSummary & {
  installHash: string;
  /** SET 64 — metasupercache footprint (metaSb:* epochs). */
  metaSbEpochs?: number;
  metaSbBytes?: number;
  comparativeLifetime?: {
    label: string;
    id: string;
    usdTotal: number;
    usdIn: number;
    usdOut: number;
  }[];
  // Legacy fields still returned by stats:local
  tokens?: unknown;
  cost?: unknown;
};

type ExtSend = <T>(msg: Record<string, unknown>) => Promise<T>;

function fmtGenerated(iso: string | null | undefined): string {
  if (!iso) return '—';
  try {
    return new Date(iso).toLocaleString();
  } catch {
    return iso;
  }
}

function InstallGrid({
  stats,
  loading,
  error,
  onResetLocal,
  resetBusy,
  resetMsg,
}: {
  stats: LocalStatsPayload | null;
  loading: boolean;
  error: string | null;
  onResetLocal: () => void;
  resetBusy: boolean;
  resetMsg: string | null;
}) {
  const grid = useMemo(() => (stats?.facets ? buildMetricsGrid(stats) : []), [stats]);

  const onExport = () => {
    if (!stats) return;
    const json = metricsGridToJson({ ...stats, installHash: stats.installHash }, grid);
    const csv = metricsGridToCsv({ ...stats, installHash: stats.installHash }, grid);
    exportInstallMetricsFiles({ installHash: stats.installHash, csv, json });
  };

  return (
    <div className="card admin-section">
      <div className="cardhead">
        <b>Your install</b>
        <span className="dim small">(local only; resets on reinstall)</span>
      </div>
      {loading && <p className="dim">Loading local stats…</p>}
      {error && <p className="bad">{error}</p>}
      {!loading && !error && !stats && (
        <p className="dim">Extension required for private install stats.</p>
      )}
      {stats && (
        <>
          <p className="dim small" style={{ marginBottom: 8 }}>
            {stats.totalsRuns} lifetime run{stats.totalsRuns === 1 ? '' : 's'}
            {stats.ringSize != null ? ` · ${stats.ringSize} in ring` : ''}
            {stats.metaSbBytes != null && stats.metaSbBytes > 0
              ? ` · metaSb ${(stats.metaSbBytes / 1024).toFixed(0)}KB/${stats.metaSbEpochs ?? 0} epochs`
              : ''}
            {stats.latestTs ? ` · latest ${fmtGenerated(stats.latestTs)}` : ''}
          </p>
          <MetricsGridTable rows={grid} columns={['latest', 'avg', 'min', 'max', 'lifetime']} />
          {stats.comparativeLifetime && stats.comparativeLifetime.length > 0 && (
            <div style={{ marginTop: 14 }}>
              <div className="cardhead"><b>Lifetime tokens — provider comparative</b></div>
              <table className="authtable admin-grid">
                <thead>
                  <tr>
                    <th>Family</th>
                    <th>Model</th>
                    <th>Total</th>
                    <th>In / Out</th>
                  </tr>
                </thead>
                <tbody>
                  {stats.comparativeLifetime.map(row => (
                    <tr key={row.id}>
                      <td>{row.label}</td>
                      <td><code style={{ fontSize: 11 }}>{row.id}</code></td>
                      <td className="ok">{formatUsd(row.usdTotal)}</td>
                      <td className="dim">{formatUsd(row.usdIn)} / {formatUsd(row.usdOut)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
          <button type="button" className="btn" style={{ marginTop: 12 }} onClick={onExport}>
            Export metrics
          </button>
          <button
            type="button"
            className="btn ghost"
            style={{ marginTop: 12, marginLeft: 8 }}
            disabled={resetBusy}
            onClick={onResetLocal}
          >
            Reset your install stats
          </button>
          <p className="dim small" style={{ marginTop: 6 }}>
            Zeroes these aggregate counters only — your run history stays untouched and openable.
          </p>
          {resetMsg && <p className="dim small">{resetMsg}</p>}
        </>
      )}
    </div>
  );
}

export function InstallStatsPanel({
  extSendMessage,
  extPresent,
  onClose,
}: {
  extSendMessage: ExtSend;
  extPresent: boolean;
  onClose: () => void;
}) {
  const [local, setLocal] = useState<LocalStatsPayload | null>(null);
  const [localLoading, setLocalLoading] = useState(false);
  const [localError, setLocalError] = useState<string | null>(null);
  const [resetBusy, setResetBusy] = useState(false);
  const [resetMsg, setResetMsg] = useState<string | null>(null);

  useEffect(() => {
    if (!extPresent) {
      setLocal(null);
      setLocalError(null);
      return;
    }
    let stop = false;
    const tick = () => {
      setLocalLoading(true);
      void extSendMessage<LocalStatsPayload>({ action: 'stats:local' })
        .then(r => {
          if (stop) return;
          if (r?.installHash) {
            setLocal(r);
            setLocalError(null);
          } else {
            setLocalError('No install stats returned');
          }
        })
        .catch(e => {
          if (!stop) setLocalError(e instanceof Error ? e.message : String(e));
        })
        .finally(() => { if (!stop) setLocalLoading(false); });
    };
    tick();
    const t = setInterval(tick, 4000);
    return () => { stop = true; clearInterval(t); };
  }, [extPresent, extSendMessage]);

  // SET 30b — reset YOUR-INSTALL aggregate stats: unprotected, confirmation-gated,
  // clears tier1StatsTotals + stamps statsBaseline (background.js `stats:resetLocal`).
  // Run history is untouched; only the aggregate counters above zero out.
  const onResetLocal = () => {
    if (resetBusy) return;
    if (!window.confirm('Reset your install\u2019s aggregate stats to zero?\n\nYour run history will NOT be deleted — only these lifetime/avg/max counters reset.')) {
      return;
    }
    setResetBusy(true);
    setResetMsg(null);
    void extSendMessage<{ ok: boolean; ts: string }>({ action: 'stats:resetLocal' })
      .then(async r => {
        if (!r?.ok) throw new Error('reset failed');
        setResetMsg(`Reset at ${fmtGenerated(r.ts)}`);
        const fresh = await extSendMessage<LocalStatsPayload>({ action: 'stats:local' });
        setLocal(fresh);
      })
      .catch(e => setResetMsg(e instanceof Error ? e.message : String(e)))
      .finally(() => setResetBusy(false));
  };

  return (
    <div className="admin-view" data-rha-boot="install">
      <div className="cardhead" style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <b style={{ fontSize: 16 }}>Your install</b>
        <button type="button" className="btn ghost" onClick={onClose}>Close</button>
      </div>
      <p className="dim small" style={{ margin: '0 0 12px' }}>
        Local-only aggregate — lives in this browser profile, never sent anywhere. Resets on reinstall.
      </p>
      <InstallGrid
        stats={local}
        loading={localLoading && !local}
        error={localError}
        onResetLocal={onResetLocal}
        resetBusy={resetBusy}
        resetMsg={resetMsg}
      />
    </div>
  );
}
