<template>
  <view>
    <navbar-back titleWidth="800" :title="title"></navbar-back>
    <u-row>
      <u-col span="1"></u-col>
      <u-col span="10">
        <scroll-view scroll-y scroll-with-animation :scroll-top="scrollTop">
          <view class="form-item-my" v-for="(field, index) in formFields" :key="'field_' + index">
            <template v-if="!field.hidden">
              <view
                class="label-my"
                :style="{ fontWeight: checkFeadToDetailField(field.headToDetailField) ? 'bold' : 'normal' }"
                >{{ field.label }}</view
              >
              <view class="content-my">
                <view v-if="field.type == 'title'" class="content-title">
                  {{ field.value }}
                </view>
                <!--普通输入框-->
                <u-input
                  v-if="field.type == 'Input'"
                  v-model="field.value"
                  clearable
                  :placeholder="field.placeholder"
                  :disabled="field.disabled || field.fillingWay == 'calculate'"
                />
                <!--数字，限制小数位数-->
                <u-input
                  v-if="field.type == 'decimal'"
                  type="number"
                  clearable
                  @blur="event => checkDecimal(event, field)"
                  v-model="field.value"
                  :placeholder="field.placeholder"
                  :disabled="field.disabled || field.fillingWay == 'calculate'"
                />
                <uni-data-select
                  v-if="field.type == 'Select' || field.type == 'HtmlSelect'"
                  v-model="field.value"
                  :localdata="field.options"
                >
                  <template v-slot:selected="{ selectedItems }">
                    <view v-if="selectedItems.length == 0" style="color: #c0c4cc"> 请选择 </view>
                    <view v-else v-html="selectedItems[0].value"> </view>
                  </template>
                  <template v-slot:option="{ item, itemSelected }">
                    <uni-list-item :disabled="item.disable">
                      <template #body>
                        <view v-html="item.label"></view>
                      </template>
                    </uni-list-item>
                  </template>
                </uni-data-select>
                <!--日期-->
                <view v-if="field.type == 'Date'" class="x-bc select-my" @click="handleFieldClick(field)">
                  <text v-if="field.value">{{ nx.$dayjs(field.value).format('YYYY-MM-DD HH:mm:ss') }}</text>
                  <text v-else>请选择</text>
                  <u-icon name="calendar-fill" size="20"></u-icon>
                </view>

                <u-datetime-picker
                  v-if="field.type == 'Date'"
                  :show="field.showPicker"
                  v-model="curDate"
                  mode="datetime"
                  @cancel="field.showPicker = false"
                  @confirm="event => pickerConfirm(event, field)"
                ></u-datetime-picker>
              </view>
            </template>
          </view>
        </scroll-view>
        <u-button style="width: 50%" type="primary" @click="saveHeadData">保存</u-button>
      </u-col>
      <u-col span="1"> </u-col>
    </u-row>
    <up-loading-page :loading="pageLoading"></up-loading-page>
  </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import nx from '@/nx'
import { onLoad } from '@dcloudio/uni-app'
import { calcRowAnalysisValue } from '@/nx/helper/calcAnalysisValue'
import tools from '@/nx/utils/tools'

const pageLoading = ref(false)
// 标题
const title = ref('')
// tab标题的滚动条位置
const scrollTop = ref(0)
// 当前任务样品
const currentTaskId = ref('')
const configReportTemplateKey = ref('')
// 字典选择器显示
// 当前日期（用于日期选择器）
const curDate = ref(Number(new Date()))
// 字段值对象
const formData = ref({})

// 处理后的字段结构
const formFields = ref([])

const staticFormSchema = [
  { label: '指派单号', fieldKey: 'businessAssayTaskId', hidden: true },
  { label: '检测方法', type: 'Input', fieldKey: 'assayMethodName' },
  { label: '分析人', type: 'Input', fieldKey: 'assayOperator', disabled: true },
  { label: '检测时间', type: 'Date', fieldKey: 'assayTime' }
]
let dynamicFormSchema = []

// 页面加载
onLoad(param => {
  if (param.currentTaskId) {
    currentTaskId.value = param.currentTaskId
    configReportTemplateKey.value = param.configReportTemplateKey
  }
  loadTaskDetail()
})

let tabs = ref([])
const dynamicFormData = ref({})
async function loadTaskDetail() {
  pageLoading.value = true
  const {
    assayTaskAnalysisDataList,
    businessAssayTasNo,
    configAssayMethodName,
    assayOperator,
    assayTime,
    formValue,
    dataCollectionId,
    dataCollectionKey
  } = await nx.$api.assayTask.batchSampleAndQcAnalysisByTaskId(currentTaskId.value)
  formData.value = {
    businessAssayTaskId: currentTaskId.value,
    assayOperator: assayOperator,
    assayTime: assayTime
  }
  if (formValue) {
    formData.value = { ...formData.value, ...JSON.parse(formValue) }
    dynamicFormData.value = JSON.parse(formValue)
  }
  if (!dynamicFormData.value.assayMethodName) {
    formData.value.assayMethodName = configAssayMethodName
  }
  title.value = '样品分析-任务单编号：' + businessAssayTasNo
  // 查询动态字段
  const dataCollectionParams = {}
  if (dataCollectionId) {
    dataCollectionParams.dataCollectionId = dataCollectionId
  } else {
    dataCollectionParams.dataCollectionKey = dataCollectionKey
  }
  const data = await nx.$api.assayTask.getDynamicBaseFormSchema(dataCollectionParams)
  dynamicFormSchema = data.map(item => {
    let customConfig = JSON.parse(item.customConfig)
    let field = {
      label: item.fieldName,
      fieldKey: item.fieldKey,
      type: item.fieldType,
      placeholder: '请输入',
	  hidden:false
	  
    }
    if (customConfig?.componentProps?.options) {
      field.options = customConfig.componentProps.options
    }
	if(customConfig.hidden){
		field.hidden = true
	}
    return field
  })
  formFields.value = [...staticFormSchema, ...dynamicFormSchema]
  bindFormValue()

  // 处理样品分类数据
  const tabGroups = assayTaskAnalysisDataList
  tabs.value = tabGroups.map(group => {
    // 必须深拷贝 datas！防止多个表格共享引用
    const tableData = JSON.parse(JSON.stringify(group.datas || []))
    const columns = group.columns || []
    return {
      name: group.analysisType,
      label: group.analysisName,
      columns,
      tableData,
      configQCSampleMethodInfo: group.configQCSampleMethod?.configInfomation
        ? JSON.parse(group.configQCSampleMethod['configInfomation'])['set']
        : []
    }
  })
  pageLoading.value = false
}
// 空白样或者标样影响计算配置字段
const configQCSampleMethodInfos = computed(() => {
  return tabs.value.filter(t => t.name === 'by' || t.name === 'kby').flatMap(tab => tab.configQCSampleMethodInfo)
})
// 表格数据更新后重新计算
async function updateTableDataByConfigFields() {
  let needCalcTabs = []
  needCalcTabs = tabs.value.filter(t => t.name !== 'by' && t.name !== 'kby' && t.name !== 'zkkby')
  const formData = realFormData.value
  if (needCalcTabs.length === 0) return
  for (const key in formData) {
    for (const tab of needCalcTabs) {
      const columnObj = tab.columns.find(c => {
        if (c.formula) {
          let FromKey = c.formula.split(':')
          return FromKey[1] === key
        }
        return false
      })
      if (!columnObj) continue
      tab.tableData.forEach(row => {
        // 赋值配置列参与计算
        if (row[columnObj.fieldIndex]) {
          row[columnObj.fieldIndex].value = formData[key]
          calcRowAnalysisValue(row, columnObj, tab.columns)
        }
      })
    }
  }
}
// 点击字段（打开选择器）
function handleFieldClick(field) {
  field.showPicker = true
}

// 判断是否需要同步到明细字段（加粗显示）
function checkFeadToDetailField(headToDetailField) {
  if (headToDetailField && headToDetailField.trim() != '') {
    return true
  } else {
    return false
  }
}

// 处理小数位数：补0或去除多余位数
function checkDecimal(e, field) {
  if (e == '') return
  const decimalCount = field.decimalPosition
  const count = Number(decimalCount)
  const value = field.value
  const pos = value.indexOf('.') + 1
  let length = value.length - pos
  if (pos == 0) {
    length = 0
  }
  while (length < count) {
    if (field.value.indexOf('.') < 0) field.value += '.'
    field.value = field.value + '0'
    length++
  }
  if (count === 0) {
    field.value = parseInt(field.value) + ''
  } else if (length > count) {
    field.value = field.value.substring(0, pos + count)
  }
}

// 绑定数据（将 formData 填入字段）
function bindFormValue() {
  for (const field of formFields.value) {
    const fieldKey = field.fieldKey
    if (fieldKey) {
      const value = formData.value[fieldKey]
      if (value) {
        field.value = value
      }
    }
  }
}

const realFormData = computed(() => {
  const formData = {}
  for (const field of formFields.value) {
    if (field.fieldKey) {
      formData[field.fieldKey] = field.value
    }
  }
  return formData
})
// 实际保存逻辑
async function handleSave(change) {
  let params = {}

  const dynamicData = Object.fromEntries(Object.entries(realFormData.value).filter(([key]) => key !== 'assayTime'))
  if (change) {
    // 计算样品数据
    updateTableDataByConfigFields()
    params = {
      ...realFormData.value,
      formValue: JSON.stringify(dynamicData),
      assayTaskAnalysisDataList: tabs.value.map(item => ({
        datas: item.tableData,
        analysisType: item.name
      }))
    }
  } else {
    params = {
      ...realFormData.value,
      formValue: JSON.stringify(dynamicData)
    }
  }
  await nx.$api.assayTask.saveBatchSmpleAndQcAnalysis(params)
  uni.redirectTo({
    url: `/pages/analysis/sample/sample-work-detail?currentTaskId=${currentTaskId.value}&configReportTemplateKey=${configReportTemplateKey.value}`
  })
}

function getDynamicFormSchemaFormData(obj) {
  const includeKeys = new Set(dynamicFormSchema.filter(item => item.fieldKey).map(item => item.fieldKey))
  return Object.fromEntries(Object.entries(obj).filter(([key]) => includeKeys.has(key)))
}
// 检查动态字段值在空白样或者标样的（影响计算配置字段）中是否变化
function checkPropertyEquality() {
  let allColumns = tabs.value.flatMap(tab => tab.columns)
  for (const column of allColumns) {
    const formula = column.formula
    if (!formula) continue
    const target = formula.split(':')[1]
    const originalValue = dynamicFormData.value[target]
    const currentValue = realFormData.value[target]
    if (!looseEqual(originalValue, currentValue)) {
      return true
    }
  }
  return false
}

function looseEqual(a, b) {
  const aEmpty = tools.isEmpty(a)
  const bEmpty = tools.isEmpty(b)

  if (aEmpty && bEmpty) {
    return true // 都是空，算相等
  }
  if (aEmpty || bEmpty) {
    return false // 一个空一个非空，不等
  }
  return a === b // 都非空，严格相等
}
// 保存抬头字段（带确认弹窗）
function saveHeadData() {
  if (!realFormData.value['assayTime']) return nx.$helper.showToast('请选择分析时间')
  if (checkPropertyEquality()) {
    uni.showModal({
      title: '提示',
      content: '您修改的字段将影响样品分析结果，系统将重新计算',
      showCancel: false,
      success: res => {
        if (res.confirm) {
          handleSave(true)
        }
      }
    })
  } else {
    handleSave(false)
  }
}

/*
 * 选择器组件确认事件
 * event： 事件默认参数
 * field： 当前字段
 * 处理逻辑：
 *   field.value = 选中的值
 *   field.valueText = 选中的文本
 * todo： 关联字段在动态字段的change事件处理
 * */
function pickerConfirm(event, field) {
  if (field.type == 'Date') {
    field.value = nx.$dayjs(event.value).valueOf()
    field.showPicker = false
    return
  }
  const confLabel = field.props.label
  const confValue = field.props.value
  const selected = event.value[0]
  const value = selected[confValue]
  const displayName = selected[confLabel]
  field.value = value
  field.valueText = displayName
  if (typeof field.change == 'function') {
    field.change({ value }, selected, { formFields: formFields.value })
  }
  field.showPicker = false
}
</script>

<style lang="scss" scoped>
.content-title {
  width: 100%;
  font-size: 20px;
  font-weight: 300;
}

.form-item-my {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.label-my {
  width: 170px; /* 标签宽度 */
  padding-right: 10px;
  text-align: right;
}

.label-my sub {
  font-size: 0.6em; /* 调整下标字体大小 */
  vertical-align: sub; /* 调整下标垂直对齐 */
}

.content-my {
  flex: 1;
  padding-left: 7px;
  .select-my {
    color: #303133;
    font-size: 15px;
    padding: 6px 8px;
    border: 1px solid #dcdcdc;
    border-radius: 5px;
  }
}
</style>
