import { useState } from 'react'
import {
  cleanup,
  fireEvent,
  render,
  RenderResult
} from '@testing-library/react'
import { beforeEach, describe, it, vi } from 'vitest'
import { TabGroup, Tab, TabPanel, TabGroupProps } from './index'

const defaultProps: TabGroupProps = {
  className: '',
  orientation: 'vertical',
  disabledText: 'Próximamente',
  indicatorColor: 'rgb(59, 130, 246)',
  variant: 'secondary',
  textColor: 'rgb(59, 130, 246)',
  wideLine: 3.2,
  textDisabledColor: 'rgb(209, 213, 219)'
}

const initialValue = 2

const BasicTabs = (props: TabGroupProps) => {
  const [value, setValue] = useState(initialValue)

  return (
    <div data-testid="container">
      <TabGroup
        {...props}
        role="tablist"
        aria-label="basic tabs example"
        value={value}
        onChange={setValue}
      >
        <Tab label="Precio y absorción" />
        <Tab data-testid="disabled" label="Competencia" disabled />
        <Tab label="Insights de mercado históricos" />
      </TabGroup>
      <TabPanel value={value} index={0}>
        <p>Item one</p>
      </TabPanel>
      <TabPanel value={value} index={1}>
        <p>Item Two</p>
      </TabPanel>
      <TabPanel value={value} index={2}>
        <p>Item Three</p>
      </TabPanel>
    </div>
  )
}

window.HTMLElement.prototype.scrollIntoView = vi.fn()

describe('<TabGroup /> variant="primary ', () => {
  it('Indication bar is renderer: orientation="horizontal"', () => {
    const props: TabGroupProps = {
      ...defaultProps,
      orientation: 'horizontal',
      variant: 'primary',
      wideLine: 3.5
    }
    const result = render(<BasicTabs {...props} />)
    const indicationBar = result.getByRole('indication-bar')

    expect(indicationBar).toBeDefined()
    expect(indicationBar.style.height).toBe('3.5px')
    expect(indicationBar.style.backgroundColor).toBe(
      defaultProps.indicatorColor
    )
  })

  it('Indication bar orientation="vertical"', () => {
    const props: TabGroupProps = {
      ...defaultProps,
      variant: 'primary',
      indicatorColor: 'bg-purple-500',
      wideLine: 3.5
    }
    const result = render(<BasicTabs {...props} />)
    const indicationBar = result.getByRole('indication-bar')

    expect(indicationBar).toBeDefined()
    expect(indicationBar.style.right).toBe('1px')
    expect(indicationBar.style.width).toBe('3.5px')
    expect(indicationBar.className).toContain('bg-purple-500')
  })

  it('<Tab /> was renderer: orientation="vertical"', () => {
    const props: TabGroupProps = {
      ...defaultProps,
      variant: 'primary',
      orientation: 'horizontal',
      textColor: 'rgb(89, 22, 201)'
    }
    const result = render(<BasicTabs {...props} />)
    const currentTab = result.getAllByRole('tab')[initialValue]

    expect(currentTab.style.color).toEqual('rgb(89, 22, 201)')
    expect(currentTab.className).toContain('font-bold')
    expect(currentTab.getAttribute('disabled')).toEqual(null)
    expect(result.getByRole('contentinfo')).toBeDefined()
    expect(result.getByRole('contentinfo').textContent).toEqual(
      defaultProps.disabledText
    )
  })
})

describe('<TabGroup /> variant="secondary"', () => {
  it('<TabGroup /> validation className and props', () => {
    const props: TabGroupProps = { ...defaultProps }
    const result = render(<BasicTabs {...props} />)
    const tabContainer = result.getByRole('tablist')

    expect(tabContainer).toBeDefined()
    expect(tabContainer.className).toContain('gap-4')
    expect(tabContainer.className).toContain('flex-col')
    expect(tabContainer.className).not.toContain('border')
  })

  it('<Tab /> validation className and props', () => {
    const result = render(<BasicTabs {...defaultProps} />)
    const currentTab = result.getAllByRole('tab')[initialValue]
    const disabledTab = result.getByTestId('disabled')

    expect(currentTab.className).toContain('rounded')
    expect(currentTab.className).toContain('border-blue-500')
    expect(currentTab.className).toContain('text-blue-500')
    expect(disabledTab.style.color).toContain('rgb(209, 213, 219)')
    expect(disabledTab.className).toContain('font-semibold')
  })
})

describe('<TabGroup /> variant="tertiary"', () => {
  it('<TabGroup /> validation className and props', () => {
    const props: TabGroupProps = {
      ...defaultProps,
      variant: 'tertiary',
      textColor: 'rgb(89, 22, 201)'
    }
    const result = render(<BasicTabs {...props} />)
    const tabContainer = result.getByRole('tablist')

    expect(tabContainer).toBeDefined()
    expect(tabContainer.className).toContain('flex-col')
    expect(tabContainer.className).not.toContain('border')
  })

  it('<Tab /> validation className and props', () => {
    const props: TabGroupProps = {
      ...defaultProps,
      disabledText: 'rgb(209, 213, 219)',
      variant: 'tertiary',
      textColor: 'rgb(89, 22, 201)',
      tabMinWidth: 120,
      tabWidth: 150
    }
    const result = render(<BasicTabs {...props} />)
    const currentTab = result.getAllByRole('tab')[initialValue]
    const disabledTab = result.getByTestId('disabled')

    expect(currentTab.style.color).toContain('rgb(89, 22, 201)')
    expect(disabledTab.style.color).toContain('rgb(209, 213, 219)')
    expect(disabledTab.className).toContain('font-semibold')
    expect(disabledTab.style.minWidth).toContain('120px')
  })
})

describe('<TabGroup /> navigation between elements', () => {
  let renderResult: RenderResult

  beforeEach(() => {
    renderResult = render(<BasicTabs />)
  })

  afterEach(() => {
    cleanup()
  })

  it('navigates to the component that was clicked', () => {
    const tabs = renderResult.getAllByRole('tab')
    expect(tabs[0].className).toContain('font-semibold')
    expect(tabs[0].className).toContain('text-info')
    fireEvent.click(tabs[0])
    expect(tabs[0].className).not.toContain('text-info')
    expect(tabs[0].className).toContain('font-bold')
  })

  it('validation container was render data', () => {
    expect(renderResult.getByTestId('container').children.length).toEqual(2)
    expect(renderResult.getByText('Item Three')).toBeDefined()

    const tabs = renderResult.getAllByRole('tab')
    fireEvent.click(tabs[1])

    expect(renderResult.getByTestId('container').children.length).toEqual(2)
    expect(renderResult.getByText('Item Three')).toBeDefined()

    fireEvent.click(tabs[0])
    expect(renderResult.getByTestId('container').children.length).toEqual(2)
    expect(renderResult.getByText('Item one')).toBeDefined()
  })
})
