import '@angular/compiler';
import { Injector, runInInjectionContext } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { gql } from 'graphql-tag';
import { of } from 'rxjs';
import { mutateCreate } from './mutate-create';

const MOCK_MUTATION = gql`
  mutation CreateTag($payload: CreateTagInput!) {
    iamCreateTag(payload: $payload) {
      id
    }
  }
`;

describe('mutateCreate', () => {
  let apolloMutateSpy: ReturnType<typeof vi.fn>;
  let injector: Injector;

  beforeEach(() => {
    apolloMutateSpy = vi.fn().mockReturnValue(of({ data: { iamCreateTag: { id: '1' } } }));
    injector = Injector.create({
      providers: [{ provide: Apollo, useValue: { mutate: apolloMutateSpy } }],
    });
  });

  function run(payload: Record<string, unknown>, headers?: Record<string, string>) {
    return runInInjectionContext(injector, () => mutateCreate(MOCK_MUTATION, payload, headers));
  }

  it('calls apollo.mutate with the payload wrapped under `payload`', () => {
    run({ id: '1', name: 'Tag' }).subscribe();
    expect(apolloMutateSpy).toHaveBeenCalledWith({
      mutation: MOCK_MUTATION,
      variables: { payload: { id: '1', name: 'Tag' } },
      context: { headers: undefined },
    });
  });

  it('forwards custom headers to the mutation context', () => {
    run({ id: '1', name: 'Tag' }, { 'X-Tenant-Id': 'abc' }).subscribe();
    expect(apolloMutateSpy).toHaveBeenCalledWith({
      mutation: MOCK_MUTATION,
      variables: { payload: { id: '1', name: 'Tag' } },
      context: { headers: { 'X-Tenant-Id': 'abc' } },
    });
  });

  it('does not mutate or generate ids — the caller owns payload shape', () => {
    run({ id: '', name: 'Tag' }).subscribe();
    const calledPayload = apolloMutateSpy.mock.calls[0][0].variables.payload;
    expect(calledPayload.id).toBe('');
  });

  it('returns the apollo mutation observable', () => {
    let emitted: unknown;
    run({ id: '1', name: 'Tag' }).subscribe((r) => (emitted = r));
    expect(emitted).toEqual({ data: { iamCreateTag: { id: '1' } } });
  });
});
