<template>
  <ElDialog
    v-model="visible"
    :title="isEdit ? '编辑配货区' : '新增配货区'"
    :close-on-click-modal="false"
    width="800px"
    destroy-on-close
  >
    <el-form ref="formRef" label-width="170px" :model="form" :rules="rules">
      <el-form-item label="配货区名称" prop="name">
        <el-input
          v-model="form.name"
          style="width: 100%"
          clearable
          maxlength="20"
          show-word-limit
          :disabled="isDisabled"
          placeholder="请输入配货区名称"
        />
      </el-form-item>
      <el-form-item label="配货区说明" prop="areaDesc">
        <el-input
          v-model="form.areaDesc"
          style="width: 100%"
          clearable
          maxlength="100"
          show-word-limit
          :disabled="isDisabled"
          placeholder="请输入配货区说明"
        />
      </el-form-item>
      <el-form-item label="配货区" prop="areaCode">
        <el-select
          v-model="form.areaCode"
          :disabled="isDisabled"
          style="width: 200px"
          placeholder="请选择配货区"
        >
          <el-option
            v-for="item in areaList"
            :key="item.code"
            :label="item.desc"
            :value="item.code"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="配货规则" prop="conditions">
        <div class="picking-rules">
          <div class="header">
            <span class="mr-10">满足条件</span>
            <el-radio-group v-model="form.matchType" :disabled="isDisabled">
              <el-radio :value="1">满足以下所有条件</el-radio>
              <el-radio :value="2">满足以下任一条件</el-radio>
            </el-radio-group>
          </div>
          <div
            v-for="(item, index) in form.conditions"
            :key="index"
            class="content"
          >
            <el-select
              v-model="item.conditionType"
              style="width: 160px"
              :disabled="isDisabled"
              placeholder="请选择配货规则"
              @change="handleConditionTypeChange(item)"
            >
              <el-option
                v-for="rule in getAvailablePickingRules(index)"
                :key="rule.code"
                :label="rule.desc"
                :value="rule.code"
              />
            </el-select>

            <el-select
              v-model="item.operator"
              style="width: 100px"
              :disabled="isDisabled"
              placeholder="关系"
            >
              <el-option
                v-for="operator in getAvailableOperators(item.conditionType)"
                :key="operator.code"
                :label="operator.desc"
                :value="operator.code"
              />
            </el-select>
            <template v-if="item.conditionType === 'order_platform'">
              <el-select
                v-model="item.conditionValue"
                class="platform-select"
                style="width: 210px"
                :disabled="isDisabled"
                placeholder="请选择平台"
                filterable
                multiple
                collapse-tags
                :max-collapse-tags="1"
                clearable
                popper-class="customize-select-style"
              >
                <el-option
                  v-for="platform in platformList"
                  :key="platform.type"
                  :label="platform.type"
                  :value="platform.type"
                  style="width: 160px"
                >
                  <img
                    :src="`/images/icon/${platform.icon.split('/').pop()}`"
                    style="height: 20px; margin: 5px 10px 0 0"
                  />
                  <span :title="platform.type">{{ platform.type }}</span>
                </el-option>
              </el-select>
            </template>
            <template v-else-if="item.conditionType === 'order_category'">
              <el-cascader
                v-model="item.conditionValue"
                class="category-cascader"
                style="width: 210px"
                placeholder="请选择商品类目"
                :options="categoryList"
                :props="{
                  label: 'name',
                  value: 'id',
                  children: 'children',
                  multiple: true,
                  emitPath: true,
                }"
                collapse-tags
                collapse-tags-tooltip
                :max-collapse-tags="1"
                tag-type="info"
                show-checked-strategy="parent"
                clearable
                :disabled="isDisabled"
              >
                <template #tag="{ data, deleteTag }">
                  <el-tag
                    v-for="tag in data.slice(0, 1)"
                    :key="tag.key"
                    type="info"
                    :closable="tag.closable"
                    class="category-cascader-tag"
                    @close="deleteTag(tag)"
                  >
                    {{ tag.text }}
                  </el-tag>
                </template>
              </el-cascader>
            </template>
            <template v-else-if="item.conditionType === 'order_user'">
              <el-select
                v-model="item.conditionValue"
                class="platform-select"
                style="width: 210px"
                placeholder="请选择所属客户"
                :disabled="isDisabled"
                filterable
                multiple
                collapse-tags
                :max-collapse-tags="1"
                clearable
              >
                <el-option
                  v-for="user in sortingUserList"
                  :key="user"
                  :label="user"
                  :value="user"
                />
              </el-select>
            </template>

            <template v-else>
              <el-input-number
                v-model="item.conditionValue"
                style="width: 210px"
                :min="1"
                :max="999"
                :disabled="isDisabled"
                placeholder="请输入数字"
              />
            </template>
            <div class="btn-group">
              <el-button
                v-if="form.conditions.length < (pickingRuleList?.length ?? 0)"
                type="primary"
                class="rule-action-btn"
                :icon="Plus"
                size="small"
                circle
                :disabled="isDisabled"
                @click="addPickingRuleItem"
              />
              <el-button
                v-if="form.conditions.length > 1"
                color="#F56C6C"
                class="rule-action-btn"
                :icon="Minus"
                size="small"
                circle
                plain
                :disabled="isDisabled"
                @click="removePickingRuleItem(index)"
              />
            </div>
          </div>
        </div>
      </el-form-item>

      <el-form-item label="自动打单" prop="autoPrint">
        <el-switch v-model="form.autoPrint" size="large" />
      </el-form-item>
      <el-form-item>
        <span v-if="form.autoPrint" class="item-info">
          开启后，配货分拣订单配齐时，自动打单，打单后订单状态转为待发货。
        </span>
        <span v-else class="item-info">
          关闭后，配货分拣订单配齐后仍在待配货状态，经过配货打单后订单状态转为待发货。
        </span>
      </el-form-item>
      <el-form-item label="启用状态" prop="enable">
        <el-switch v-model="form.enable" size="large" />
      </el-form-item>
      <el-form-item>
        <span v-if="form.enable" class="item-info">
          开启后，该配货区正常使用。
        </span>
        <span v-else class="item-info" style="color: #f56c6c">
          关闭后，该配货区暂不使用。
        </span>
      </el-form-item>
      <el-form-item label="是否对接二次扫码设备" prop="secondScan">
        <el-select
          v-model="form.secondScan"
          style="width: 200px"
          placeholder="请选择是否对接二次扫码设备"
        >
          <el-option label="是" :value="true" />
          <el-option label="否" :value="false" />
        </el-select>
      </el-form-item>
      <el-form-item label="序号" prop="sortNo">
        <el-input-number
          v-model="form.sortNo"
          :min="1"
          :max="999"
          style="width: 200px"
          step-strictly
          controls-position="right"
          :disabled="isDisabled"
          placeholder="请输入序号"
        />
      </el-form-item>
      <el-form-item>
        <span class="item-info">配货规则逻辑冲突时，优先执行更小的序号</span>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="flex flex-center">
        <el-button @click="visible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确定</el-button>
      </div>
    </template>
  </ElDialog>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { Plus, Minus } from '@element-plus/icons-vue'
import { ElMessageBox, type FormInstance } from 'element-plus'
import platformJson from '@/json/platform.json'
import type {
  OperatorList,
  SortingRuleCondition,
  SortingRuleDetail,
} from '@/types/api/order'
import type { BaseRespData } from '@/types/api'
import {
  getAreaListApi,
  addAreaApi,
  editAreaApi,
  checkUsedBoxApi,
  getSortingUserListApi,
  getCategoryListApi,
} from '@/api/order'
import { showError } from '@/utils/ui'

const props = defineProps<{
  modelValue: boolean
  isEdit?: boolean
  editData?: SortingRuleDetail
  warehouseId: number
  warehouseName: string
  isDisabled?: boolean
  pickingRuleList: OperatorList[]
  operatorList: OperatorList[]
}>()
const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'submit'): void
}>()

const visible = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  },
})

const formRef = ref<FormInstance>()
const areaList = ref<OperatorList[]>([])
const sortingUserList = ref<OperatorList[]>([])
const categoryList = ref<OperatorList[]>([])
const form = ref<SortingRuleDetail>({
  name: '',
  areaDesc: '',
  areaCode: '',
  matchType: 1,
  conditions: [
    {
      conditionType: '',
      operator: '',
      conditionValue: undefined,
    },
  ],
  enable: false,
  secondScan: false,
  sortNo: 1,
  autoPrint: false,
  warehouseId: 0,
  warehouseName: '',
  defaultFlag: false,
})

// 获取可用的配货规则条件 （剔除已选中的配货规则）
const getAvailablePickingRules = (currentIndex: number) => {
  const selectedFields = form.value.conditions
    .filter((_, index) => index !== currentIndex)
    .map((item) => item.conditionType)
  return props.pickingRuleList.filter(
    (rule) => !selectedFields.includes(rule.code),
  )
}

// 根据配货规则类型获取可用的操作符
const getAvailableOperators = (conditionType: string) => {
  const list = props.operatorList
  const matchers: Record<string, (code: string) => boolean> = {
    order_total_num: (code) => code !== 'in' && code !== 'contain',
    order_platform: (code) => code === 'in',
    order_category: (code) => code === 'contain',
    order_user: (code) => code === 'contain',
  }
  const matcher = matchers[conditionType]
  return matcher ? list.filter((operator) => matcher(operator.code)) : list
}

// 配货规则条件改变
const handleConditionTypeChange = (item: SortingRuleCondition) => {
  switch (item.conditionType) {
    case 'order_platform':
      item.conditionValue = undefined
      item.operator = 'in'
      break
    case 'order_total_num':
      item.conditionValue = undefined
      item.operator = 'gt'
      break
    case 'order_category':
      item.conditionValue = undefined
      item.operator = 'contain'
      break
    case 'order_user':
      item.conditionValue = undefined
      item.operator = 'contain'
      break
  }
}

// 配货规则
const createPickingRuleItem = (): SortingRuleCondition => ({
  conditionType: '',
  operator: '',
  conditionValue: undefined,
})

// 配货规则校验
const validateConditions = (
  _rule: unknown,
  _value: unknown,
  callback: (error?: Error) => void,
) => {
  const items = form.value.conditions
  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    const isValueValid = [
      'order_platform',
      'order_category',
      'order_user',
    ].includes(item.conditionType)
      ? Array.isArray(item.conditionValue) && item.conditionValue.length > 0
      : item.conditionValue !== null && item.conditionValue !== undefined
    if (!item.conditionType || !isValueValid || !item.operator) {
      callback(new Error('请完善配货规则'))
      return
    }
  }
  callback()
}

const rules = computed(() => {
  const base = {
    areaDesc: [
      { required: true, message: '请输入配货区说明', trigger: 'blur' },
    ],
    areaCode: [{ required: true, message: '请选择配货区', trigger: 'change' }],
    autoPrint: [
      { required: true, message: '请选择是否自动打单', trigger: 'change' },
    ],
    enable: [{ required: true, message: '请选择启用状态', trigger: 'change' }],
    secondScan: [
      {
        required: true,
        message: '请选择是否对接二次扫码设备',
        trigger: 'change',
      },
    ],
    sortNo: [{ required: true, message: '请输入序号', trigger: 'blur' }],
  }
  if (form.value.areaCode === 'AREA_0') return base
  return {
    ...base,
    conditions: [
      { validator: validateConditions, trigger: 'blur' },
      { required: true, message: '请完善配货规则', trigger: 'change' },
    ],
  }
})

const platformList = platformJson

// 将详情返回的字符串条件值转为表单可用格式
const formatConditionsForForm = (conditions: SortingRuleCondition[]) =>
  conditions.map((item) => {
    if (
      typeof item.conditionValue !== 'string' ||
      !['order_platform', 'order_category', 'order_user'].includes(
        item.conditionType,
      )
    ) {
      return item
    }
    const values = item.conditionValue.split(',').filter(Boolean)
    // 类目 id 一般为 number，需与级联 options 的 id 类型一致才能回显
    if (item.conditionType === 'order_category') {
      return {
        ...item,
        conditionValue: values.map((v) => {
          const num = Number(v)
          return Number.isNaN(num) ? v : num
        }),
      }
    }
    return { ...item, conditionValue: values }
  })

// 添加配货规则
const addPickingRuleItem = () => {
  form.value.conditions.push(createPickingRuleItem())
  formRef.value?.validateField('conditions')
}

// 删除配货规则
const removePickingRuleItem = (index: number) => {
  form.value.conditions.splice(index, 1)
  formRef.value?.validateField('conditions')
}

// 加载配货区列表
// 新增：剔除已选配货区
// 编辑：剔除已选配货区，但包含当前配货区
// 编辑配货区0：列表包含配货区0（def === true)
const loadAreaList = async () => {
  const res = await getAreaListApi(props.warehouseId)
  if (res.code !== 200) return
  areaList.value = res.data
  // 新增
  if (!props.isEdit) {
    areaList.value = areaList.value.filter((item) => item.used === false)
  }
  // 编辑配货区0
  else if (props.editData?.areaCode === 'AREA_0') {
    areaList.value = areaList.value.filter((item) => item.def === true)
  }
  // 编辑其他配货区
  else {
    areaList.value = areaList.value.filter(
      (item) => item.used === false || item.code === props.editData?.areaCode,
    )
  }
}

// 获取所属客户列表
const getSortingUserList = async () => {
  const res = await getSortingUserListApi()
  if (res.code !== 200) return
  sortingUserList.value = res.data
}

// 获取商品类目
const getCategoryList = async () => {
  const res = await getCategoryListApi()
  if (res.code !== 200) return
  categoryList.value = res.data
}

// 提交
const handleSubmit = async () => {
  form.value.warehouseId = props.warehouseId
  form.value.warehouseName = props.warehouseName
  if (props.editData?.areaCode !== 'AREA_0') {
    await formRef.value?.validate()
  }
  const submitData = {
    ...form.value,
    // 格式化配货规则
    conditions: form.value.conditions.map(
      (item): SortingRuleCondition => ({
        ...item,
        conditionValue: Array.isArray(item.conditionValue)
          ? item.conditionValue
              .map((v) => (Array.isArray(v) ? v[v.length - 1] : v))
              .join(',')
          : item.conditionValue,
      }),
    ),
  }

  if (!submitData.name) {
    const desc = areaList.value.find(
      (item) => item.code === submitData.areaCode,
    )?.desc
    submitData.name = `${desc}-${props.warehouseName}`
  }
  if (props.isEdit) {
    submitData.id = props.editData?.id
    try {
      await checkUsedBoxApi(submitData.id as number)
    } catch (err) {
      const error = err as BaseRespData<never>
      if (error?.code !== 301) {
        showError(error?.message)
        return
      }
      try {
        await ElMessageBox.confirm(error.message, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          dangerouslyUseHTMLString: true,
        })
      } catch {
        return
      }
    }
  }

  const res = props.isEdit
    ? await editAreaApi(submitData)
    : await addAreaApi(submitData)

  if (res.code !== 200) return
  ElMessage.success(props.isEdit ? '编辑成功' : '新增成功')
  visible.value = false
  emit('submit')
}

onMounted(async () => {
  await Promise.all([loadAreaList(), getSortingUserList(), getCategoryList()])
  if (props.editData) {
    form.value = {
      ...props.editData,
      conditions: formatConditionsForForm(props.editData.conditions),
    }
  }
})
</script>
<style scoped lang="scss">
.item-info {
  font-size: 12px;
  color: #666;
  line-height: 1;
  margin-top: -15px;
}

.picking-rules {
  background-color: #eee;
  border-radius: 3px;
  padding: 5px 15px;
  width: 100%;

  .header {
    font-size: 12px;
    font-weight: 500;
    display: flex;
    align-items: center;

    :deep(.el-radio__label) {
      font-size: 12px;
    }
  }

  .content {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 8px;

    &:first-of-type {
      margin-top: 6px;
    }
  }

  .btn-group {
    display: flex;
  }

  .rule-action-btn {
    font-size: 16px;
  }

  .platform-select {
    :deep(.el-select__wrapper) {
      height: var(--el-component-size);
      min-height: var(--el-component-size);
      box-sizing: border-box;
    }

    :deep(.el-select__selection) {
      flex-wrap: nowrap;
    }

    :deep(.el-select__selected-item) {
      flex-shrink: 1;
      min-width: 0;
      overflow: hidden;
    }

    :deep(.el-tag) {
      max-width: 100%;

      .el-tag__content {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }
}
</style>
<style lang="scss">
.customize-select-style {
  .el-select-dropdown__list {
    width: 500px;
    display: flex;
    flex-wrap: wrap;
  }
}

// cascader 样式，确保单行显示
.category-cascader {
  .el-cascader__tags {
    display: flex !important;
    flex-wrap: nowrap !important;
    align-items: center;
    overflow: hidden;
  }

  .category-cascader-tag {
    flex: 0 1 auto !important;
    min-width: 0 !important;
    max-width: 100%;
    overflow: hidden;
  }
}
</style>
