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

const binding: ManagedBinding = {
  workerId: 'wrk_00000000-0000-0000-0000-000000000001',
  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: binding.workerId,
    displayName: '/root/worker-a',
    assignmentTitle: 'Backend migration',
    disposition: 'awaiting_execution',
    policyMode: 'auto',
    attemptNumber: 3,
    autoResumeCount: 2,
    lastProgressAt: '2026-08-21T02:59:00.000Z',
    needsUser: false,
    isWorking: false,
    isResuming: true,
    ...overrides,
  };
}

test('backend continuity view drives operator-readable status, policy and counts', () => {
  const view = backend({ policySource: 'worker' });
  const snapshot = localUiSnapshot({ [binding.workerId]: binding }, { [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?.attemptNumber, 3);
  assert.equal(snapshot.currentWorker?.controlAvailable, true);
  assert.equal(snapshot.counts.resuming, 1);
  assert.equal(snapshot.autoResume, 'on');
});

test('cached backend view never enables controls while executor is disconnected', () => {
  const view = backend({ disposition: 'paused', policyMode: 'manual', attemptNumber: 2, autoResumeCount: 1, lastProgressAt: null, isResuming: false });
  const snapshot = localUiSnapshot(
    { [binding.workerId]: binding },
    { [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');
});

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 });
  const snapshot = localUiSnapshot({ [binding.workerId]: binding }, { [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();
  delete view.displayName;
  delete view.assignmentTitle;
  const snapshot = localUiSnapshot({ [binding.workerId]: binding }, { [binding.workerId]: view }, connected, true);
  assert.equal(snapshot.workers[0]?.label, 'Managed worker');
  assert.notEqual(snapshot.workers[0]?.label, binding.workerId);
});

test('mixed worker policies are represented as mixed rather than a fake global toggle', () => {
  const second: ManagedBinding = { ...binding, workerId: 'wrk_00000000-0000-0000-0000-000000000002', tabId: 8, conversationId: 'c-2' };
  const firstView = backend({ policyMode: 'auto' });
  const secondView = { ...backend({ policyMode: 'manual' }), workerId: second.workerId };
  const snapshot = localUiSnapshot(
    { [binding.workerId]: binding, [second.workerId]: second },
    { [binding.workerId]: firstView, [second.workerId]: secondView },
    connected,
    true,
  );
  assert.equal(snapshot.autoResume, 'mixed');
  assert.equal(snapshot.capabilities.runControls, false);
});

test('stall and run capabilities stay unavailable until authoritative backend fields are published', () => {
  const basic = localUiSnapshot({ [binding.workerId]: binding }, { [binding.workerId]: backend() }, connected, true);
  assert.equal(basic.capabilities.runMetadata, false);
  assert.equal(basic.capabilities.stallMetadata, false);
  assert.equal(basic.workers[0]?.stallState, 'unavailable');

  const detailed = localUiSnapshot({ [binding.workerId]: binding }, { [binding.workerId]: backend({
    runId: 'run_00000000-0000-0000-0000-000000000001',
    runTitle: 'Execution Continuity',
    policySource: 'run',
    pauseReason: 'stall',
    noProgressAttempts: 20,
    stallWarningAt: '2026-08-21T02:30:00.000Z',
    stallPausedAt: '2026-08-21T03:00:00.000Z',
    stallMetadataAvailable: true,
  }) }, connected, true);
  assert.equal(detailed.capabilities.runMetadata, true);
  assert.equal(detailed.capabilities.policySource, true);
  assert.equal(detailed.capabilities.stallMetadata, true);
  assert.equal(detailed.workers[0]?.stallState, 'paused');
});
