import React from 'react';
import { Text, View } from 'react-native';
import { render, fireEvent } from '@testing-library/react-native';
import {
  ScreenLoading,
  RefreshableScreen,
  EmptyState,
  LoadingButtonState,
} from '@/components/ui/ScreenLoading';

describe('ScreenLoading', () => {
  it('renders children when not loading and no error', () => {
    const { getByText } = render(
      <ScreenLoading isLoading={false} error={null}>
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(getByText('Content')).toBeTruthy();
  });

  it('renders loading state when isLoading is true', () => {
    const { getByText } = render(
      <ScreenLoading isLoading={true} error={null}>
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(getByText('Loading...')).toBeTruthy();
  });

  it('renders custom loading message', () => {
    const { getByText } = render(
      <ScreenLoading
        isLoading={true}
        error={null}
        loadingMessage="Fetching data..."
      >
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(getByText('Fetching data...')).toBeTruthy();
  });

  it('renders error state when error is provided', () => {
    const { getByText } = render(
      <ScreenLoading isLoading={false} error="Network error">
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(getByText('Something went wrong')).toBeTruthy();
    expect(getByText('Network error')).toBeTruthy();
  });

  it('renders retry button when onRetry is provided', () => {
    const onRetry = jest.fn();
    const { getByText } = render(
      <ScreenLoading isLoading={false} error="Error" onRetry={onRetry}>
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(getByText('Try Again')).toBeTruthy();
  });

  it('calls onRetry when retry button is pressed', () => {
    const onRetry = jest.fn();
    const { getByText } = render(
      <ScreenLoading isLoading={false} error="Error" onRetry={onRetry}>
        <Text>Content</Text>
      </ScreenLoading>
    );
    fireEvent.press(getByText('Try Again'));
    expect(onRetry).toHaveBeenCalledTimes(1);
  });

  it('does not render retry button when onRetry is not provided', () => {
    const { queryByText } = render(
      <ScreenLoading isLoading={false} error="Error">
        <Text>Content</Text>
      </ScreenLoading>
    );
    expect(queryByText('Try Again')).toBeNull();
  });
});

describe('RefreshableScreen', () => {
  it('renders children', () => {
    const onRefresh = jest.fn();
    const { getByText } = render(
      <RefreshableScreen isRefreshing={false} onRefresh={onRefresh}>
        <Text>Content</Text>
      </RefreshableScreen>
    );
    expect(getByText('Content')).toBeTruthy();
  });
});

describe('EmptyState', () => {
  it('renders title and description', () => {
    const { getByText } = render(
      <EmptyState
        title="No items"
        description="Add some items to get started"
      />
    );
    expect(getByText('No items')).toBeTruthy();
    expect(getByText('Add some items to get started')).toBeTruthy();
  });

  it('renders action button when provided', () => {
    const onAction = jest.fn();
    const { getByText } = render(
      <EmptyState
        title="No items"
        actionLabel="Add Item"
        onAction={onAction}
      />
    );
    expect(getByText('Add Item')).toBeTruthy();
  });

  it('calls onAction when action button is pressed', () => {
    const onAction = jest.fn();
    const { getByText } = render(
      <EmptyState
        title="No items"
        actionLabel="Add Item"
        onAction={onAction}
      />
    );
    fireEvent.press(getByText('Add Item'));
    expect(onAction).toHaveBeenCalledTimes(1);
  });

  it('does not render action button when onAction is not provided', () => {
    const { queryByText } = render(
      <EmptyState title="No items" actionLabel="Add Item" />
    );
    expect(queryByText('Add Item')).toBeNull();
  });
});

describe('LoadingButtonState', () => {
  it('renders children when not loading', () => {
    const { getByText } = render(
      <LoadingButtonState isLoading={false}>
        <Text>Submit</Text>
      </LoadingButtonState>
    );
    expect(getByText('Submit')).toBeTruthy();
  });

  it('renders loading state when isLoading is true', () => {
    const { getByText } = render(
      <LoadingButtonState isLoading={true}>
        <Text>Submit</Text>
      </LoadingButtonState>
    );
    expect(getByText('Loading...')).toBeTruthy();
  });

  it('renders custom loading text', () => {
    const { getByText } = render(
      <LoadingButtonState isLoading={true} loadingText="Saving...">
        <Text>Submit</Text>
      </LoadingButtonState>
    );
    expect(getByText('Saving...')).toBeTruthy();
  });
});
