<template>
  <div class="table-search vxetable-search" v-if="columns.length">
    <el-form
      ref="formRef"
      :model="searchParam"
      :label-position="publicAttr.labelPosition"
      :label-width="publicAttr.labelWidth"
      :rules="rules"
    >
      <Grid ref="gridRef" :collapsed="collapsed" :gap="[20, 0]" :cols="searchCol" :setting="settingStatus">
        <template #default="scope">
          <draggable
            v-if="settingStatus"
            :list="flatColumns"
            :style="scope?.style"
            item-key="field"
            animation="300"
            forceFallback="true"
          >
            <template #item="{ element, index }">
              <GridItem :key="index" v-bind="getResponsive(element)" :index="index" @click="handleSelFormItem(element)">
                <el-form-item
                  :label="`${$t(`table.${element?.table}.${element?.field}`)} :`"
                  class="setting-grid-item"
                  :class="{ 'is-active': activeColumn && activeColumn.field == element.field }"
                >
                  <template v-if="editable || element.search?.render">
                    <BaseFormItem :column="element" :search-param="searchParam" />
                  </template>
                  <template v-else>
                    <!-- <span>{{ searchParam[element.search?.key ?? handleProp(element.field!)] ?? "" }}</span> -->
                    <span class="text-h5-r">{{ formatFunc(searchParam[handleProp(element.field!)], element) }}</span>
                  </template>
                </el-form-item>
              </GridItem>
            </template>
          </draggable>
          <template v-else>
            <GridItem v-for="(item, index) in columns" :key="item.field" v-bind="getResponsive(item)" :index="index">
              <el-form-item
                :label="`${$t(`table.${item?.table}.${item?.field}`)} :`"
                :class="{'to-search': editable && ![undefined, ''].includes(searchParam[item.search?.key ?? handleProp(item.field!)])}"
                :prop="item.search?.key ?? handleProp(item.field!)"
                :rules="item.rules"
              >
                <template v-if="editable || item.search?.render">
                  <BaseFormItem :column="item" :search-param="searchParam" />
                </template>
                <template v-else>
                  <span class="text-h5-r">{{ formatFunc(searchParam[handleProp(item.field!)], item) }}</span>
                </template>
              </el-form-item>
            </GridItem>
          </template>
          <GridItem suffix :span="5" class="flx-end-start">
            <div class="flx-start flx-1">
              <div class="flx-shrink flx-start mr-32 h-full">
                <template v-if="!settingStatus">
                  <el-button v-if="showCollapse" type="primary" link class="search-isOpen" @click="collapsed = !collapsed">
                    {{ collapsed ? $t("common.table.expand") : $t("common.table.putAway") }}
                    <el-icon class="el-icon--right">
                      <component :is="collapsed ? ArrowDown : ArrowUp"></component>
                    </el-icon>
                  </el-button>
                </template>
                <template v-else>
                  <div class="setting-main flx-end w-full h-full">
                    <div class="setting-main_public flx-shrink flx-center -enter-y" :data-title="$t('sys.setting.publicAttr')">
                      <el-form :model="publicAttr" class="flx-center">
                        <el-form-item prop="labelWidth" class="mb-0 mr-16" v-if="publicAttr.labelPosition != 'top'">
                          <div class="flx-center">
                            <span class="text-body-c text-secondary-text mr-8 white-nowrap-word"
                              >{{ $t("sys.setting.columnWidth") }}:</span
                            >
                            <el-input-number class="w-full" v-model="publicAttr.labelWidth" :step="10" :min="50" :max="300" />
                          </div>
                        </el-form-item>
                        <el-form-item class="mb-0" prop="labelPosition">
                          <div class="flx-center">
                            <span class="text-body-c text-secondary-text mr-8">{{ $t("sys.setting.align") }}:</span>
                            <el-radio-group v-model="publicAttr.labelPosition" :id="'public.labelPosition'">
                              <el-radio-button label="left">{{ $t("sys.setting.left") }}</el-radio-button>
                              <el-radio-button label="right">{{ $t("sys.setting.right") }}</el-radio-button>
                              <el-radio-button label="top">{{ $t("sys.setting.top") }}</el-radio-button>
                            </el-radio-group>
                          </div>
                        </el-form-item>
                      </el-form>
                    </div>
                    <div
                      v-if="activeColumn"
                      class="setting-main_private ml-24 -enter-y"
                      :data-title="$t(`table.${activeColumn.table}.${activeColumn.field}`) + $t('sys.setting.privateAttr')"
                    >
                      <el-form :model="publicAttr" class="flx-center">
                        <el-form-item prop="labelWidth" class="mb-0 mr-16">
                          <div class="flx-center">
                            <span class="text-body-c text-secondary-text mr-8 white-nowrap-word"
                              >{{ $t("sys.setting.columnNum") }}:</span
                            >
                            <el-radio-group v-model="activeColumn.search.span" id="search.span">
                              <el-radio-button :label="1">1</el-radio-button>
                              <el-radio-button :label="2">2</el-radio-button>
                              <el-radio-button :label="3">3</el-radio-button>
                              <el-radio-button :label="4">4</el-radio-button>
                              <el-radio-button :label="5">5</el-radio-button>
                            </el-radio-group>
                          </div>
                        </el-form-item>
                        <el-form-item prop="labelWidth" class="mb-0 mr-16" v-if="activeColumn.formatEnum">
                          <div class="flx-center">
                            <span class="text-body-c text-secondary-text mr-8 white-nowrap-word"
                              >{{ $t("sys.setting.format") }}:</span
                            >
                            <el-select
                              v-model="activeColumn.format"
                              class="m-2"
                              :placeholder="$t('sys.setting.notSet')"
                              clearable
                            >
                              <el-option
                                v-for="item in formatEnumMap?.get(activeColumn.field)"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value"
                              />
                            </el-select>
                          </div>
                        </el-form-item>
                      </el-form>
                    </div>
                  </div>
                </template>
              </div>
              <div class="flx-1 flx-end">
                <el-button class="enter-x" circle v-if="!settingStatus" :icon="Operation" @click="gotoSetting"></el-button>
                <template v-else>
                  <el-button class="enter-x" type="primary" :icon="Check" @click="settingConfirm(formRef)">{{
                    $t("common.saveText")
                  }}</el-button>
                  <el-button class="enter-x" :icon="Close" @click="settingStatus = !settingStatus">{{
                    $t("common.cancelText")
                  }}</el-button>
                </template>
              </div>
            </div>
          </GridItem>
        </template>
      </Grid>
    </el-form>
  </div>
</template>
<script setup lang="tsx" name="BaseForm">
import { computed, ref, inject, watch } from "vue";
import { ColumnProps, SearchProps } from "@/components/LjVxeTable/interface";
import { BreakPoint } from "@/components/Grid/interface";
import { Delete, Search, ArrowDown, ArrowUp, Operation, Check, Close } from "@element-plus/icons-vue";
import BaseFormItem from "./BaseFormItem.vue";
import Grid from "@/components/Grid/index.vue";
import GridItem from "@/components/Grid/components/GridItem.vue";
import draggable from "vuedraggable";
import { cloneDeep, pick } from "lodash-es";
import { handleProp, handleRowAccordingToProp } from "@/utils";
import type { FormInstance, FormRules } from "element-plus";

interface ProTableProps {
  columns?: ColumnProps[]; // 搜索配置列
  searchParam?: { [key: string]: any }; // 搜索参数
  searchCol: number | Record<BreakPoint, number>;
  /**
   * @argument string[] 布局读取/保存时，赋值的属性
   */
  layoutAttr?: string[];
  /**
   * @argument Object 布局默认设置，保存时移除，的属性
   */
  layoutAttrDefine?: any;
  /**
   * @argument boolean 是否折叠
   */
  collapse?: boolean;
}

/**
 * @description 是否可编辑
 */
const editable = inject("editable");
const rules = inject("rules", undefined);
const formatEnumMap = inject("baseFormatEnumMap", ref(new Map()));

// 默认值
const props = withDefaults(defineProps<ProTableProps>(), {
  columns: () => [],
  searchParam: () => ({}),
  layoutAttr: () => [],
  layoutAttrDefine: () => ({}),
  collapse: false
});

// 获取响应式设置
const getResponsive = (item: ColumnProps) => {
  return {
    span: item.search?.span,
    offset: item.search?.offset ?? 0,
    xs: item.search?.xs,
    sm: item.search?.sm,
    md: item.search?.md,
    lg: item.search?.lg,
    xl: item.search?.xl
  };
};

// 是否默认折叠搜索项
const collapsed = ref(props.collapse);
// const collapsed = ref(false);

// 是否正在编辑
const settingStatus = ref(false);

// 获取响应式断点
const gridRef = ref();
const breakPoint = computed<BreakPoint>(() => gridRef.value?.breakPoint);

// 判断是否显示 展开/合并 按钮
const showCollapse = computed(() => {
  let show = false;
  props.columns.reduce((prev, current) => {
    prev +=
      (current.search![breakPoint.value]?.span ?? current.search?.span ?? 1) +
      (current.search![breakPoint.value]?.offset ?? current.search?.offset ?? 0);
    if (typeof props.searchCol !== "number") {
      if (prev > props.searchCol[breakPoint.value]) show = true;
    } else {
      if (prev > props.searchCol) show = true;
    }
    return prev;
  }, 0);
  return show;
});

// 记录当前编辑的column
let activeColumn = ref<any>(null);
/**
 * 编辑状态，点击某个column
 * @param item 搜索项item
 */
const handleSelFormItem = (item: any) => {
  activeColumn.value = item;
  console.log("handleSelFormItem activeColumn :>> ", activeColumn.value);
  // activeBaseColMsg.value = getBaseCol(item) ?? {};
};

// 初始化 columns
const flatColumns = ref<ColumnProps[]>();
// const flatColumnsFunc = (columns: ColumnProps[], flatArr: ColumnProps[] = []) => {
//   // columns.forEach(async (col: any) => {
//   //   // 给每一项 column 添加默认属性
//   //   col.search.labelPosition = col.search.labelPosition ?? props.layoutAttrDefine.labelPosition; // "top"
//   //   col.search.labelWidth = col.search.labelWidth ?? props.layoutAttrDefine.labelWidth; // 120
//   //   col.search.span = col.search.span ?? props.layoutAttrDefine.span; // 1

//   //   flatArr.push(col);
//   //   // col.isFilterEnum = col.isFilterEnum ?? true;
//   // });

//   // 取第一个column作为公共参数
//   publicAttr.value = {
//     labelPosition: flatArr[0].search?.labelPosition,
//     labelWidth: flatArr[0].search?.labelWidth
//   };
//   // // 读取个性设置后，排序，
//   // if (dwFieldMap.size) {
//   //   flatArr.sort((a, b) => {
//   //     return a.order! - b.order!;
//   //   });
//   // }
//   return flatArr;
// };
let publicAttr = ref({
  labelPosition: props.layoutAttrDefine.labelPosition,
  labelWidth: props.layoutAttrDefine.labelWidth
});

/**
 * @description 开始编辑
 */
const gotoSetting = () => {
  collapsed.value = false;
  settingStatus.value = true;
  activeColumn.value = null;
  console.log("props.columns :>> ", props.columns);
  flatColumns.value = props.columns;

  publicAttr.value = {
    labelPosition: flatColumns.value[0].search?.labelPosition,
    labelWidth: flatColumns.value[0].search?.labelWidth
  };
  console.log("gotoSetting flatColumns.value :>> ", flatColumns.value);
};

const cols = inject("cols", ref(5));
const emit = defineEmits(["confirm"]);
/**
 * @description 设置窗口，保存事件
 */
const settingConfirm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log("flatColumns.value :>> ", flatColumns.value);
      if (!flatColumns.value) return;
      // 将顺序赋值
      // let columns = flatColumns.value);
      flatColumns.value.forEach((col: ColumnProps, index: number) => {
        col.search!.order = index + 1; // 从1开始
        col.search!.labelPosition = publicAttr.value.labelPosition;
        col.search!.labelWidth = publicAttr.value.labelWidth;
      });

      emit("confirm", flatColumns.value);
      settingStatus.value = false;
    } else {
      console.log("error submit!", fields);
    }
  });
};

const formRef = ref<FormInstance>();

const formatFunc: any = computed((text: string, item: any) => (text: string, item: any): string => {
  if (item?.format) {
    return handleRowAccordingToProp(props.searchParam, item.field!, item?.format);
  }
  return text;
});

watch(
  () => props.columns,
  val => {
    if (!val.length) return;
    publicAttr = ref({
      labelPosition: val[0].search?.labelPosition,
      labelWidth: val[0].search?.labelWidth
    });
  }
);

defineExpose({
  element: formRef
});
</script>

<style lang="scss" scoped>
.setting-grid-item {
  position: relative;

  &::before {
    content: "";
    position: absolute;
    top: -4px;
    left: -4px;
    right: -4px;
    bottom: -4px;
    border: 2px dashed $color-primary-100;
    border-radius: $br-sm;
    z-index: 10;
  }
  &.is-active::before,
  &:hover::before {
    content: "";
    position: absolute;
    top: -4px;
    left: -4px;
    right: -4px;
    bottom: -4px;
    // left: -10px;
    // right: -10px;
    border: 2px solid $color-primary-400;
    border-radius: $br-sm;
    z-index: 10;
    cursor: pointer;
  }
  &.is-active {
    position: relative;
    // background-color: $color-primary-200 !important;
  }
  &:not(.is-active):hover::before {
    border-style: dashed;
    border-color: $color-primary-500;
  }
}

.setting-main {
  .setting-main_private,
  .setting-main_public {
    position: relative;
  }
  .setting-main_private::before,
  .setting-main_public::before {
    content: attr(data-title);
    position: absolute;
    top: -16px;
    left: 0;
    @include text-style-footnote-description;
    color: $color-text-disable;
  }
  .setting-main_private::after,
  .setting-main_public::after {
    content: "";
    position: absolute;
    top: -4px;
    bottom: -4px;
    left: -8px;
    right: -8px;
    background-color: $color-gray-3;
    border-radius: $br-md;
    border: 2px solid $color-gray-1;
    z-index: -1;
    box-shadow: $shadow-1-down;
  }
  .setting-main_private::before {
    color: $color-primary-400;
    // opacity: 0.5;
  }
  .setting-main_private::after {
    background-color: $color-primary-100;
  }
  .setting-main_private {
    height: 32px;
  }
}
.vxetable-search {
  :deep(.el-form-item__label) {
    color: $color-text-secondary-text;
  }
  .to-search {
    :deep(.el-form-item__label) {
      color: $color-primary-700;
    }
  }

  :deep(.el-form-item) {
    .el-select,
    .el-autocomplete,
    .el-date-editor.el-input,
    .el-date-editor.el-input__wrapper {
      // display: flex;
      // width: 100%;
    }
    .el-select .select-trigger {
      flex: 1;
    }
  }
}
</style>
