import { describe, test, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { WrapperUI } from './wrapper-ui'
import { useWidgetStore } from '../stores/widget-store'
import type { WrapperState } from './types'

describe('WrapperUI', () => {
  const widgetId = 'test-wrapper-ui'

  const defaultProps = {
    id: widgetId,
    children: <div>Test Content</div>,
  }

  beforeEach(() => {
    useWidgetStore.getState().clearWidgets()
    // Pre-set the widget in the store with default values
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      title: 'Wrapper Widget',
      collapsed: false,
      disabled: false,
      isFetching: false,
    })
  })

  test('renders correctly with default props', () => {
    render(<WrapperUI {...defaultProps} />)
    expect(screen.getByText('Test Content')).toBeTruthy()
    expect(screen.getByText('Wrapper Widget')).toBeTruthy()
  })

  test('renders with custom title from store', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      title: 'Custom Title',
    })
    render(<WrapperUI {...defaultProps} />)
    expect(screen.getByText('Custom Title')).toBeTruthy()
  })

  test('renders in expanded state by default', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      collapsed: false,
    })
    render(<WrapperUI {...defaultProps} />)
    const accordion = screen.getByRole('region')
    expect(accordion).toBeTruthy()
  })

  test('renders in collapsed state', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      collapsed: true,
    })
    render(<WrapperUI {...defaultProps} />)
    // When collapsed, AccordionDetails is not visible
    const accordion = screen.getByRole('button')
    expect(accordion).toBeTruthy()
  })

  test('renders loading indicator when isFetching is true', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      isFetching: true,
    })
    render(<WrapperUI {...defaultProps} />)
    const progressBar = screen.getByRole('progressbar')
    expect(progressBar).toBeTruthy()
  })

  test('does not render loading indicator when isFetching is false', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      isFetching: false,
    })
    render(<WrapperUI {...defaultProps} />)
    const progressBar = screen.queryByRole('progressbar')
    expect(progressBar).toBeNull()
  })

  test('renders actions when provided and not collapsed', () => {
    const actions = [
      <button key='action1'>Action 1</button>,
      <button key='action2'>Action 2</button>,
    ]
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      collapsed: false,
    })
    render(<WrapperUI {...defaultProps} actions={actions} />)
    expect(screen.getByText('Action 1')).toBeTruthy()
    expect(screen.getByText('Action 2')).toBeTruthy()
  })

  test('renders actions even when collapsed', () => {
    const actions = [<button key='action1'>Action 1</button>]
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      collapsed: true,
    })
    render(<WrapperUI {...defaultProps} actions={actions} />)
    // Actions are rendered in the AccordionSummary which is always visible
    expect(screen.getByText('Action 1')).toBeTruthy()
  })

  test('does not render actions when array is empty', () => {
    render(<WrapperUI {...defaultProps} actions={[]} />)
    // No actions should be rendered
    expect(screen.getByText('Test Content')).toBeTruthy()
  })

  test('renders options when provided', () => {
    const options = [
      {
        label: 'Option 1',
        onClick: vi.fn(),
      },
    ]
    render(<WrapperUI {...defaultProps} options={options} />)
    const optionsButton = screen.getByLabelText('Options')
    expect(optionsButton).toBeTruthy()
  })

  test('renders options with custom label', () => {
    const options = [
      {
        label: 'Option 1',
        onClick: vi.fn(),
      },
    ]
    const labels = {
      options: {
        title: 'Custom Options Label',
      },
    }
    render(<WrapperUI {...defaultProps} options={options} labels={labels} />)
    const optionsButton = screen.getByLabelText('Custom Options Label')
    expect(optionsButton).toBeTruthy()
  })

  test('does not render options when array is empty', () => {
    render(<WrapperUI {...defaultProps} options={[]} />)
    const optionsButton = screen.queryByLabelText('Options')
    expect(optionsButton).toBeNull()
  })

  test('handles onChangeCollapsed callback', () => {
    const onChangeCollapsed = vi.fn()
    render(
      <WrapperUI {...defaultProps} onChangeCollapsed={onChangeCollapsed} />,
    )

    const accordion = screen.getByRole('button')
    fireEvent.click(accordion)

    expect(onChangeCollapsed).toHaveBeenCalledTimes(1)
  })

  test('renders disabled state', () => {
    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      disabled: true,
    })
    render(<WrapperUI {...defaultProps} />)
    const accordion = screen.getByRole('button')
    expect(accordion.classList.contains('Mui-disabled')).toBe(true)
  })

  test('applies custom sx styles', () => {
    const sx = { backgroundColor: 'red' }
    render(<WrapperUI {...defaultProps} sx={sx} />)
    // Component should render (we can't easily test sx application without jest-dom)
    expect(screen.getByText('Test Content')).toBeTruthy()
  })

  test('renders children correctly', () => {
    render(
      <WrapperUI {...defaultProps}>
        <div>Child 1</div>
        <div>Child 2</div>
      </WrapperUI>,
    )
    expect(screen.getByText('Child 1')).toBeTruthy()
    expect(screen.getByText('Child 2')).toBeTruthy()
  })

  test('renders with all props combined', () => {
    const actions = [<button key='action1'>Action 1</button>]
    const options = [
      {
        label: 'Option 1',
        onClick: vi.fn(),
      },
    ]
    const labels = {
      options: {
        title: 'Custom Options',
      },
    }
    const onChangeCollapsed = vi.fn()

    useWidgetStore.getState().setWidget<WrapperState>(widgetId, {
      title: 'Full Test',
      collapsed: false,
      disabled: false,
      isFetching: true,
    })

    render(
      <WrapperUI
        {...defaultProps}
        actions={actions}
        options={options}
        labels={labels}
        sx={{ margin: 2 }}
        onChangeCollapsed={onChangeCollapsed}
      />,
    )

    expect(screen.getByText('Full Test')).toBeTruthy()
    expect(screen.getByText('Action 1')).toBeTruthy()
    expect(screen.getByLabelText('Custom Options')).toBeTruthy()
    expect(screen.getByRole('progressbar')).toBeTruthy()
    expect(screen.getByText('Test Content')).toBeTruthy()
  })

  test('handles collapse toggle multiple times', () => {
    const onChangeCollapsed = vi.fn()
    render(
      <WrapperUI {...defaultProps} onChangeCollapsed={onChangeCollapsed} />,
    )

    const accordion = screen.getByRole('button')
    fireEvent.click(accordion)
    fireEvent.click(accordion)

    expect(onChangeCollapsed).toHaveBeenCalledTimes(2)
  })
})
