import { describe, test, expect, beforeEach } from 'vitest'
import { render, screen, fireEvent, within } from '@testing-library/react'
import { FullScreen } from './fullscreen'
import { useWidgetStore } from '../../stores/widget-store'
import type { FullScreenState } from './types'

describe('FullScreen', () => {
  const widgetId = 'test-widget'

  beforeEach(() => {
    // Clear store before each test
    useWidgetStore.getState().clearWidgets()
    // Initialize widget with title
    useWidgetStore.getState().setWidget<FullScreenState>(widgetId, {
      title: 'Test Widget',
    })
  })

  test('renders fullscreen button', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

    const button = screen.getByRole('button')
    expect(button).toBeTruthy()
  })

  test('opens dialog when fullscreen button is clicked', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

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

    // Check if dialog is opened
    expect(screen.getByText('Test Widget')).toBeTruthy()
    expect(screen.getByText('Widget Content')).toBeTruthy()
  })

  test('closes dialog when close button is clicked', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

    // Open dialog
    const openButton = screen.getByRole('button')
    fireEvent.click(openButton)

    // Find and click close button (inside the dialog)
    const dialog = screen.getByRole('dialog')
    const closeButton = within(dialog).getAllByRole('button')[0]

    fireEvent.click(closeButton!)

    // Store should be updated
    const widget = useWidgetStore
      .getState()
      .getWidget<FullScreenState>(widgetId)
    expect(widget?.isFullScreen).toBe(false)
  })

  test('uses custom aria label when provided', () => {
    const customLabels = {
      ariaLabel: 'custom-fullscreen-dialog',
    }

    render(
      <FullScreen id={widgetId} labels={customLabels}>
        <div>Widget Content</div>
      </FullScreen>,
    )

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

    const dialog = screen.getByRole('dialog')
    expect(dialog.getAttribute('aria-labelledby')).toBe(
      'custom-fullscreen-dialog',
    )
  })

  test('uses default aria label when not provided', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

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

    const dialog = screen.getByRole('dialog')
    expect(dialog.getAttribute('aria-labelledby')).toBe(
      `fullscreen-dialog-title-${widgetId}`,
    )
  })

  test('renders children inside dialog content', () => {
    const TestChild = () => (
      <div>
        <p>First paragraph</p>
        <p>Second paragraph</p>
      </div>
    )

    render(
      <FullScreen id={widgetId}>
        <TestChild />
      </FullScreen>,
    )

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

    expect(screen.getByText('First paragraph')).toBeTruthy()
    expect(screen.getByText('Second paragraph')).toBeTruthy()
  })

  test('dialog is not visible initially', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

    // Dialog should not be rendered until button is clicked
    expect(screen.queryByRole('dialog')).toBeNull()
  })

  test('updates widget store when opening fullscreen', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

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

    const widget = useWidgetStore
      .getState()
      .getWidget<FullScreenState>(widgetId)
    expect(widget?.isFullScreen).toBe(true)
  })

  test('updates widget store when closing fullscreen', () => {
    // Pre-set the widget to fullscreen
    useWidgetStore.getState().setWidget<FullScreenState>(widgetId, {
      title: 'Test Widget',
      isFullScreen: true,
    })

    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

    // Find and click close button
    const dialog = screen.getByRole('dialog')
    const closeButton = within(dialog).getAllByRole('button')[0]

    fireEvent.click(closeButton!)

    const widget = useWidgetStore
      .getState()
      .getWidget<FullScreenState>(widgetId)
    expect(widget?.isFullScreen).toBe(false)
  })

  test('handles multiple fullscreen widgets independently', () => {
    const widget1Id = 'widget-1'
    const widget2Id = 'widget-2'

    // Initialize both widgets with titles
    useWidgetStore.getState().setWidget<FullScreenState>(widget1Id, {
      title: 'Widget 1',
    })
    useWidgetStore.getState().setWidget<FullScreenState>(widget2Id, {
      title: 'Widget 2',
    })

    render(
      <>
        <FullScreen id={widget1Id}>
          <div>Content 1</div>
        </FullScreen>
        <FullScreen id={widget2Id}>
          <div>Content 2</div>
        </FullScreen>
      </>,
    )

    const buttons = screen.getAllByRole('button')

    // Open first widget
    fireEvent.click(buttons[0]!)
    let widget1 = useWidgetStore
      .getState()
      .getWidget<FullScreenState>(widget1Id)
    let widget2 = useWidgetStore
      .getState()
      .getWidget<FullScreenState>(widget2Id)

    expect(widget1?.isFullScreen).toBe(true)
    expect(widget2?.isFullScreen).toBeUndefined()

    // Verify widget 1 content is displayed
    expect(screen.getByText('Content 1')).toBeTruthy()

    // Close first widget via store (simpler than clicking)
    useWidgetStore.getState().setWidget<FullScreenState>(widget1Id, {
      title: 'Widget 1',
      isFullScreen: false,
    })

    // Open second widget
    fireEvent.click(buttons[1]!)

    widget1 = useWidgetStore.getState().getWidget<FullScreenState>(widget1Id)
    widget2 = useWidgetStore.getState().getWidget<FullScreenState>(widget2Id)

    expect(widget1?.isFullScreen).toBe(false)
    expect(widget2?.isFullScreen).toBe(true)

    // Verify widget 2 content is displayed
    expect(screen.getByText('Content 2')).toBeTruthy()
  })

  test('renders dialog title with correct typography', () => {
    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

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

    const title = screen.getByText('Test Widget')
    expect(title).toBeTruthy()
    expect(title.tagName).toBe('SPAN')
  })

  test('dialog respects isFullScreen state from store', () => {
    // Set initial state to fullscreen
    useWidgetStore.getState().setWidget<FullScreenState>(widgetId, {
      title: 'Test Widget',
      isFullScreen: true,
    })

    render(
      <FullScreen id={widgetId}>
        <div>Widget Content</div>
      </FullScreen>,
    )

    // Dialog should be visible immediately
    expect(screen.getByRole('dialog')).toBeTruthy()
    expect(screen.getByText('Widget Content')).toBeTruthy()
  })
})
