import { defineComponent, ref } from 'vue'
import {
  ElPopover,
  ElScrollbar,
  ElCheckbox,
  ElCheckboxGroup,
  ElRadioGroup,
  ElRadio,
  ElInput,
} from 'element-plus'

const styles = {
  searchForm: {
    position: 'relative',
  },
  titleBox: {
    display: 'flex',
    padding: '10px 18px',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  checkboxGroup: {
    display: 'flex',
    padding: '10px',
    justifyContent: 'flex-start',
    flexWrap: 'wrap',
    backgroundColor: '#efefef',
  },

  checkbox: {
    width: '33.3333%',
    'margin-right': '0px !important',
  },
} as const

interface ICompanyList {
  warehouseName: string
  wayList: IwayList[]
}
interface IwayList {
  name: string
  id: string
}
interface IAllList {
  factoryId?: number
  id: number | string
  name: string
  serviceCode?: string
  siteUrl?: string
  status?: number
  uinuinWarehouseId?: number | null
  updateTime?: string
  warehouseId?: number
  warehouseName?: string
  wayList?: IwayList[]
}
export default defineComponent({
  name: 'CustomizeForm',
  props: {
    modelValue: {
      type: [Array, String, Number] as PropType<
        (string | number)[] | string | number
      >,
      default: () => [],
      // 可选：添加自定义验证器确保类型安全
      validator: (value: unknown) => {
        return (
          Array.isArray(value) ||
          typeof value === 'string' ||
          typeof value === 'number'
        )
      },
    },
    companyList: {
      type: Array as PropType<IAllList[] | ICompanyList[]>,
      default: () => [],
    },
    isRadio: {
      type: Boolean,
      default: false,
    },
    valueKey: {
      type: String,
      default: 'id',
    },
    searchPlaceholder: {
      type: String,
      default: '请搜索承运商',
    },
    startPlaceholder: {
      type: String,
      default: '请选择物流方式',
    },
    startWidth: {
      type: String,
      default: '100%',
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const companyList = ref<ICompanyList[]>([])
    const templeCompanyList = ref<ICompanyList[] | IwayList[] | IAllList[]>([])
    const allList = ref<IAllList[]>([])
    const allWayLists = ref<IwayList[]>([])
    const selectedList = ref<(string | number)[]>([])
    const selectedRadioList = ref<string | number>()
    const waysName = ref('')
    const searchName = ref('')
    watch(
      () => props.modelValue,
      (newVal) => {
        if (props.isRadio) {
          allWayLists.value = props.companyList.flatMap(
            (company) => company.wayList,
          ) as IwayList[]

          if (props.valueKey === 'id') {
            selectedRadioList.value = newVal as string | number
          } else {
            selectedRadioList.value =
              allWayLists.value.find((el: IwayList) => newVal === el.name)
                ?.id || ''
          }
        } else {
          selectedList.value = newVal as (string | number)[]
        }
      },
      {
        immediate: true,
        deep: true,
      },
    )

    watch(
      [
        () => selectedList.value,
        () => props.companyList,
        () => selectedRadioList.value,
      ],
      (newVal) => {
        if (props.isRadio) {
          companyList.value = newVal[1] as ICompanyList[]
          allWayLists.value = props.companyList.flatMap(
            (company) => company.wayList,
          ) as IwayList[]

          waysName.value =
            allWayLists.value.find((el: IwayList) => newVal[2] === el.id)
              ?.name || ''
          if (props.valueKey === 'id') {
            emit('update:modelValue', newVal[2])
          } else {
            emit('update:modelValue', waysName.value)
          }
        } else {
          emit('update:modelValue', newVal[0])
          allList.value = newVal[1] as IAllList[]
          companyList.value = transformData(newVal[1] as IAllList[])

          if (newVal[1]?.length) {
            waysName.value = (newVal[1] as IAllList[])
              .filter((item) => {
                if (newVal[0].includes(item.id)) {
                  return item.name
                }
              })
              .map((item) => item.name)
              .join(',')
            // emit('waysName', res)
            // console.log(87, waysName.value)
          }
        }
      },
      { deep: true, immediate: true },
    )
    const handleClearSelection = () => {
      /* 1. 清空显示文本 */
      waysName.value = ''
      /* 2. 清空双向绑定结果 */
      if (props.isRadio) {
        selectedRadioList.value = '' // 单选
        emit('update:modelValue', '')
      } else {
        selectedList.value = [] // 多选
        emit('update:modelValue', [])
      }
      /* 3. 可选：把搜索框也重置 */
      searchName.value = ''
    }
    function setCheckAll(company: ICompanyList, event: boolean) {
      if (event) {
        selectedList.value = [
          ...selectedList.value,
          ...company.wayList.map((item) => item.id),
        ]
      } else {
        selectedList.value = selectedList.value.filter(
          (item) =>
            !company.wayList.map((el) => el.id).includes(item as string),
        )
      }
    }

    const getCompanySelectedStatus = computed(() => {
      const statusMap = new Map()

      companyList.value.forEach((company: ICompanyList) => {
        const allSelected = company.wayList.every((way) =>
          selectedList.value.includes(way.id),
        )
        statusMap.set(company.warehouseName, allSelected)
      })

      return (company: ICompanyList) => statusMap.get(company.warehouseName)
    })

    function fuzzySearch<T>(
      items: T[],
      searchTerm: string,
      key: keyof T = 'name' as keyof T,
    ): T[] {
      // 空搜索返回所有元素
      if (!searchTerm.trim()) {
        return [...items]
      }

      // 将搜索词转为小写（不区分大小写）
      const searchLower = searchTerm.toLowerCase()

      return items.filter((item) => {
        // 获取属性值
        const value = item[key]

        // 确保属性值存在且为字符串
        if (typeof value !== 'string') return false

        // 将属性值转为小写并检查是否包含搜索词
        return value.toLowerCase().includes(searchLower)
      })
    }

    function transformData(data: IAllList[]) {
      const warehouseMap = new Map()
      for (const item of data) {
        const warehouseName = item.warehouseName ?? '未命名仓库'
        if (!warehouseMap.has(warehouseName)) {
          warehouseMap.set(warehouseName, new Set())
        }

        warehouseMap.get(warehouseName).add({ name: item.name, id: item.id })
      }
      const result: {
        warehouseName: string
        wayList: { name: string; id: string }[]
      }[] = []

      warehouseMap.forEach((children, parent) => {
        result.push({
          warehouseName: parent,
          wayList: Array.from(children),
        })
      })

      return result
    }

    return () => (
      <ElPopover
        width="750px"
        placement="bottom-start"
        trigger="click"
        popper-style={{ padding: 0 }}
        onUpdate:visible={(value) => {
          if (value) searchName.value = ''
        }}
        v-slots={{
          reference: () => (
            <ElInput
              modelValue={waysName.value}
              style={{ width: props.startWidth }}
              placeholder={props.startPlaceholder}
              clearable
              onClear={handleClearSelection}
            />
          ),
        }}
      >
        <ElInput
          modelValue={searchName.value}
          onUpdate:modelValue={(value) => {
            if (props.isRadio) {
              templeCompanyList.value = fuzzySearch(allWayLists.value, value)
            } else {
              templeCompanyList.value = fuzzySearch(allList.value, value)
            }
            console.log('templeCompanyList', templeCompanyList.value)
            searchName.value = value
          }}
          clearable
          style={{ width: '200px', padding: '10px' }}
          placeholder={props.searchPlaceholder}
        />
        <ElScrollbar
          class="scroll-container"
          maxHeight="450px"
          style={{ 'border-top': '1px solid #eee' }}
        >
          {!searchName.value ? (
            companyList.value.map((company, index) => (
              <div class="companyBox" key={index}>
                <div style={styles.titleBox}>
                  <div class="title">{company.warehouseName}</div>
                  {!props.isRadio && (
                    <ElCheckbox
                      modelValue={getCompanySelectedStatus.value(
                        company as ICompanyList,
                      )}
                      onChange={(v) =>
                        setCheckAll(company as ICompanyList, v as boolean)
                      }
                      class="selectAll"
                    >
                      全选
                    </ElCheckbox>
                  )}
                </div>

                {props.isRadio ? (
                  <ElRadioGroup
                    modelValue={selectedRadioList.value}
                    onUpdate:modelValue={(value) => {
                      console.log('company', value)
                      selectedRadioList.value = value as string | number
                    }}
                    style={styles.checkboxGroup}
                  >
                    {company.wayList?.map((item) => (
                      <div title={item.name} style={styles.checkbox}>
                        <ElRadio
                          label={item.name}
                          value={item.id}
                          key={`item-${item.id}`}
                        >
                          {item.name}
                        </ElRadio>
                      </div>
                    ))}
                  </ElRadioGroup>
                ) : (
                  <ElCheckboxGroup
                    modelValue={selectedList.value}
                    onUpdate:modelValue={(value) =>
                      (selectedList.value = value)
                    }
                    style={styles.checkboxGroup}
                  >
                    {(company as ICompanyList).wayList.map((item) => (
                      <div title={item.name} style={styles.checkbox}>
                        <ElCheckbox
                          label={item.name}
                          value={item.id}
                          key={`item-${item.id}`}
                          class="checkboxItem"
                        />
                      </div>
                    ))}
                  </ElCheckboxGroup>
                )}
              </div>
            ))
          ) : props.isRadio ? (
            <ElRadioGroup
              modelValue={selectedRadioList.value}
              onUpdate:modelValue={(value) => {
                console.log('company', value)
                selectedRadioList.value = value as string | number
              }}
              style={styles.checkboxGroup}
            >
              {(templeCompanyList.value as IwayList[]).map((item) => (
                <div title={item.name} style={styles.checkbox}>
                  <ElRadio
                    label={item.name}
                    value={item.id}
                    key={`item-${item.id}`}
                  >
                    {item.name}
                  </ElRadio>
                </div>
              ))}
            </ElRadioGroup>
          ) : (
            <ElCheckboxGroup
              modelValue={selectedList.value}
              onUpdate:modelValue={(value) => (selectedList.value = value)}
              style={styles.checkboxGroup}
            >
              {(templeCompanyList.value as IwayList[]).map((item) => (
                <div title={item.name} style={styles.checkbox}>
                  <ElCheckbox
                    label={item.name}
                    value={item.id}
                    key={`item-${item.id}`}
                    class="checkboxItem"
                  />
                </div>
              ))}
            </ElCheckboxGroup>
          )}
        </ElScrollbar>
      </ElPopover>
    )
  },
})
