import { TestBed } from '@angular/core/testing';
import { describe, it, expect } from 'vitest';
import { Valid } from '@registratie/domain/change-request.machine';
import { ChangeRequestAdapter } from '@registratie/infrastructure/change-request.adapter';
import { createSubmitChangeRequest } from './submit-change-request';
import { parsePostcode } from '@registratie/domain/value-objects/postcode';

const postcode = parsePostcode('2514 EA');
if (!postcode.ok) throw new Error('fixture postcode should parse');

const data: Valid = {
  straat: 'Lange Voorhout 9',
  postcode: postcode.value,
  woonplaats: 'Den Haag',
};

function setup(adapter: Partial<ChangeRequestAdapter>) {
  TestBed.configureTestingModule({
    providers: [{ provide: ChangeRequestAdapter, useValue: adapter }],
  });
  return TestBed.runInInjectionContext(() => createSubmitChangeRequest());
}

describe('createSubmitChangeRequest', () => {
  it('resolves ok with the referentie on success', async () => {
    const submit = setup({ changeRequest: () => Promise.resolve('BIG-2026-000123') });
    const r = await submit(data);
    expect(r).toEqual({ ok: true, value: 'BIG-2026-000123' });
  });

  it('folds a rejected call into a Result error, never throwing', async () => {
    const submit = setup({
      changeRequest: () => Promise.reject(new Error('network kaput')),
    });
    const r = await submit(data);
    expect(r.ok).toBe(false);
  });

  it('surfaces a ProblemDetails detail message when the server rejects with one', async () => {
    const submit = setup({
      changeRequest: () => Promise.reject({ detail: 'Postcode komt niet overeen met de straat.' }),
    });
    const r = await submit(data);
    expect(r).toEqual({ ok: false, error: 'Postcode komt niet overeen met de straat.' });
  });
});
