import { act, fireEvent, render, screen } from '@testing-library/react';
import { useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { beforeEach, expect, it, vi } from 'vitest';
import type { AuthUser } from '@alqove/types';
import type { Membership } from '@alqove/api-client';
import { useAuthStore } from '@/stores/auth';
import SellerLayout from '../layout';
const navigation = vi.hoisted(() => ({ pathname: '/seller', replace: vi.fn() }));
vi.mock('next/navigation', () => ({ usePathname: () => navigation.pathname, useRouter: () => ({ replace: navigation.replace }) }));
vi.mock('@/lib/api', () => ({ api: {} }));
vi.mock('@/components/seller/seller-top-bar', () => ({ SellerTopBar: ({ storeName }: { storeName: string }) => <header>{storeName}</header> }));
const member = (storeId: string, capabilities: Membership['capabilities'] = ['store.admin', 'team.view', 'team.manage']): Membership => ({
  id: `m-${storeId}`, store_id: storeId, store_name: storeId,
  role: 'owner', capabilities, is_exempt: false,
});
beforeEach(() => {
  navigation.pathname = '/seller';
  navigation.replace.mockReset();
  useAuthStore.setState({ user: { id: 'user', store_id: 'legacy' } as AuthUser, token: 'token',
    isLoading: false, memberships: [member('a'), member('b')], selectedStoreId: 'a' });
});
it.each([
  ['/seller/schedule', 'schedule.manage', 'Schedule'],
  ['/seller/timesheets', 'timesheets.approve', 'Timesheets'],
  ['/seller/payroll', 'payroll.export', 'Payroll'],
  ['/seller/settings/schedule', 'settings.schedule', 'Schedule settings'],
] as const)('gates %s on its own capability instead of marketplace ownership', (path, capability, label) => {
  navigation.pathname = path;
  useAuthStore.setState({ memberships: [member('a', [capability])] });
  const { rerender } = render(<SellerLayout><div>Module content</div></SellerLayout>);
  expect(screen.getByText('Module content')).toBeInTheDocument();
  expect(screen.getByRole('link', { name: label })).toHaveAttribute('href', path);
  act(() => useAuthStore.setState({ memberships: [member('a', ['store.admin'])] }));
  rerender(<SellerLayout><div>Module content</div></SellerLayout>);
  expect(screen.queryByText('Module content')).not.toBeInTheDocument();
});
it('switches stores with a fresh form and query cache, never reviving the previous store', () => {
  function StoreForm() {
    const [draft, setDraft] = useState('');
    const qc = useQueryClient();
    return <><input aria-label="Draft" value={draft} onChange={(e) => { setDraft(e.target.value); qc.setQueryData(['private'], e.target.value); }} />
      <span data-testid="cache">{qc.getQueryData<string>(['private']) ?? 'empty'}</span></>;
  }
  render(<SellerLayout><StoreForm /></SellerLayout>);
  fireEvent.change(screen.getByLabelText('Draft'), { target: { value: 'Store A draft' } });
  fireEvent.change(screen.getByRole('combobox', { name: 'Store' }), { target: { value: 'b' } });
  expect(useAuthStore.getState().selectedStoreId).toBe('b');
  expect(screen.getByLabelText('Draft')).toHaveValue('');
  expect(screen.getByTestId('cache')).toHaveTextContent('empty');
  fireEvent.change(screen.getByRole('combobox', { name: 'Store' }), { target: { value: 'a' } });
  expect(screen.getByLabelText('Draft')).toHaveValue('');
  expect(screen.getByTestId('cache')).toHaveTextContent('empty');
  act(() => useAuthStore.setState({ memberships: [] }));
  expect(screen.queryByLabelText('Draft')).not.toBeInTheDocument();
});
it.each(['/seller', '/seller/orders', '/seller/settings/payments', '/seller/returns', '/seller/inbox/messages', '/seller/teamish', '/seller/team/unregistered', '/seller/unknown', '/seller/settings/unknown'])('gates %s on an explicit capability, not role or path prefix', (path) => {
  navigation.pathname = path;
  useAuthStore.setState({ memberships: [member('a', ['team.view', 'team.manage'])] });
  render(<SellerLayout><div>Private seller content</div></SellerLayout>);
  expect(screen.queryByText('Private seller content')).not.toBeInTheDocument();
});
it('permits a team manager without a legacy store but hides marketplace nav', () => {
  navigation.pathname = '/seller/team';
  useAuthStore.setState({ user: { id: 'user', store_id: null } as AuthUser, memberships: [member('a', ['team.view', 'team.manage'])] });
  render(<SellerLayout><div>Team roster</div></SellerLayout>);
  expect(screen.getByText('Team roster')).toBeInTheDocument();
  expect(screen.getByRole('link', { name: 'Team' })).toBeInTheDocument();
  expect(screen.queryByRole('link', { name: 'Payouts' })).not.toBeInTheDocument();
  expect(screen.queryByRole('link', { name: 'Dashboard' })).not.toBeInTheDocument();
});
it.each([[null], [[]]])('never renders protected content with unknown or absent memberships (%s)', (memberships) => {
  useAuthStore.setState({ memberships });
  render(<SellerLayout><div>Private seller content</div></SellerLayout>);
  expect(screen.queryByText('Private seller content')).not.toBeInTheDocument();
});
