import test from 'node:test';
import assert from 'node:assert/strict';

import { IncidentScheduler } from './IncidentScheduler.js';

function createMemorySave(state) {
  return {
    state: structuredClone(state),
    get() {
      return this.state;
    },
    set(partial) {
      const nextState = { ...this.state };
      for (const [key, value] of Object.entries(partial)) {
        if (value && typeof value === 'object' && !Array.isArray(value) && nextState[key] && typeof nextState[key] === 'object' && !Array.isArray(nextState[key])) {
          nextState[key] = { ...nextState[key], ...structuredClone(value) };
        } else {
          nextState[key] = structuredClone(value);
        }
      }
      this.state = nextState;
      return this.state;
    }
  };
}

test('IncidentScheduler escalates active quest pressure and raises linked ticket priority', async () => {
  const sentMail = [];
  const priorityUpdates = [];
  const save = createMemorySave({
    shift_started_at: '2026-04-25T11:00:00Z',
    world_flags: [],
    pressure: {},
    incidents: {}
  });

  const scheduler = new IncidentScheduler({
    loader: {
      incidents: new Map(),
      get(type, id) {
        if (type === 'quests') {
          return {
            id,
            ticket_id: 'T002',
            pressure_profile: 'web_outage_escalation'
          };
        }

        if (type === 'pressureProfiles') {
          return {
            id: 'web_outage_escalation',
            escalation_steps: [
              { trigger_after_seconds: 900, notification: 'Hermes is still showing errors.', notification_severity: 'warning' },
              { trigger_after_seconds: 1800, notification: 'Priority is going up.', notification_severity: 'warning', escalate_linked_ticket: 'high' }
            ]
          };
        }

        return null;
      }
    },
    email: {
      send(payload) {
        sentMail.push(payload);
        return payload;
      }
    },
    quests: {
      getAllEntries() {
        return [[
          'Q002',
          { state: 'active', started_at: '2026-04-25T11:30:00Z' }
        ]];
      }
    },
    save,
    tickets: {
      setPriority(ticketId, value) {
        priorityUpdates.push({ ticketId, value });
      }
    },
    validator: {
      async evaluateRule() {
        return { passed: false, failures: ['not-applicable'] };
      }
    },
    now: () => new Date('2026-04-25T12:05:00Z').getTime(),
    tickSeconds: 30
  });

  await scheduler.tick();

  assert.equal(sentMail.length, 2);
  assert.deepEqual(priorityUpdates, [{ ticketId: 'T002', value: 'high' }]);
  assert.deepEqual(save.get().pressure.Q002.fired_step_indexes, [0, 1]);
});
