/**
 * (share/ui/input-group — addon align, label/for, focus guard, controls).
 */
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupText,
  InputGroupButton,
  InputGroupInput,
  InputGroupTextarea,
} from '@/share/ui/input-group'

jest.mock('@/share/ui/button', () => ({
  Button: ({ children, ...p }: any) => <button type="button" {...p}>{children}</button>,
}))
jest.mock('@/share/ui/input', () => ({
  Input: React.forwardRef((p: any, ref: any) => <input ref={ref} {...p} />),
}))
jest.mock('@/share/ui/textarea', () => ({ Textarea: (p: any) => <textarea {...p} /> }))
jest.mock('@/share/ui/tooltip', () => ({
  Tooltip: ({ children }: any) => <div>{children}</div>,
  TooltipContent: ({ children }: any) => <span>{children}</span>,
  TooltipProvider: ({ children }: any) => <>{children}</>,
  TooltipTrigger: ({ children }: any) => <span>{children}</span>,
}))

describe('[share/ui/input-group]', () => {
  describe('layout', () => {
    it('renders group with inline-start addon', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start">
            <InputGroupText>@</InputGroupText>
          </InputGroupAddon>
          <input placeholder="input" />
        </InputGroup>,
      )
      expect(document.querySelector('[data-slot="input-group"]')).toBeInTheDocument()
      expect(screen.getByText('@')).toBeInTheDocument()
    })

    it('supports inline-end, block-start, block-end align', () => {
      const { rerender } = render(
        <InputGroup>
          <InputGroupAddon align="inline-end">
            <InputGroupText>End</InputGroupText>
          </InputGroupAddon>
          <input />
        </InputGroup>,
      )
      expect(document.querySelector('[data-align="inline-end"]')).toBeInTheDocument()

      rerender(
        <InputGroup>
          <InputGroupAddon align="block-start">
            <InputGroupText>Block</InputGroupText>
          </InputGroupAddon>
          <input />
        </InputGroup>,
      )
      expect(document.querySelector('[data-align="block-start"]')).toBeInTheDocument()

      rerender(
        <InputGroup>
          <InputGroupAddon align="block-end">
            <InputGroupText>Block End</InputGroupText>
          </InputGroupAddon>
          <input />
        </InputGroup>,
      )
      expect(document.querySelector('[data-align="block-end"]')).toBeInTheDocument()
    })
  })

  describe('addon as label', () => {
    it('uses label + htmlFor to associate with input', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start" htmlFor="group-input">
            <InputGroupText>@</InputGroupText>
          </InputGroupAddon>
          <input id="group-input" data-testid="group-input" placeholder="input" />
        </InputGroup>,
      )
      const addon = document.querySelector('[data-slot="input-group-addon"]')
      expect(addon?.tagName).toBe('LABEL')
      expect(addon).toHaveAttribute('for', 'group-input')
    })
  })

  describe('focus guard (addon should not steal focus incorrectly)', () => {
    it('click on addon button does not focus input', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start">
            <InputGroupButton data-testid="addon-btn">Btn</InputGroupButton>
          </InputGroupAddon>
          <input data-testid="group-input" placeholder="input" />
        </InputGroup>,
      )
      fireEvent.click(screen.getByTestId('addon-btn'))
      expect(document.activeElement).not.toBe(screen.getByTestId('group-input'))
    })

    it('Enter on label-like addon does not focus input', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start" htmlFor="group-input">
            <InputGroupText>@</InputGroupText>
          </InputGroupAddon>
          <input id="group-input" data-testid="group-input" />
        </InputGroup>,
      )

      const addon = document.querySelector('[data-slot="input-group-addon"]')
      fireEvent.keyDown(addon!, { key: 'Enter' })

      expect(document.activeElement).not.toBe(screen.getByTestId('group-input'))
    })

    it('Space on label-like addon does not focus input', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start" htmlFor="group-input">
            <InputGroupText>@</InputGroupText>
          </InputGroupAddon>
          <input id="group-input" data-testid="group-input" />
        </InputGroup>,
      )

      const addon = document.querySelector('[data-slot="input-group-addon"]')
      fireEvent.keyDown(addon!, { key: ' ' })

      expect(document.activeElement).not.toBe(screen.getByTestId('group-input'))
    })

    it('Enter on nested addon button does not focus input', () => {
      render(
        <InputGroup>
          <InputGroupAddon align="inline-start">
            <InputGroupButton data-testid="addon-btn">Btn</InputGroupButton>
          </InputGroupAddon>
          <input data-testid="group-input" />
        </InputGroup>,
      )

      fireEvent.keyDown(screen.getByTestId('addon-btn'), { key: 'Enter' })

      expect(document.activeElement).not.toBe(screen.getByTestId('group-input'))
    })
  })

  describe('InputGroupButton + tooltip', () => {
    it('renders button without tooltip', () => {
      render(
        <InputGroup>
          <InputGroupAddon>
            <InputGroupButton>Action</InputGroupButton>
          </InputGroupAddon>
          <input />
        </InputGroup>,
      )
      expect(screen.getByRole('button', { name: 'Action' })).toBeInTheDocument()
    })

    it('renders tooltip content when tooltip prop set', () => {
      render(
        <InputGroup>
          <InputGroupAddon>
            <InputGroupButton tooltip="Hint">Btn</InputGroupButton>
          </InputGroupAddon>
          <input />
        </InputGroup>,
      )
      expect(screen.getByRole('button', { name: 'Btn' })).toBeInTheDocument()
      expect(screen.getByText('Hint')).toBeInTheDocument()
    })
  })

  describe('InputGroupInput / Textarea', () => {
    it('renders InputGroupInput', () => {
      render(
        <InputGroup>
          <InputGroupInput placeholder="Group input" data-testid="group-control" />
        </InputGroup>,
      )
      expect(screen.getByPlaceholderText('Group input')).toBeInTheDocument()
      expect(document.querySelector('[data-slot="input-group-control"]')).toBeInTheDocument()
    })

    it('renders InputGroupTextarea', () => {
      render(
        <InputGroup>
          <InputGroupTextarea placeholder="Textarea" data-testid="group-textarea" />
        </InputGroup>,
      )
      expect(screen.getByPlaceholderText('Textarea')).toBeInTheDocument()
    })
  })
})
