<template>
  <section class="query-wrap">
    <div class="query-title">{{ title }}</div>
    <div class="query-grid">
      <div v-for="field in renderFields" :key="field.key" class="query-cell">
        <div class="cell-label">{{ field.label }}</div>
        <div
          class="cell-control"
          :class="{ 'is-checkbox': field.type === 'checkbox' }"
        >
          <el-input
            clearable
            v-if="field.type === 'input'"
            v-model="formState[field.key]"
            class="control-input"
            :placeholder="field.placeholder || ''"
          />
          <el-input
            clearable
            v-else-if="field.type === 'number'"
            v-model="formState[field.key]"
            class="control-input"
            type="number"
            :placeholder="field.placeholder || ''"
          />
          <el-select
            clearable
            v-else-if="field.type === 'select'"
            v-model="formState[field.key]"
            class="control-select"
            :placeholder="field.placeholder || '请选择'"
            :multiple="field.multiple || false"
            collapse-tags
            collapse-tags-tooltip
          >
            <el-option
              v-for="item in field.options || []"
              :key="item.value ?? item"
              :label="item.label ?? item"
              :value="item.value ?? item"
            />
          </el-select>
          <el-date-picker
            clearable
            v-else-if="field.type === 'date'"
            v-model="formState[field.key]"
            class="control-date"
            type="date"
            :placeholder="field.placeholder || '请选择日期'"
            value-format="YYYY-MM-DD"
          />
          <el-date-picker
            clearable
            v-else-if="field.type === 'datetime'"
            v-model="formState[field.key]"
            class="control-date"
            type="datetime"
            :placeholder="field.placeholder || '请选择时间'"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
          <el-date-picker
            clearable
            v-else-if="field.type === 'daterange'"
            v-model="formState[field.key]"
            class="control-date"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
          />
          <el-date-picker
            clearable
            v-else-if="field.type === 'datetimerange'"
            v-model="formState[field.key]"
            class="control-date"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
          <template v-else-if="field.type === 'department'">
            <MOSTY.Department
              clearable
              v-model="formState[field.key]"
              class="control-select"
            />
          </template>
          <div v-else-if="field.type === 'checkbox'" class="checkbox-wrap">
            <el-checkbox v-model="formState[field.key]" />
          </div>
          <div v-else-if="field.type === 'slot'" class="checkbox-wrap">
            <slot :name="field.key" />
          </div>
        </div>
      </div>
    </div>
    <div class="query-action">
      <div>
        <slot name="but"></slot>
      </div>
      <div>
        <el-button size="small" type="primary" @click="handleSearch">{{
          searchText
        }}</el-button>
        <el-button size="small" type="button" @click="handleReset"
          >重置
        </el-button>
      </div>
    </div>
  </section>
</template>

<script setup>
import { computed, reactive, watch } from "vue";
import * as MOSTY from "@/components/MyComponents/index";
const props = defineProps({
  title: {
    type: String,
    default: "查询条件"
  },
  searchText: {
    type: String,
    default: "查询"
  },
  fields: {
    type: Array,
    default: () => []
  },
  searchArr: {
    type: Array,
    default: () => []
  }
});

const emit = defineEmits(["search", "submit", "reset"]);
const formState = reactive({});

const renderFields = computed(() => {
  const source = props.searchArr.length ? props.searchArr : props.fields;
  return source
    .map((field) => ({
      ...field,
      key: field.key || field.prop,
      type: field.type || field.showType || "input"
    }))
    .filter((field) => field.key);
});

const getResetValue = (field) => {
  if (field.defaultVal !== undefined) {
    return Array.isArray(field.defaultVal)
      ? [...field.defaultVal]
      : field.defaultVal;
  }
  if (field.type === "checkbox") {
    return false;
  }
  if (field.type === "daterange" || field.type === "datetimerange") {
    return [];
  }
  if (field.type === "select") {
    if (field.multiple) {
      return [];
    }
    return null;
  }
  return "";
};

const buildResetPayload = () => {
  const payload = {};
  renderFields.value.forEach((field) => {
    payload[field.key] = getResetValue(field);
  });
  return payload;
};

const setFormState = (value = {}) => {
  Object.keys(formState).forEach((key) => {
    delete formState[key];
  });
  renderFields.value.forEach((field) => {
    if (value[field.key] !== undefined) {
      formState[field.key] = Array.isArray(value[field.key])
        ? [...value[field.key]]
        : value[field.key];
      return;
    }
    formState[field.key] = getResetValue(field);
  });
};

const getFormSnapshot = () => {
  const snapshot = {};
  renderFields.value.forEach((field) => {
    const value = formState[field.key];
    if (Array.isArray(value)) {
      snapshot[field.key] = [...value];
      return;
    }
    snapshot[field.key] = value;
  });
  return snapshot;
};

const handleSearch = () => {
  const payload = getFormSnapshot();
  emit("search", payload);
  emit("submit", payload);
};

const handleReset = () => {
  const payload = buildResetPayload();
  setFormState(payload);
  emit("reset", true);
  emit("search", payload);
  emit("submit", payload);
};

watch(
  renderFields,
  () => {
    setFormState(buildResetPayload());
  },
  { immediate: true }
);

defineExpose({
  formState,
  handleSearch,
  handleReset
});
</script>

<style scoped lang="scss">
.query-wrap {
  border: 1px solid #b8d3ff;
  background: #fff;
}

.query-title {
  height: 32px;
  background: linear-gradient(to right, #9ed7ff, #e6f0f8);
  line-height: 32px;
  padding-left: 10px;
  font-size: 16px;
  font-weight: 700;
  color: #0d2148;
  border-bottom: 1px solid #b8d3ff;
}

.query-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.query-cell {
  display: flex;
  min-height: 40px;
  border-right: 1px solid #b8d3ff;
  border-bottom: 1px solid #b8d3ff;
}

.query-cell:nth-child(4n) {
  border-right: 0;
}

.cell-label {
  width: 130px;
  flex-shrink: 0;
  border-right: 1px solid #b8d3ff;
  font-size: 14px;
  color: #0d2148;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

.cell-control {
  flex: 1;
  min-width: 0;
  padding: 4px 8px;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.cell-control.is-checkbox {
  justify-content: center;
  padding: 0;
}

.control-input,
.control-select,
.control-date {
  width: 100%;
  max-width: 100%;
  min-width: 0;
}

:deep(.control-input .el-input__wrapper),
:deep(.control-select .el-select__wrapper),
:deep(.control-date .el-input__wrapper) {
  width: 100%;
  max-width: 100%;
  min-height: 28px;
  border-radius: 0;
  box-shadow: 0 0 0 1px #b8d3ff inset;
}

:deep(.control-date.el-date-editor) {
  width: 100%;
  max-width: 100%;
  min-width: 0;
}

:deep(.control-date.el-date-editor .el-range-input) {
  min-width: 0;
}

:deep(.control-input .el-input__inner),
:deep(.control-select .el-select__placeholder),
:deep(.control-date .el-input__inner) {
  font-size: 14px;
  color: #0d2148;
}

:deep(.control-date .el-range-input) {
  font-size: 14px;
  color: #0d2148;
}

:deep(.control-date .el-range__icon),
:deep(.control-date .el-range__close-icon) {
  line-height: 1;
}

.checkbox-wrap {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

:deep(.checkbox-wrap .el-checkbox) {
  margin-right: 0;
  height: 100%;
  display: flex;
  align-items: center;
}

:deep(.checkbox-wrap .el-checkbox__inner) {
  width: 14px;
  height: 14px;
}

.query-action {
  height: 36px;
  display: flex;
  // justify-content: flex-end;
  justify-content: space-between;
  align-items: center;
  padding: 0 8px;
}

.search-btn {
  height: 26px;
  min-width: 70px;
  border: 1px solid #0f5bbd;
  background: #0f5bbd;
  color: #fff;
  font-size: 14px;
  cursor: pointer;
}
</style>
