import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import type { Membership, ScheduleWeek, Shift } from '@alqove/api-client';
import { api } from '@/lib/api';
import { useSelectedMembership } from '@/lib/stores/store-context';
import { StaffScheduleClient } from '../staff-schedule-client';
vi.mock('@/lib/stores/store-context', () => ({ useSelectedMembership: vi.fn() }));
vi.mock('@/lib/api', () => ({ api: { scheduling: { settings: vi.fn(), myWeek: vi.fn(), week: vi.fn() } } }));
const member: Membership = { id: 'm1', store_id: 's1', role: 'sales', is_exempt: false, capabilities: ['schedule.view'] };
const shift: Shift = { id: 'sh1', store_id: 's1', store_membership_id: 'm1', member_name: 'Ada', position_id: null, position_name: 'Buyer', starts_at: '2026-09-07T16:00:00Z', ends_at: '2026-09-08T01:00:00Z', published_at: '2026-09-06T10:00:00Z', revision: 'r', notes: 'Opening' };
const week: ScheduleWeek = { week_start: '2026-09-07', starts_at: '2026-09-07T07:00:00Z', ends_at: '2026-09-14T07:00:00Z', timezone: 'America/Los_Angeles', shifts: [shift], publication: null };
function mount() { return render(<QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { retry: false } } })}><StaffScheduleClient /></QueryClientProvider>); }
beforeEach(() => {
  vi.clearAllMocks();
  vi.mocked(api.scheduling.settings).mockResolvedValue({ data: { timezone: 'America/Los_Angeles', work_week_start_day: 'mon', work_week_start_time: '04:00', payroll_rounding_mode: 'none', payroll_rounding_increment_minutes: 1, clock_in_early_minutes: 0, clock_in_late_minutes: 0, clock_out_late_minutes: 0 } });
  vi.mocked(useSelectedMembership).mockReturnValue(member);
  vi.mocked(api.scheduling.myWeek).mockResolvedValue({ data: week });
  vi.mocked(api.scheduling.week).mockResolvedValue({ data: { ...week, shifts: [shift, { ...shift, id: 'sh2', member_name: 'Bo', store_membership_id: 'm2' }] } });
});
afterEach(() => vi.useRealTimers());
describe('staff schedule', () => {
  it('starts in the store-local current week rather than the UTC or browser date', async () => {
    vi.setSystemTime(new Date('2026-09-07T02:00:00Z'));
    mount();
    await waitFor(() => expect(api.scheduling.myWeek).toHaveBeenCalledWith('s1', '2026-09-06'));
  });
  it('reads own published shifts from /my, then switches to read-only team grid', async () => {
    mount();
    expect(await screen.findByText('Opening')).toBeInTheDocument();
    expect(screen.getByText('09:00 – 18:00')).toBeInTheDocument();
    expect(screen.getByText('America/Los_Angeles')).toBeInTheDocument();
    expect(api.scheduling.week).not.toHaveBeenCalled();
    await userEvent.click(screen.getByRole('button', { name: 'Team Schedule' }));
    expect(await screen.findByRole('table')).toBeInTheDocument();
    expect(screen.getByRole('rowheader', { name: 'Bo' })).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: /edit|publish|copy|add shift/i })).not.toBeInTheDocument();
    await userEvent.click(screen.getByRole('button', { name: 'Next week' }));
    await waitFor(() => expect(api.scheduling.week).toHaveBeenLastCalledWith('s1', '2026-09-14'));
  });
  it('remains read only for members who also have management capabilities', async () => {
    vi.mocked(useSelectedMembership).mockReturnValue({ ...member, capabilities: ['schedule.view', 'schedule.manage', 'schedule.publish', 'schedule.view_drafts'] });
    vi.mocked(api.scheduling.week).mockResolvedValue({ data: { ...week, shifts: [shift, { ...shift, id: 'draft', notes: 'Secret draft', published_at: null }] } });
    mount();
    await userEvent.click(screen.getByRole('button', { name: 'Team Schedule' }));
    await screen.findByRole('table');
    expect(screen.queryByText('Secret draft')).not.toBeInTheDocument();
    expect(screen.queryByRole('button', { name: /edit|publish|copy|add shift/i })).not.toBeInTheDocument();
  });
  it('does not query without a selected membership', () => {
    vi.mocked(useSelectedMembership).mockReturnValue(undefined);
    mount();
    expect(api.scheduling.myWeek).not.toHaveBeenCalled();
    expect(screen.getByText(/select a store/i)).toBeInTheDocument();
  });
});
