import { describe, it, expect } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import React from 'react'
import FormBuilderPanel from '@/components/FormBuilderPanel'
import { createFormStore } from '@/lib/state/formStore'
import type { SelectField, RadioField } from '@/lib/state/formStore'
import { NextIntlClientProvider } from 'next-intl'
import enMessages from '@/messages/en.json'
const messages: Record<string, string> = enMessages as Record<string, string>

describe('FormBuilderPanel', () => {
  it('필드 추가와 action URL/스팸 옵션 변경을 수행한다', () => {
    const store = createFormStore()
    render(
      <NextIntlClientProvider locale="en" messages={messages}>
        <FormBuilderPanel store={store} />
      </NextIntlClientProvider>
    )

    // 초기 상태
    expect(screen.queryAllByTestId('field-item').length).toBe(0)

    // 필드 추가 2개 (번역 키 이슈 회피: 첫 번째 버튼 클릭)
    fireEvent.click(screen.getAllByRole('button')[0])
    fireEvent.click(screen.getAllByRole('button')[0])
    expect(screen.queryAllByTestId('field-item').length).toBe(2)

    // action URL 입력
    const actionInput = screen.getByLabelText('Action URL') as HTMLInputElement
    fireEvent.change(actionInput, { target: { value: 'https://example.com/form' } })
    expect(actionInput.value).toBe('https://example.com/form')
    expect(store.getState().actionUrl).toBe('https://example.com/form')

    // 스팸 옵션 - honeypot 변경
    const hpInput = screen.getByLabelText('Honeypot Field') as HTMLInputElement
    fireEvent.change(hpInput, { target: { value: '_trap' } })
    expect(store.getState().spam.honeypotFieldName).toBe('_trap')

    // 스팸 옵션 - min seconds 변경
    const tsInput = screen.getByLabelText('Min Submit Seconds') as HTMLInputElement
    fireEvent.change(tsInput, { target: { value: '5' } })
    expect(store.getState().spam.minSubmitSeconds).toBe(5)
  })

  it('pattern과 maxLength 편집이 상태에 반영된다', () => {
    const store = createFormStore()
    render(
      <NextIntlClientProvider locale="en" messages={messages}>
        <FormBuilderPanel store={store} />
      </NextIntlClientProvider>
    )

    // 텍스트 필드 1개 추가
    fireEvent.click(screen.getAllByRole('button')[0])

    const pat0 = screen.getByLabelText('Pattern 0') as HTMLInputElement
    fireEvent.change(pat0, { target: { value: '^[A-Za-z ]+$' } })
    expect(store.getState().fields[0].pattern).toBe('^[A-Za-z ]+$')

    const max0 = screen.getByLabelText('MaxLength 0') as HTMLInputElement
    fireEvent.change(max0, { target: { value: '50' } })
    expect(store.getState().fields[0].maxLength).toBe(50)
  })

  it('select/radio 옵션 편집이 동작하고 추가 버튼으로 타입별 필드를 만든다', () => {
    const store = createFormStore()
    render(
      <NextIntlClientProvider locale="en" messages={messages}>
        <FormBuilderPanel store={store} />
      </NextIntlClientProvider>
    )

    // select 추가 후 옵션 편집 (버튼 인덱스로 접근)
    const buttons1 = screen.getAllByRole('button')
    // 버튼 순서: Text, Email, Tel, Date, Textarea, Checkbox, Select, Radio
    fireEvent.click(buttons1[6])
    const opts0 = screen.getByLabelText('Options 0') as HTMLInputElement
    fireEvent.change(opts0, { target: { value: 'A,B,C' } })
    expect(store.getState().fields[0].type).toBe('select')
    expect((store.getState().fields[0] as SelectField).options).toEqual(['A','B','C'])

    // radio 추가 후 옵션 편집
    const buttons2 = screen.getAllByRole('button')
    fireEvent.click(buttons2[7])
    const opts1 = screen.getByLabelText('Options 1') as HTMLInputElement
    fireEvent.change(opts1, { target: { value: 'S,M,L' } })
    expect(store.getState().fields[1].type).toBe('radio')
    expect((store.getState().fields[1] as RadioField).options).toEqual(['S','M','L'])

    // email/checkbox/textarea/date/tel도 추가 버튼 존재 (인덱스 기반 클릭)
    const buttons3 = screen.getAllByRole('button')
    fireEvent.click(buttons3[1]) // Email
    fireEvent.click(buttons3[5]) // Checkbox
    fireEvent.click(buttons3[4]) // Textarea
    fireEvent.click(buttons3[3]) // Date
    fireEvent.click(buttons3[2]) // Tel

    const names = store.getState().fields.map((f) => f.type)
    expect(names).toContain('email')
    expect(names).toContain('checkbox')
    expect(names).toContain('textarea')
    expect(names).toContain('date')
    expect(names).toContain('tel')
  })

  it('필드 레이블/필수 편집, 이동/삭제가 동작한다', () => {
    const store = createFormStore()
    render(
      <NextIntlClientProvider locale="en" messages={messages}>
        <FormBuilderPanel store={store} />
      </NextIntlClientProvider>
    )

    // 3개 추가
    fireEvent.click(screen.getAllByRole('button')[0])
    fireEvent.click(screen.getAllByRole('button')[0])
    fireEvent.click(screen.getAllByRole('button')[0])
    expect(screen.queryAllByTestId('field-item').length).toBe(3)

    // 첫 필드 레이블 변경
    const label0 = screen.getByLabelText('Label 0') as HTMLInputElement
    fireEvent.change(label0, { target: { value: 'Name' } })
    expect(store.getState().fields[0].label).toBe('Name')

    // 첫 필드 required 토글
    const req0 = screen.getByLabelText('Required 0') as HTMLInputElement
    fireEvent.click(req0)
    expect(store.getState().fields[0].required).toBe(true)

    // 첫 필드를 아래로 이동 (0 -> 1)
    fireEvent.click(screen.getByRole('button', { name: 'Down 0' }))
    expect(store.getState().fields.map(f => f.name)).toEqual(['field2','field1','field3'])

    // 두 번째(이전 첫) 필드 삭제
    fireEvent.click(screen.getByRole('button', { name: 'Remove 1' }))
    expect(store.getState().fields.map(f => f.name)).toEqual(['field2','field3'])
  })
})
