import assert from 'node:assert/strict';
import test from 'node:test';
import { deadmanProbeRunIds, localUiSnapshot, type BackendContinuityView } from '../src/ui-model.js';
import type { ManagedBinding, RuntimeStatus } from '../src/storage.js';

const workerId = 'wrk_00000000-0000-0000-0000-000000000001';
const runId = 'run_00000000-0000-0000-0000-000000000001';
const binding: ManagedBinding = {
  workerId, tabId: 7, conversationId: 'c-1', url: 'https://chatgpt.com/c/c-1', state: 'idle', updatedAt: '2026-08-21T03:00:00.000Z',
};
const connected: RuntimeStatus = { state: 'connected', detail: 'ok', updatedAt: '2026-08-21T03:00:00.000Z' };

function backend(overrides: Partial<BackendContinuityView> = {}): BackendContinuityView {
  return {
    workerId, runId, runTitle: 'Execution Continuity', workerName: '/root/worker-a', displayName: '/root/worker-a', assignmentTitle: 'Backend migration',
    disposition: 'awaiting_execution', policyMode: 'auto', runPolicyMode: 'auto', policySource: 'run', workerPolicyOverride: false,
    deadmanFallbackEnabled: false, deadmanThresholdMs: 1_800_000, attemptNumber: 3, autoResumeCount: 2,
    lastProgressAt: '2026-08-21T02:59:00.000Z', needsUser: false, isWorking: false, isResuming: true, blockReason: null, pauseReason: null,
    noProgressAttempts: 0, stallWarningAt: null, stallPausedAt: null, conversationUrl: binding.url, recentEvents: [],
    ...overrides,
  };
}

test('backend continuity view drives operator-readable status, policy, run metadata and counts', () => {
  const view = backend({ policySource: 'worker', workerPolicyOverride: true });
  const snapshot = localUiSnapshot({ [workerId]: binding }, { [workerId]: view }, connected, true, 7);
  assert.equal(snapshot.currentWorker?.label, 'Backend migration');
  assert.equal(snapshot.currentWorker?.hierarchicalName, '/root/worker-a');
  assert.equal(snapshot.currentWorker?.statusLabel, 'Resuming');
  assert.equal(snapshot.currentWorker?.policyMode, 'auto');
  assert.equal(snapshot.currentWorker?.policySource, 'worker');
  assert.equal(snapshot.currentWorker?.workerPolicyOverride, true);
  assert.equal(snapshot.currentWorker?.attemptNumber, 3);
  assert.equal(snapshot.currentWorker?.controlAvailable, true);
  assert.equal(snapshot.counts.resuming, 1);
  assert.equal(snapshot.autoResume, 'on');
  assert.equal(snapshot.runs[0]?.runId, runId);
  assert.equal(snapshot.runs[0]?.policyMode, 'auto');
  assert.equal(snapshot.capabilities.runControls, true);
});

test('cached backend view never enables controls while executor is disconnected', () => {
  const view = backend({ disposition: 'paused', policyMode: 'manual', runPolicyMode: 'manual', attemptNumber: 2, autoResumeCount: 1, lastProgressAt: null, isResuming: false, pauseReason: 'user' });
  const snapshot = localUiSnapshot({ [workerId]: binding }, { [workerId]: view }, { state: 'disconnected', detail: 'offline', updatedAt: connected.updatedAt }, true, 7);
  assert.equal(snapshot.currentWorker?.statusLabel, 'Paused');
  assert.equal(snapshot.currentWorker?.controlAvailable, false);
  assert.equal(snapshot.autoResume, 'off');
  assert.equal(snapshot.capabilities.runControls, false);
});

test('needs-user state outranks generic idle conversation state', () => {
  const view = backend({ disposition: 'awaiting_human', attemptNumber: 4, autoResumeCount: 3, lastProgressAt: null, needsUser: true, isResuming: false, blockReason: 'Approve deployment' });
  const snapshot = localUiSnapshot({ [workerId]: binding }, { [workerId]: view }, connected, true);
  assert.equal(snapshot.workers[0]?.statusLabel, 'Needs you');
  assert.equal(snapshot.counts.needsUser, 1);
});

test('raw worker UUID is not used as the primary label when backend display metadata is unavailable', () => {
  const view = backend({ displayName: undefined, assignmentTitle: undefined, workerName: '/root/worker-a' });
  const snapshot = localUiSnapshot({ [workerId]: binding }, { [workerId]: view }, connected, true);
  assert.equal(snapshot.workers[0]?.label, 'Managed worker');
  assert.notEqual(snapshot.workers[0]?.label, workerId);
});

test('mixed worker policies remain distinct from the authoritative run default', () => {
  const second: ManagedBinding = { ...binding, workerId: 'wrk_00000000-0000-0000-0000-000000000002', tabId: 8, conversationId: 'c-2' };
  const firstView = backend({ policyMode: 'auto' });
  const secondView = backend({ workerId: second.workerId, workerName: '/root/worker-b', policyMode: 'manual', policySource: 'worker', workerPolicyOverride: true });
  const snapshot = localUiSnapshot({ [workerId]: binding, [second.workerId]: second }, { [workerId]: firstView, [second.workerId]: secondView }, connected, true);
  assert.equal(snapshot.autoResume, 'mixed');
  assert.equal(snapshot.runs[0]?.policyMode, 'auto');
  assert.equal(snapshot.capabilities.runControls, true);
});

test('stall and recent-event capabilities are authoritative when a backend view is present', () => {
  const detailed = localUiSnapshot({ [workerId]: binding }, { [workerId]: backend({
    disposition: 'paused', pauseReason: 'stall', noProgressAttempts: 20, stallWarningAt: '2026-08-21T02:30:00.000Z',
    stallPausedAt: '2026-08-21T03:00:00.000Z', isResuming: false, recentEvents: [{ type: 'continuation.paused_for_stall', timestamp: '2026-08-21T03:00:00.000Z', detail: null }],
  }) }, connected, true);
  assert.equal(detailed.capabilities.runMetadata, true);
  assert.equal(detailed.capabilities.policySource, true);
  assert.equal(detailed.capabilities.stallMetadata, true);
  assert.equal(detailed.capabilities.recentEvents, true);
  assert.equal(detailed.workers[0]?.stallState, 'paused');
});

test('dead-man probe candidates require enabled policy and every observed unfinished worker locally dead', () => {
  const secondId = 'wrk_00000000-0000-0000-0000-000000000002';
  const views = {
    [workerId]: backend({ deadmanFallbackEnabled: true }),
    [secondId]: backend({ workerId: secondId, workerName: '/root/worker-b', deadmanFallbackEnabled: true }),
  };
  const aliveSecond: ManagedBinding = { ...binding, workerId: secondId, tabId: 8, state: 'idle' };
  assert.deepEqual(deadmanProbeRunIds({ [workerId]: { ...binding, state: 'closed' }, [secondId]: aliveSecond }, views), []);
  assert.deepEqual(deadmanProbeRunIds({ [workerId]: { ...binding, state: 'closed' }, [secondId]: { ...aliveSecond, state: 'error' } }, views), [runId]);
  assert.deepEqual(deadmanProbeRunIds({}, { [workerId]: backend({ deadmanFallbackEnabled: false }) }), []);
});
