import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { I18nextProvider } from 'react-i18next';
import { ThemeProvider } from 'styled-components';
import i18n from '@/locales/i18n';
import { LocaleProvider } from '@/app/providers/LocaleProvider';
import { lightTheme } from '@/styles/theme';
import { SetupWizard } from '@/features/onboarding/components/SetupWizard';
import * as departmentAdminService from '@/features/admin/services/departmentAdminService';
import * as notificationService from '@/features/notifications/services/notificationService';

const updateStep = vi.fn().mockResolvedValue(undefined);
const complete = vi.fn().mockResolvedValue(undefined);

vi.mock('@/features/onboarding/hooks/useOnboarding', () => ({
  ONBOARDING_QUERY_KEY: ['onboarding', 'status'],
  useOnboarding: () => ({
    shouldShowWizard: true,
    persona: 'department_head',
    departmentId: 'dept-1',
    currentStep: 'portal',
    updateStep,
    complete,
    isUpdating: false,
    isLoading: false,
  }),
}));

vi.mock('@/features/auth/store/authStore', () => ({
  useAuthStore: (selector: (state: { user: { company_id: string } }) => unknown) =>
    selector({ user: { company_id: 'company-1' } }),
}));

vi.mock('@/features/auth/hooks/usePermissions', () => ({
  usePermissions: () => ({
    can: () => false,
    isSuperAdmin: false,
  }),
}));

vi.mock('@/features/admin/services/inviteService', () => ({
  inviteService: {
    list: vi.fn().mockResolvedValue([]),
    create: vi.fn(),
  },
}));

vi.mock('@/features/admin/services/categoryAdminService', () => ({
  listCategories: vi.fn().mockResolvedValue([]),
  createCategory: vi.fn(),
}));

const wrapper = ({ children }: { children: React.ReactNode }) => {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  });

  return (
    <QueryClientProvider client={queryClient}>
      <I18nextProvider i18n={i18n}>
        <LocaleProvider>
          <ThemeProvider theme={lightTheme}>
            <MemoryRouter>{children}</MemoryRouter>
          </ThemeProvider>
        </LocaleProvider>
      </I18nextProvider>
    </QueryClientProvider>
  );
};

describe('SetupWizard critical fixes', () => {
  beforeEach(() => {
    vi.clearAllMocks();

    vi.spyOn(departmentAdminService, 'getDepartment').mockResolvedValue({
      id: 'dept-1',
      company_id: 'company-1',
      name: 'IT Support',
      code: 'IT',
      slug: 'it-support',
      portal_enabled: true,
      portal_description_en: '',
      portal_description_ar: '',
      is_active: true,
      users_count: 1,
      created_at: '',
      updated_at: '',
    });

    vi.spyOn(departmentAdminService, 'updateDepartmentPortalSettings').mockResolvedValue({
      id: 'dept-1',
      company_id: 'company-1',
      name: 'IT Support',
      code: 'IT',
      slug: 'it-support',
      portal_enabled: true,
      portal_description_en: 'Updated',
      portal_description_ar: '',
      is_active: true,
      users_count: 1,
      created_at: '',
      updated_at: '',
    });

    vi.spyOn(notificationService, 'fetchNotificationPreferences').mockResolvedValue([
      {
        id: 'pref-1',
        notification_type: 'sla_warning',
        notification_type_label: 'SLA Warning',
        channels: { in_app: true, email: true, slack: false, sms: false },
        enabled_channels: ['in_app', 'email'],
      },
      {
        id: 'pref-2',
        notification_type: 'ticket_assigned',
        notification_type_label: 'Ticket Assigned',
        channels: { in_app: true, email: false, slack: false, sms: false },
        enabled_channels: ['in_app'],
      },
    ]);

    vi.spyOn(notificationService, 'updateNotificationPreferences').mockResolvedValue(undefined);
    vi.spyOn(departmentAdminService, 'listDepartmentHeads').mockResolvedValue([]);
  });

  it('closes wizard without completing onboarding', async () => {
    render(<SetupWizard />, { wrapper });

    fireEvent.click(screen.getByRole('button', { name: 'Save and Exit Setup' }));

    await waitFor(() => {
      expect(updateStep).toHaveBeenCalledWith('portal');
    });
    expect(complete).not.toHaveBeenCalled();
  });

  it('saves portal settings via portal-settings endpoint', async () => {
    render(<SetupWizard />, { wrapper });

    fireEvent.click(screen.getByRole('button', { name: 'Save & Continue' }));

    await waitFor(() => {
      expect(departmentAdminService.updateDepartmentPortalSettings).toHaveBeenCalledWith('dept-1', {
        portal_enabled: true,
        portal_description_en: null,
        portal_description_ar: null,
      });
    });
  });

  it('shows SLA configure CTA on notifications step', async () => {
    render(<SetupWizard />, { wrapper });

    fireEvent.click(screen.getByRole('button', { name: 'Save & Continue' }));
    await waitFor(() => expect(updateStep).toHaveBeenCalled());

    fireEvent.click(screen.getByRole('button', { name: 'Continue' }));
    await waitFor(() => expect(updateStep).toHaveBeenCalledTimes(2));

    fireEvent.click(screen.getByRole('button', { name: 'Continue' }));
    await waitFor(() => expect(updateStep).toHaveBeenCalledTimes(3));

    expect(await screen.findByRole('button', { name: 'Configure SLA policies' })).toBeInTheDocument();
  });
});
