import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
import { useSession } from 'next-auth/react';

// Mock SimpleWysiwygField to avoid Lexical ESM import issues in Jest
// The WYSIWYG functionality is tested separately in sanitize-client.test.ts
jest.mock('@/lib/cms/SimpleWysiwygField', () => ({
  SimpleWysiwygField: ({ value, onChange, label, maxLength, helpText }: any) => (
    <div data-testid="simple-wysiwyg-mock">
      <label>{label}</label>
      <textarea
        value={value || ''}
        onChange={(e) => onChange(e.target.value)}
        data-testid="wysiwyg-textarea"
        maxLength={maxLength}
      />
      {helpText && <span>{helpText}</span>}
    </div>
  ),
}));

import EditorForm from '../EditorForm';

jest.mock('next-auth/react');
jest.mock('next/navigation', () => ({
  useRouter: () => ({
    push: jest.fn(),
  }),
  usePathname: () => '/dashboard/editor',
}));
jest.mock('@/lib/isr-revalidation', () => ({
  triggerISRRevalidation: jest.fn(() => Promise.resolve({ success: true })),
}));

describe('Editor Integration', () => {
  const mockInitialData = {
    dealerId: 'dealer-123',
    subdomain: 'testdealer',
    domainPrefix: 'myamsoil',
    domain: 'com',
    customDomain: null,
    subscriptionTier: 'growth', // Growth+ tier has custom domain access
    dealerNumber: '1234567',
    businessName: 'Test Business',
    contactName: 'John Doe',
    address: '123 Main St',
    city: 'Minneapolis',
    state: 'MN',
    zip: '55401',
    country: 'United States',
    phone: '(612) 555-1234',
    contactEmail: 'john@test.com',
    description: 'Test description',
    hideAddress: false,
    showContactName: false,
    logoUrl: null,
    headScripts: null,
    bodyScripts: null,
    socialLinks: null,
    preferredLanguage: 'en' as const,
    allowLanguageSwitch: true,
    amsoilLinkDomain: null,
  };

  beforeEach(() => {
    (useSession as jest.Mock).mockReturnValue({
      data: { user: { id: 'user-123', email: 'test@example.com' } },
    });
  });

  it('should render form with pre-filled data', () => {
    render(<EditorForm initialData={mockInitialData} />);

    expect(screen.getByLabelText(/Business Name/i)).toHaveValue('Test Business');
    // Use getByRole to specifically target the text input, not the checkbox
    expect(screen.getByRole('textbox', { name: /Contact Name/i })).toHaveValue('John Doe');
    expect(screen.getByLabelText(/City/i)).toHaveValue('Minneapolis');
  });

  it('should disable subdomain field', () => {
    render(<EditorForm initialData={mockInitialData} />);

    const subdomainInput = screen.getByDisplayValue('testdealer.myamsoil.com');
    expect(subdomainInput).toBeDisabled();
  });

  it('should hide custom domain field for starter tier', () => {
    const starterData = { ...mockInitialData, subscriptionTier: 'starter' };
    render(<EditorForm initialData={starterData} />);

    expect(screen.queryByLabelText(/Custom Domain/i)).not.toBeInTheDocument();
  });

  it('should show custom domain field for growth tier', () => {
    render(<EditorForm initialData={mockInitialData} />);

    expect(screen.getByLabelText(/Custom Domain/i)).toBeInTheDocument();
  });

  it('should submit form successfully', async () => {
    global.fetch = jest.fn(() =>
      Promise.resolve({
        ok: true,
        json: () => Promise.resolve({ success: true }),
      })
    ) as jest.Mock;

    render(<EditorForm initialData={mockInitialData} />);

    const businessNameInput = screen.getByLabelText(/Business Name/i);
    fireEvent.change(businessNameInput, { target: { value: 'Updated Business' } });

    const submitButton = screen.getByText('Publish');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(screen.getByText(/Published successfully!/i)).toBeInTheDocument();
    });
  });

  it('should display validation errors', async () => {
    global.fetch = jest.fn(() =>
      Promise.resolve({
        ok: false,
        json: () =>
          Promise.resolve({
            error: 'Validation failed',
            fieldErrors: { customDomain: 'Custom domain is not available' },
          }),
      })
    ) as jest.Mock;

    render(<EditorForm initialData={mockInitialData} />);

    const customDomainInput = screen.getByLabelText(/Custom Domain/i);
    await act(async () => {
      fireEvent.change(customDomainInput, { target: { value: 'existing.com' } });
    });

    const submitButton = screen.getByText('Publish');
    // Form submission re-throws errors for programmatic callers, so we catch it
    await act(async () => {
      fireEvent.click(submitButton);
      // Give state time to update
      await new Promise((r) => setTimeout(r, 0));
    });

    await waitFor(() => {
      expect(screen.getByText(/Custom domain is not available/i)).toBeInTheDocument();
    });
  });

  it('should render AMSOIL Link Destination dropdown', () => {
    render(<EditorForm initialData={mockInitialData} />);

    expect(screen.getByLabelText(/AMSOIL Link Destination/i)).toBeInTheDocument();
    expect(screen.getByText(/amsoil\.com \(United States\)/)).toBeInTheDocument();
    expect(screen.getByText(/amsoil\.ca \(Canada\)/)).toBeInTheDocument();
  });

  it('should include amsoilLinkDomain in submit payload', async () => {
    global.fetch = jest.fn(() =>
      Promise.resolve({
        ok: true,
        json: () => Promise.resolve({ success: true }),
      })
    ) as jest.Mock;

    render(<EditorForm initialData={mockInitialData} />);

    // Change the dropdown to "ca"
    const select = screen.getByLabelText(/AMSOIL Link Destination/i);
    await act(async () => {
      fireEvent.change(select, { target: { value: 'ca' } });
    });

    const submitButton = screen.getByText('Publish');
    await act(async () => {
      fireEvent.click(submitButton);
      await new Promise((r) => setTimeout(r, 0));
    });

    await waitFor(() => {
      expect(global.fetch).toHaveBeenCalledWith(
        '/api/dealer/update',
        expect.objectContaining({
          body: expect.stringContaining('"amsoilLinkDomain":"ca"'),
        })
      );
    });
  });

  it('should default to amsoil.ca for Canadian dealers', () => {
    const canadianData = { ...mockInitialData, domain: 'ca' };
    render(<EditorForm initialData={canadianData} />);

    const select = screen.getByLabelText(/AMSOIL Link Destination/i) as HTMLSelectElement;
    expect(select.value).toBe('ca');
  });
});
