import test from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { SecurityProfileStore } from '../lib/security/security-profile-store.mjs';
import { SecurityOnboarding } from '../lib/security/security-onboarding.mjs';

function setup(secret = 'test-only-security-profile-key-at-least-32-chars') {
  const sent = [];
  const alerter = {
    isConfigured: true,
    async sendMessage(text, options) {
      sent.push({ text, options });
      return { ok: true };
    },
  };
  const path = join(mkdtempSync(join(tmpdir(), 'security-onboarding-')), 'profile.enc');
  const store = new SecurityProfileStore(path, secret).init();
  return { sent, store, onboarding: new SecurityOnboarding({ store, alerter, chatId: '42' }) };
}

function query() {
  return { message: { chat: { id: 42 } } };
}

test('first startup asks only for language before personal information', async () => {
  const { sent, onboarding } = setup();
  assert.equal(await onboarding.ensureStarted(), true);
  assert.equal(sent.length, 1);
  assert.match(sent[0].text, /DAVE/);
  assert.match(sent[0].text, /language|Sprache/i);
  assert.deepEqual(sent[0].options.replyMarkup.inline_keyboard[0].map(button => button.callback_data), [
    'security_language:de',
    'security_language:en',
  ]);
  assert.doesNotMatch(sent[0].text, /city|country|address|Stadt|Land|Adresse/i);
});

test('minimal onboarding saves only after review confirmation', async () => {
  const { store, onboarding } = setup();
  await onboarding.start(42);
  let result = await onboarding.handleCallback('security_language:de', query());
  assert.equal(result.handled, true);
  assert.match(result.response.text, /verschl/iu);
  result = await onboarding.handleCallback('security_consent:minimal', query());
  assert.match(result.response.text, /Land/);

  const answers = ['Deutschland', 'NRW', 'Koeln', 'Europe/Berlin', 'weather,cyber', 'important', '22:00-07:00'];
  for (const answer of answers) result = onboarding.handleMessage(answer, query().message);
  assert.equal(store.exists, false);
  assert.match(result.response.text, /pr.f/iu);

  result = await onboarding.handleCallback('security_review:save', query());
  assert.equal(store.exists, true);
  assert.equal(store.getProfile().language, 'de');
  assert.equal(store.getProfile().location.city, 'Koeln');
  assert.equal(result.handled, true);
});

test('profile deletion requires explicit callback confirmation', async () => {
  const { store, onboarding } = setup();
  store.save({ language: 'en', location: { country: 'DE' }, consentedAt: new Date().toISOString() });
  assert.match(onboarding.deletePrompt().text, /Delete/);
  await onboarding.handleCallback('security_delete:cancel', query());
  assert.equal(store.exists, true);
  await onboarding.handleCallback('security_delete:confirm', query());
  assert.equal(store.exists, false);
});

test('setup remains unavailable without a valid encryption key', async () => {
  const { sent, onboarding } = setup('short');
  assert.equal(await onboarding.ensureStarted(), false);
  assert.match(sent[0].text, /SECURITY_PROFILE_ENCRYPTION_KEY/);
});
