import type { ArtifactDocument } from '../../lib/agent-tools';
import type { TelemetrySnapshot, ToolEvent } from '../../lib/contracts';
import { formatBytes, formatPercent } from '../../lib/format';

interface InspectorPanelProps {
  hidden?: boolean;
  telemetry: TelemetrySnapshot;
  toolEvents: ToolEvent[];
  artifacts: ArtifactDocument[];
  onSelectArtifact: (artifactId: string) => void;
}

export function InspectorPanel({ hidden = false, telemetry, toolEvents, artifacts, onSelectArtifact }: InspectorPanelProps) {
  const contextRatio = telemetry.contextLimit > 0 ? telemetry.contextUsed / telemetry.contextLimit : 0;
  const prefillRatio = telemetry.promptTotal > 0 ? telemetry.promptProcessed / telemetry.promptTotal : 0;
  const activeRate = telemetry.inferencePhase === 'prefill'
    ? telemetry.prefillTokensPerSecond
    : telemetry.decodeTokensPerSecond || telemetry.tokensPerSecond;
  const speedRatio = Math.min(1, Math.max(0, activeRate / 50));
  const gaugeLabel = telemetry.inferencePhase === 'prefill'
    ? 'Prefill'
    : telemetry.inferencePhase === 'decode'
      ? 'Decode'
      : 'Average';
  const samplingLabel = telemetry.inferencePhase === 'idle'
    ? 'Ready'
    : telemetry.inferencePhase === 'complete' ? 'Average' : 'Live';

  return (
    <aside className="inspector" aria-label="Runtime inspector" hidden={hidden}>
      <section className="inspector-section telemetry-section" aria-labelledby="telemetry-title">
        <div className="section-heading">
          <h2 id="telemetry-title">Telemetry</h2>
          <span className={`sampling-label phase-${telemetry.inferencePhase}`}>{samplingLabel}</span>
        </div>

        <div className="speed-gauge">
          <div className="gauge-ring" style={{ '--gauge': `${Math.round(speedRatio * 100)}%` } as React.CSSProperties}>
            <div>
              <strong>{activeRate.toFixed(1)}</strong>
              <small><span>{gaugeLabel}</span><span>tok/s</span></small>
            </div>
          </div>
          <dl>
            <div><dt>Backend</dt><dd>{telemetry.backend}</dd></div>
            <div><dt>First token</dt><dd>{telemetry.timeToFirstTokenMs} ms</dd></div>
            <div><dt>Graph splits</dt><dd>{telemetry.graphSplits ?? '—'}</dd></div>
          </dl>
        </div>

        <div className="telemetry-live-grid" aria-label="Live inference rates">
          <TelemetryMetric
            label="Prefill"
            value={`${telemetry.prefillTokensPerSecond.toFixed(1)} tok/s`}
            detail={telemetry.promptTotal > 0
              ? `${telemetry.promptProcessed.toLocaleString()} / ${telemetry.promptTotal.toLocaleString()} tokens`
              : 'No prompt yet'}
            ratio={prefillRatio}
            active={telemetry.inferencePhase === 'prefill'}
            progressLabel={telemetry.promptTotal > 0 ? formatPercent(prefillRatio) : 'Waiting'}
          />
          <TelemetryMetric
            label="Decode"
            value={`${telemetry.decodeTokensPerSecond.toFixed(1)} tok/s`}
            detail={`${telemetry.completionTokens.toLocaleString()} generated tokens`}
            ratio={telemetry.decodeTokensPerSecond / 50}
            active={telemetry.inferencePhase === 'decode'}
            progressLabel="Rate / 50 tok/s"
          />
        </div>

        <div className="device-card">
          <span className="device-icon" aria-hidden="true"><i /><i /><i /></span>
          <div>
            <small>Active adapter</small>
            <strong>{telemetry.device}</strong>
          </div>
          <span>{telemetry.gpuLayers}<small>layers</small></span>
        </div>

        <Meter label="Context" value={contextRatio} detail={`${telemetry.contextUsed.toLocaleString()} / ${telemetry.contextLimit.toLocaleString()}`} />
        <div className="memory-grid">
          <div><small>Model allocation</small><strong>{formatBytes(telemetry.modelMemoryBytes)}</strong></div>
          <div><small>KV allocation</small><strong>{formatBytes(telemetry.kvMemoryBytes)}</strong></div>
        </div>
      </section>

      <section className="inspector-section tool-log-section" aria-labelledby="tool-log-title">
        <div className="section-heading compact">
          <h2 id="tool-log-title">Tool log</h2>
        </div>
        <ol className="event-log">
          {toolEvents.length === 0 && <li className="event-empty">No tool calls in this session.</li>}
          {toolEvents.map((event) => (
            <li key={event.id}>
              <span className={`event-pip event-${event.state}`} />
              <time>{event.timestamp}</time>
              <div><strong>{event.label}</strong><small>{event.detail}</small></div>
            </li>
          ))}
        </ol>
      </section>

      <section className="inspector-section artifact-index-section" aria-labelledby="artifact-index-title">
        <div className="section-heading compact">
          <h2 id="artifact-index-title">Artifacts</h2>
          <span className="artifact-count" aria-label={`${artifacts.length} artifacts`}>{artifacts.length}</span>
        </div>
        {artifacts.length === 0 ? (
          <p className="artifact-empty">Generated HTML artifacts will be indexed here and rendered in the conversation.</p>
        ) : (
          <ol className="artifact-index">
            {artifacts.map((artifact, index) => (
              <li key={artifact.id}>
                <button type="button" onClick={() => onSelectArtifact(artifact.id)}>
                  <span>{String(index + 1).padStart(2, '0')}</span>
                  <strong>{artifact.title}</strong>
                  <svg viewBox="0 0 20 20" aria-hidden="true"><path d="m7 4 6 6-6 6" /></svg>
                </button>
              </li>
            ))}
          </ol>
        )}
      </section>
    </aside>
  );
}

function TelemetryMetric({
  label,
  value,
  detail,
  ratio,
  active,
  progressLabel,
}: {
  label: string;
  value: string;
  detail: string;
  ratio: number;
  active: boolean;
  progressLabel: string;
}) {
  const percentage = Math.round(Math.min(1, Math.max(0, ratio)) * 100);
  return (
    <div className={`telemetry-metric${active ? ' is-active' : ''}`}>
      <div><span>{label}</span><strong>{value}</strong></div>
      <small>{detail}</small>
      <div className="telemetry-meter" role="meter" aria-label={`${label}: ${progressLabel}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percentage}>
        <span style={{ width: `${percentage}%` }} />
      </div>
    </div>
  );
}

function Meter({ label, value, detail }: { label: string; value: number; detail: string }) {
  const percentage = Math.round(Math.min(1, Math.max(0, value)) * 100);
  return (
    <div className="meter">
      <div><span>{label}</span><small>{detail}</small></div>
      <div className="meter-track" role="meter" aria-label={label} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percentage}>
        <span style={{ width: `${percentage}%` }} />
      </div>
    </div>
  );
}
