/**
 * Login / session / connection-state characterization for `authStore`.
 *
 * authStore has no single `login()` action — the UI composes:
 *   pingWithCredentials → addServer → setActiveServer → setLoggedIn
 * Tests target that composed sequence + the connection-state surface
 * (`isConnecting`, `connectionError`) and the Last.fm session helpers.
 *
 * Phase F2 / PR 3 of the pre-refactor testing plan.
 */
import { beforeEach, describe, expect, it } from 'vitest';
import { useAuthStore } from './authStore';
import { resetAuthStore } from '@/test/helpers/storeReset';
import { makeServer } from '@/test/helpers/factories';

beforeEach(() => {
  resetAuthStore();
});

describe('login flow (composed)', () => {
  it('successful login: addServer → setActiveServer → setLoggedIn pins the active session', () => {
    const profile = makeServer({ name: 'Home' });
    const { addServer, setActiveServer, setLoggedIn } = useAuthStore.getState();

    const id = addServer({ name: profile.name, url: profile.url, username: profile.username, password: profile.password });
    setActiveServer(id);
    setLoggedIn(true);

    const s = useAuthStore.getState();
    expect(s.servers).toHaveLength(1);
    expect(s.servers[0]?.id).toBe(id);
    expect(s.servers[0]?.name).toBe('Home');
    expect(s.activeServerId).toBe(id);
    expect(s.isLoggedIn).toBe(true);
  });

  it('failed login (no addServer call) leaves prior valid state intact', () => {
    const existing = makeServer({ name: 'Existing' });
    const existingId = useAuthStore.getState().addServer({
      name: existing.name, url: existing.url, username: existing.username, password: existing.password,
    });
    useAuthStore.getState().setActiveServer(existingId);
    useAuthStore.getState().setLoggedIn(true);

    // Simulate ping failure — the UI sets connecting + error but does NOT
    // touch servers / activeServerId / isLoggedIn.
    useAuthStore.getState().setConnecting(true);
    useAuthStore.getState().setConnectionError('connection refused');
    useAuthStore.getState().setConnecting(false);

    const s = useAuthStore.getState();
    expect(s.servers).toHaveLength(1);
    expect(s.servers[0]?.id).toBe(existingId);
    expect(s.activeServerId).toBe(existingId);
    expect(s.isLoggedIn).toBe(true);
    expect(s.connectionError).toBe('connection refused');
  });

  it('addServer assigns a unique id even for duplicate-payload calls', () => {
    const make = () => useAuthStore.getState().addServer({
      name: 'Same', url: 'https://same.test', username: 'u', password: 'p',
    });
    const id1 = make();
    const id2 = make();
    expect(id1).not.toBe(id2);
    expect(useAuthStore.getState().servers).toHaveLength(2);
  });
});

describe('connection state', () => {
  it('setConnecting / setConnectionError toggle the loading + error fields independently', () => {
    const { setConnecting, setConnectionError } = useAuthStore.getState();

    setConnecting(true);
    expect(useAuthStore.getState().isConnecting).toBe(true);

    setConnectionError('boom');
    expect(useAuthStore.getState().connectionError).toBe('boom');

    setConnecting(false);
    setConnectionError(null);
    expect(useAuthStore.getState().isConnecting).toBe(false);
    expect(useAuthStore.getState().connectionError).toBeNull();
  });
});

describe('logout', () => {
  it('clears isLoggedIn + musicFolders but keeps the server entry', () => {
    const id = useAuthStore.getState().addServer({
      name: 'Home', url: 'https://x.test', username: 'u', password: 'p',
    });
    useAuthStore.getState().setActiveServer(id);
    useAuthStore.getState().setLoggedIn(true);
    useAuthStore.getState().setMusicFolders([{ id: 'mf-1', name: 'Music' }]);

    useAuthStore.getState().logout();

    const s = useAuthStore.getState();
    expect(s.isLoggedIn).toBe(false);
    expect(s.musicFolders).toEqual([]);
    expect(s.servers).toHaveLength(1);
    expect(s.activeServerId).toBe(id);
  });
});
