import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import GeneralSettings from '../GeneralSettings';

// Mock react-i18next
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, defaultValue?: string) => defaultValue || key,
  }),
}));

// Mock react-router-dom hooks
const mockOutletContext = vi.fn();
const mockUpdateBusiness = vi.fn();

vi.mock('react-router-dom', async () => {
  const actual = await vi.importActual('react-router-dom');
  return {
    ...actual,
    useOutletContext: () => mockOutletContext(),
  };
});

describe('GeneralSettings', () => {
  const ownerContext = {
    user: { id: '1', role: 'owner', email: 'owner@test.com' },
    business: {
      id: '1',
      name: 'Test Business',
      subdomain: 'test-business',
      contactEmail: 'contact@test.com',
      phone: '+1234567890',
      timezone: 'America/New_York',
      timezoneDisplayMode: 'business',
    },
    updateBusiness: mockUpdateBusiness,
  };

  const staffContext = {
    ...ownerContext,
    user: { id: '2', role: 'staff', email: 'staff@test.com' },
  };

  beforeEach(() => {
    vi.clearAllMocks();
    mockUpdateBusiness.mockResolvedValue(undefined);
  });

  it('renders the title for owner', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('General Settings')).toBeInTheDocument();
  });

  it('renders the subtitle for owner', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Manage your business identity and contact information.')).toBeInTheDocument();
  });

  it('shows owner only message for non-owner', () => {
    mockOutletContext.mockReturnValue(staffContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Only the business owner can access these settings.')).toBeInTheDocument();
  });

  it('renders business name input', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByDisplayValue('Test Business')).toBeInTheDocument();
  });

  it('renders subdomain input as readonly', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    const subdomainInput = screen.getByDisplayValue('test-business');
    expect(subdomainInput).toHaveAttribute('readonly');
  });

  it('renders contact email input', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByDisplayValue('contact@test.com')).toBeInTheDocument();
  });

  it('renders phone input', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByDisplayValue('+1234567890')).toBeInTheDocument();
  });

  it('renders timezone select', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByDisplayValue('America/New_York')).toBeInTheDocument();
  });

  it('renders timezone display mode select', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    // There are multiple "Business Timezone" elements (label and option)
    const elements = screen.getAllByText('Business Timezone');
    expect(elements.length).toBeGreaterThanOrEqual(1);
  });

  it('renders save button', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Save Changes')).toBeInTheDocument();
  });

  it('updates business name on input change', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    const input = screen.getByDisplayValue('Test Business');
    fireEvent.change(input, { target: { value: 'New Business Name', name: 'name' } });
    expect(screen.getByDisplayValue('New Business Name')).toBeInTheDocument();
  });

  it('calls updateBusiness on save', async () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    fireEvent.click(screen.getByText('Save Changes'));
    await waitFor(() => {
      expect(mockUpdateBusiness).toHaveBeenCalled();
    });
  });

  it('shows toast after saving', async () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    fireEvent.click(screen.getByText('Save Changes'));
    // Toast should appear after save completes
    await waitFor(() => {
      expect(screen.getByText('Changes saved successfully')).toBeInTheDocument();
    });
  });

  it('renders business identity section', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Business Identity')).toBeInTheDocument();
  });

  it('renders timezone settings section', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Timezone Settings')).toBeInTheDocument();
  });

  it('renders contact information section', () => {
    mockOutletContext.mockReturnValue(ownerContext);
    render(
      <MemoryRouter>
        <GeneralSettings />
      </MemoryRouter>
    );
    expect(screen.getByText('Contact Information')).toBeInTheDocument();
  });
});
