#!/usr/bin/env tsx
/**
 * Smoke test métier — preuves HTTP réelles + ingestion directe
 * Usage: tsx server/scripts/smoke-business.ts [BASE_URL] [API_KEY]
 */
import { intakeService, blacklistService, extensionAuthService } from '../src/services/intake.service.js';
import { getDb, resetDbForTests, closeDb } from '../src/db/index.js';

const BASE = process.argv[2] ?? 'http://127.0.0.1:3847';
const API_KEY = process.argv[3] ?? process.env.MAJ_WP_API_KEY ?? 'dev-maj-wp-api-key-change-in-prod';
const ADMIN_USER = process.env.ADMIN_USER ?? 'admin';
const ADMIN_PASS = process.env.ADMIN_PASS ?? 'admin';

const log = (step: string, detail: unknown) => {
  console.log(`\n${'═'.repeat(60)}\n${step}\n${'─'.repeat(60)}`);
  console.log(typeof detail === 'string' ? detail : JSON.stringify(detail, null, 2));
};

async function http(method: string, path: string, opts: { body?: unknown; token?: string; cookie?: string } = {}) {
  const headers: Record<string, string> = { 'Content-Type': 'application/json' };
  if (opts.token) headers.Authorization = `Bearer ${opts.token}`;
  if (opts.cookie) headers.Cookie = opts.cookie;
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers,
    body: opts.body ? JSON.stringify(opts.body) : undefined,
  });
  const text = await res.text();
  let json: unknown = text;
  try { json = JSON.parse(text); } catch { /* raw */ }
  return { status: res.status, body: json, headers: Object.fromEntries(res.headers.entries()) };
}

async function main() {
  // Use isolated DB for smoke — only if SMOKE_ISOLATED=1
  if (process.env.SMOKE_ISOLATED === '1') {
    resetDbForTests();
  }

  log('0. HEALTH', await http('GET', '/api/health'));

  const login = await http('POST', '/api/auth/login', {
    body: { username: ADMIN_USER, password: ADMIN_PASS },
  });
  log('1. ADMIN LOGIN', { status: login.status, body: login.body });
  const cookie = login.headers['set-cookie']?.split(';')[0] ?? '';

  // ── Gmail ingest + dedup ──
  const g1 = intakeService.ingest({
    source_type: 'gmail',
    source_external_id: 'gmail-msg-smoke-001',
    source_url: 'https://mail.google.com/mail/u/0/#inbox/smoke001',
    sender_email: 'smoke.test@example.com',
    sender_name: 'Smoke Test',
    title: 'Email smoke test paiement',
    body: 'Contenu email de test smoke.',
    attachments: [{ filename: 'facture.pdf', mimeType: 'application/pdf', size: 12345, sourceRef: 'att-smoke-1' }],
  });
  log('2. GMAIL INGEST #1', { created: g1.created, duplicate: g1.duplicate, id: g1.item.id, decision: g1.item.decision });

  const g2 = intakeService.ingest({
    source_type: 'gmail',
    source_external_id: 'gmail-msg-smoke-001',
    title: 'duplicate attempt',
    sender_email: 'smoke.test@example.com',
  });
  log('3. GMAIL DEDUP #2', { created: g2.created, duplicate: g2.duplicate, same_id: g2.item.id === g1.item.id });

  // ── Monday Chrome + dedup + API cross-dedup ──
  const m1 = intakeService.ingest({
    source_type: 'monday_chrome',
    source_account: '123',
    source_external_id: 'monday-123-456789',
    source_url: 'https://foo.monday.com/boards/123/pulses/456789',
    sender_name: 'Marie Monday',
    title: 'Item Monday smoke',
    body: 'Description item Monday',
  });
  log('4. MONDAY CHROME INGEST', { created: m1.created, id: m1.item.id });

  const m2 = intakeService.ingest({
    source_type: 'monday_chrome',
    source_account: '123',
    source_external_id: 'monday-123-456789',
    title: 'dup chrome',
  });
  log('5. MONDAY CHROME DEDUP', { duplicate: m2.duplicate, same_id: m2.item.id === m1.item.id });

  const m3 = intakeService.ingest({
    source_type: 'monday_api',
    source_account: '123',
    source_external_id: 'monday-123-456789',
    title: 'from monday api',
  });
  log('6. MONDAY API vs CHROME DEDUP', { duplicate: m3.duplicate, same_id: m3.item.id === m1.item.id });

  // ── Approve / Ignore / Restore ──
  const approved = intakeService.approve(g1.item.id)!;
  log('7. APPROVE', { id: approved.id, decision: approved.decision, status: approved.status });

  const ignored = intakeService.ignore(m1.item.id)!;
  log('8. IGNORE', { id: ignored.id, decision: ignored.decision });

  log('9. IGNORED LIST (HTTP)', await http('GET', '/api/intake/ignored', { cookie }));

  const restored = intakeService.restore(m1.item.id)!;
  log('10. RESTORE', { id: restored.id, decision: restored.decision });

  // ── Blacklist ──
  const blItem = intakeService.ingest({
    source_type: 'gmail',
    source_external_id: 'gmail-bl-001',
    sender_email: 'blacklist.me@example.com',
    sender_name: 'BL Test',
    title: 'Blacklist test item',
  });
  intakeService.ignore(blItem.item.id);
  const blSender = blacklistService.ignoreSenderFromItem(blItem.item.id)!;
  log('11. BLACKLIST SENDER', blSender);

  const autoIgnored = intakeService.ingest({
    source_type: 'gmail',
    source_external_id: 'gmail-bl-002',
    sender_email: 'blacklist.me@example.com',
    title: 'Should be auto_ignored',
  });
  log('12. AUTO_IGNORED NEW EMAIL', {
    decision: autoIgnored.item.decision,
    warnings: autoIgnored.item.parse_warnings,
  });

  blacklistService.deactivate(blSender.id);
  log('13. BLACKLIST DEACTIVATED', blacklistService.list(true));

  // Re-approve gmail for maj-wp flow (may already be approved)
  intakeService.approve(g1.item.id);

  // ── maj-wp simulation ──
  log('14. GET /api/v1/tickets/ready', await http('GET', '/api/v1/tickets/ready', { token: API_KEY }));

  const claim = await http('POST', '/api/v1/intake/claim-next', {
    token: API_KEY,
    body: { consumer_id: 'smoke-maj-wp' },
  });
  log('15. CLAIM-NEXT', claim);

  const claimBody = claim.body as { item?: { id: string }; claim_token?: string };
  const claimId = claimBody.item?.id;
  const claimToken = claimBody.claim_token;

  if (claimId) {
    const claim2 = await http('POST', `/api/v1/intake/${claimId}/claim`, {
      token: API_KEY,
      body: { consumer_id: 'smoke-maj-wp-2' },
    });
    log('16. CONCURRENT CLAIM (expect 409)', claim2);

    const created = await http('POST', `/api/v1/intake/${claimId}/created`, {
      token: API_KEY,
      body: {
        claim_token: claimToken,
        maj_wp_ticket_id: 'WP-SMOKE-42',
        remote_status: 'open',
        remote_message: 'Ticket créé smoke test',
      },
    });
    log('17. CREATED ACK', created);

    const created2 = await http('POST', `/api/v1/intake/${claimId}/created`, {
      token: API_KEY,
      body: { maj_wp_ticket_id: 'WP-SMOKE-42' },
    });
    log('18. IDEMPOTENT CREATED ACK', created2);

    const status1 = await http('POST', `/api/v1/intake/${claimId}/status`, {
      token: API_KEY,
      body: {
        status: 'in_progress',
        remote_status: 'WAITING_HUMAN',
        remote_message: 'WAITING_HUMAN — Informations client manquantes',
      },
    });
    log('19. STATUS UPDATE (WAITING_HUMAN)', status1);

    const status2 = await http('POST', `/api/v1/intake/${claimId}/status`, {
      token: API_KEY,
      body: {
        status: 'failed',
        remote_status: 'error',
        remote_message: 'Échec création',
        error: 'Timeout API prestashop',
      },
    });
    log('20. ERROR STATUS', status2);

    log('21. GET ITEM FINAL', await http('GET', `/api/v1/intake/${claimId}`, { token: API_KEY }));
  }

  log('22. TICKETS LIST (admin)', await http('GET', '/api/intake/tickets', { cookie }));

  // ── Extension pairing (no hardcoded secret) ──
  const pairCode = extensionAuthService.createPairingCode();
  const paired = extensionAuthService.redeemPairingCode(pairCode.code, 'smoke-test')!;
  log('23. EXTENSION PAIRING', { code: pairCode.code, token_id: paired.id, token_len: paired.token.length });

  const extIngest = await http('POST', '/api/extension/ingest', {
    token: paired.token,
    body: {
      source_type: 'monday_chrome',
      source_account: '999',
      source_external_id: 'monday-999-111',
      title: 'Extension HTTP ingest',
      body: 'Via Bearer pairing token',
    },
  });
  log('24. EXTENSION INGEST HTTP', extIngest);

  const extDup = await http('POST', '/api/extension/ingest', {
    token: paired.token,
    body: {
      source_type: 'monday_chrome',
      source_account: '999',
      source_external_id: 'monday-999-111',
      title: 'Extension dup',
    },
  });
  log('25. EXTENSION DEDUP', extDup);

  console.log('\n✓ SMOKE BUSINESS COMPLETE\n');
  closeDb();
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
