// Display guard: starting encounter does NOT steal display from another live encounter.
// Ending encounter does NOT clear display if different encounter showing.

import React from 'react';
import { screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { getCalls, MOCK_DB } from '../__mocks__/firebase/_mock-db';
import { setupReady, addMonsterViaUI, startCombatViaUI } from './testHelpers';

const DISPLAY_PATH = 'artifacts/ttrpg-initiative-tracker-default/public/data/activeDisplay/status';

function findCallActiveDisplay(fn) {
  return getCalls().filter(c => c.fn === fn && c.path.includes('activeDisplay/status'));
}

describe('Display guard', () => {
  test('startEncounter: claims display when slot empty', async () => {
    await setupReady('GuardCamp1', 'GuardEnc1');
    await addMonsterViaUI('Goblin', 10, 5);
    await startCombatViaUI();
    const adCalls = findCallActiveDisplay('setDoc');
    const last = adCalls[adCalls.length - 1];
    expect(last).toBeTruthy();
    expect(last.data.activeEncounterId).toBeTruthy();
  });

  test('startEncounter: does NOT steal display from another live encounter', async () => {
    // Pre-seed display as busy with a DIFFERENT encounter
    MOCK_DB.set(DISPLAY_PATH, {
      activeCampaignId: 'other-camp',
      activeEncounterId: 'other-enc',
    });

    await setupReady('GuardCamp2', 'GuardEnc2');
    await addMonsterViaUI('Orc', 15, 8);
    await startCombatViaUI();

    // Combat started on encounter doc
    const encCalls = getCalls().filter(c => c.fn === 'updateDoc' && c.path.includes('/encounters/'));
    expect(encCalls.some(c => c.data.isStarted === true)).toBe(true);

    // But display setDoc should NOT have been called to claim this encounter
    const adClaims = findCallActiveDisplay('setDoc').filter(
      c => c.data && c.data.activeEncounterId && c.data.activeEncounterId !== 'other-enc'
    );
    expect(adClaims).toHaveLength(0);
  });

  test('endEncounter: clears display when ending the displayed encounter', async () => {
    await setupReady('GuardCamp3', 'GuardEnc3');
    await addMonsterViaUI('Wolf', 8, 3);
    await startCombatViaUI();

    fireEvent.click(screen.getByRole('button', { name: /End Combat/i }));
    fireEvent.click(await screen.findByRole('button', { name: /Confirm/i }));

    await waitFor(() => {
      const adCalls = findCallActiveDisplay('setDoc');
      const last = adCalls[adCalls.length - 1];
      return last && last.data && last.data.activeCampaignId === null;
    });
    const adCalls = findCallActiveDisplay('setDoc');
    const last = adCalls[adCalls.length - 1];
    expect(last.data).toMatchObject({ activeCampaignId: null, activeEncounterId: null });
  });

  test('endEncounter: does NOT clear display when different encounter is live', async () => {
    await setupReady('GuardCamp4', 'GuardEnc4');
    await addMonsterViaUI('Bat', 4, 2);
    await startCombatViaUI();

    // Now hijack display to a different encounter (simulating eyeball toggle elsewhere)
    MOCK_DB.set(DISPLAY_PATH, {
      activeCampaignId: 'different-camp',
      activeEncounterId: 'different-enc',
    });

    fireEvent.click(screen.getByRole('button', { name: /End Combat/i }));
    fireEvent.click(await screen.findByRole('button', { name: /Confirm/i }));

    // Wait for encounter to end
    await waitFor(() => {
      const encCalls = getCalls().filter(c => c.fn === 'updateDoc' && c.path.includes('/encounters/'));
      const last = encCalls[encCalls.length - 1];
      return last && last.data.isStarted === false;
    });

    // Display should NOT have been cleared
    const clearCalls = findCallActiveDisplay('setDoc').filter(
      c => c.data && c.data.activeCampaignId === null
    );
    expect(clearCalls).toHaveLength(0);
  });
});
