// @vitest-environment jsdom
// Covers WIZD-01: card grid renders Azure Blob, Amazon S3, S3-Compatible (Azure first)
// Covers WIZD-04: remote name field validates alphanumeric/dash/underscore
import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { WizardProvider } from '../../store/context';
import { BackendSelectionStep } from './BackendSelectionStep';

function renderStep() {
  return render(
    <WizardProvider>
      <BackendSelectionStep />
    </WizardProvider>
  );
}

describe('BackendSelectionStep', () => {
  describe('WIZD-01: backend card grid', () => {
    it('renders Azure Blob Storage card', () => {
      renderStep();
      expect(screen.getByText('Azure Blob Storage')).toBeDefined();
    });

    it('renders Amazon S3 card', () => {
      renderStep();
      expect(screen.getByText('Amazon S3')).toBeDefined();
    });

    it('renders S3-Compatible card', () => {
      renderStep();
      expect(screen.getByText('S3-Compatible')).toBeDefined();
    });

    it('Azure Blob is listed before S3 in DOM order', () => {
      renderStep();
      const buttons = screen.getAllByRole('button');
      // Find Azure and S3 buttons by their accessible names
      const azureIdx = buttons.findIndex(b => b.textContent?.includes('Azure Blob Storage'));
      const s3Idx = buttons.findIndex(b => b.textContent?.includes('Amazon S3'));
      expect(azureIdx).toBeGreaterThanOrEqual(0);
      expect(s3Idx).toBeGreaterThanOrEqual(0);
      expect(azureIdx).toBeLessThan(s3Idx);
    });

    it('clicking a backend card dispatches SET_BACKEND_TYPE and SET_STEP', () => {
      renderStep();
      // Fill in a valid remote name first
      const nameInput = screen.getByRole('textbox');
      fireEvent.change(nameInput, { target: { value: 'my-remote' } });
      // Click the Azure card — if navigation dispatches SET_STEP(1), component may unmount
      // We verify no validation error appears (meaning dispatch proceeded)
      const azureButton = screen.getAllByRole('button').find(b => b.textContent?.includes('Azure Blob Storage'))!;
      expect(azureButton).toBeDefined();
      fireEvent.click(azureButton);
      // After successful navigation step fires, no validation alert should be present
      expect(screen.queryByRole('alert')).toBeNull();
    });
  });

  describe('WIZD-04: remote name field', () => {
    it('renders remote name input at the top of the step', () => {
      renderStep();
      const nameInput = screen.getByRole('textbox');
      expect(nameInput).toBeDefined();
      // Verify input appears before backend cards in DOM
      const container = nameInput.closest('form') ?? document.body;
      const allButtons = container.querySelectorAll('button');
      const inputPosition = Array.from(container.querySelectorAll('input, button')).indexOf(nameInput as HTMLInputElement);
      const firstButtonPosition = Array.from(container.querySelectorAll('input, button')).indexOf(allButtons[0]);
      expect(inputPosition).toBeLessThan(firstButtonPosition);
    });

    it('shows no error before first Next attempt', () => {
      renderStep();
      // No alert role should be present on initial render
      expect(screen.queryByRole('alert')).toBeNull();
    });

    it('shows inline error after first Next attempt with invalid name', async () => {
      renderStep();
      // Click a card without filling in name — triggers validation
      const azureButton = screen.getAllByRole('button').find(b => b.textContent?.includes('Azure Blob Storage'))!;
      fireEvent.click(azureButton);
      // Error should appear after async validation
      await waitFor(() => {
        expect(screen.getByRole('alert')).toBeDefined();
        expect(screen.getByText(/required/i)).toBeDefined();
      });
    });

    it('accepts alphanumeric, dashes, and underscores', async () => {
      renderStep();
      const nameInput = screen.getByRole('textbox');
      fireEvent.change(nameInput, { target: { value: 'my-remote_01' } });
      const azureButton = screen.getAllByRole('button').find(b => b.textContent?.includes('Azure Blob Storage'))!;
      fireEvent.click(azureButton);
      // Valid name — no alert should appear (wait briefly to confirm no error appears)
      await waitFor(() => {
        expect(screen.queryByRole('alert')).toBeNull();
      });
    });

    it('rejects names with spaces or special characters', async () => {
      renderStep();
      const nameInput = screen.getByRole('textbox');
      fireEvent.change(nameInput, { target: { value: 'my remote!' } });
      const azureButton = screen.getAllByRole('button').find(b => b.textContent?.includes('Azure Blob Storage'))!;
      fireEvent.click(azureButton);
      // Invalid name — alert should appear after async validation
      await waitFor(() => {
        expect(screen.getByRole('alert')).toBeDefined();
        expect(screen.getByText(/letters, numbers, dashes/i)).toBeDefined();
      });
    });
  });
});
