import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { createI18n } from 'vue-i18n'

import ReservationTaskFieldRenderer from '@/components/reservation/ReservationTaskFieldRenderer.vue'
import zhCN from '@/i18n/locales/zh-CN'
import type { ReservationTaskFieldResult } from '@/types/reservation'

const fields: ReservationTaskFieldResult[] = [
  {
    row_number: 1,
    card_name: 'New Booking',
    display_area: '客人信息',
    field_path: 'guest.name',
    display_name: '客人姓名',
    visible: 'Y',
    editable: 'Y',
    input_editable: 'Y',
    select_editable: 'N',
    date_picker: 'N',
    number_input: 'N',
    file_display: 'N',
    table_editable: 'N',
    enum_options: null,
    required_rule: 'Y',
    display_condition: null,
    validation_rule: null,
    write_path: 'reservation.guest.name',
    opera_write_participation: 'Y',
    opera_parameter_mapping: 'profile.name',
    notes: null,
    value: '王建国',
  },
  {
    row_number: 2,
    card_name: 'New Booking',
    display_area: '预订信息',
    field_path: 'room.type',
    display_name: '房型',
    visible: 'Y',
    editable: 'Y',
    input_editable: 'N',
    select_editable: 'Y',
    date_picker: 'N',
    number_input: 'N',
    file_display: 'N',
    table_editable: 'N',
    enum_options: '豪华 Q1A, 行政套房',
    required_rule: 'Y',
    display_condition: null,
    validation_rule: null,
    write_path: 'reservation.room.type',
    opera_write_participation: 'Y',
    opera_parameter_mapping: 'roomType',
    notes: null,
    value: '豪华 Q1A',
  },
]

function mountRenderer(readOnly = false) {
  const i18n = createI18n({
    legacy: false,
    locale: 'zh-CN',
    messages: {
      'zh-CN': zhCN,
    },
  })

  return mount(ReservationTaskFieldRenderer, {
    props: {
      fields,
      modelValue: {
        'guest.name': '王建国',
        'room.type': '豪华 Q1A',
      },
      readOnly,
      validationErrors: {},
    },
    global: {
      plugins: [i18n],
    },
  })
}

describe('ReservationTaskFieldRenderer', () => {
  it('emits updates using field_path as key', async () => {
    const wrapper = mountRenderer()
    const input = wrapper.find('textarea')

    await input.setValue('Mark Lee')

    expect(wrapper.emitted('update:modelValue')?.[0]?.[0]).toMatchObject({
      'guest.name': 'Mark Lee',
      'room.type': '豪华 Q1A',
    })
  })

  it('renders editable select from enum options', () => {
    const wrapper = mountRenderer()

    expect(wrapper.find('select').exists()).toBe(true)
    expect(wrapper.findAll('option')).toHaveLength(2)
  })

  it('renders static values when the task is read only', () => {
    const wrapper = mountRenderer(true)

    expect(wrapper.find('textarea').exists()).toBe(false)
    expect(wrapper.text()).toContain('王建国')
  })

  it('shows validation errors next to their fields', () => {
    const i18n = createI18n({
      legacy: false,
      locale: 'zh-CN',
      messages: {
        'zh-CN': zhCN,
      },
    })

    const wrapper = mount(ReservationTaskFieldRenderer, {
      props: {
        fields,
        modelValue: {
          'guest.name': '',
          'room.type': '豪华 Q1A',
        },
        readOnly: false,
        validationErrors: {
          'guest.name': '客人姓名为必填项',
        },
      },
      global: {
        plugins: [i18n],
      },
    })

    expect(wrapper.text()).toContain('客人姓名为必填项')
    expect(wrapper.find('textarea').attributes('aria-invalid')).toBe('true')
  })
})
