<template>
  <div>
    <template v-for="item in list">
      <template
        v-if="
          item &&
          !item.hide &&
          (item.type === BLOCK_TYPE.DETAIL ||
            item.type === BLOCK_TYPE.FORM ||
            item.type === BLOCK_TYPE.FIELD)
        "
      >
        <div :key="item.slug">
          <slot name="form-header"></slot>
          <fast2-theme-provider
            ref="themebox"
            theme="block"
            type="form"
            :formulas="permission.formulas"
            :hasRowPermission="hasFieldPermission"
            :inTab="inTab"
            :option="item.data"
            :readOnly="readOnly"
            :rowPermission="getRowPermission(permission.fieldJson)"
          >
            <template v-slot="component">
              <avue-form
                v-if="component.reload"
                v-model="providerData.formData"
                :option="component.option"
                :ref="item.slug"
              >
                <slot name="form-slot"></slot>
              </avue-form>
            </template>
          </fast2-theme-provider>
          <p v-if="isShowTableCount">{{ labels.subtotal }}: {{ count }}</p>
          <slot name="form-footer"></slot>
        </div>
      </template>
      <template v-else-if="item && !item.hide && item.type === BLOCK_TYPE.LIST">
        <div :key="item.slug">
          <ThemeProvider
            theme="block"
            type="crud"
            :addInCell="addInCell"
            :formulas="permission.formulas"
            :hasRowPermission="hasRowPermission"
            :itemLinkList="itemLinkList"
            :option="item.data"
            :readOnly="readOnly"
            :rowPermission="getRowPermission(permission.tableJson)"
          >
            <template v-slot="component">
              <slot name="crud-header">
                <h4 v-if="!readOnly">
                  <el-button size="mini" @click="listRowAdd">{{ labels.addDetails }}</el-button>
                </h4>
              </slot>
              <avue-crud
                ref="table"
                v-if="inited"
                v-model="tableData"
                :data="providerData.tableData"
                :option="component.option"
                @row-del="listRowDel"
                @row-save="listRowSave"
                @row-update="listRowUpdate"
              >
                <template v-for="item in itemLinkList" :slot="item.prop" slot-scope="scope">
                  <el-tag
                    v-if="scope.row[item.prop]"
                    :key="item.prop"
                    @click.stop="go(item, scope.row)"
                  >
                    {{ scope.row[item.prop] }}</el-tag
                  >
                </template>
              </avue-crud>
              <p v-if="isShowTableCount">{{ labels.subtotal }}: {{ tableCount }}</p>
              <slot name="crud-footer"></slot>
            </template>
          </ThemeProvider>
        </div>
      </template>
      <template v-else-if="item && !item.hide && item.type === BLOCK_TYPE.DYNAMIC">
        <div :key="item.slug">
          <component
            :is="getComponent(item.type, item.component)"
            :list="item.data && item.data.tableData ? item.data.tableData : item.data"
            :providerData="providerData"
            :readOnly="readOnly"
          ></component>
        </div>
      </template>
      <template v-else>
        <div :key="item.slug">
          <h5>{{ labels.unableToParseData }}</h5>
          <code>{{ item }}</code>
        </div>
      </template>
    </template>
  </div>
</template>
<script>
/**
 * 界面配置总管理界面
 * 左侧 维护 所有可配数据列表
 * 主内容根据 可配数据类型 展示 表单，表格，详情，组件列表管理，可选择设置对应的数据
 * 进入屏蔽其他操作状态，单纯进行布局， 保存 及 发布 ， 可维护类型为 表格 表单 详情， 组合， 可 维护 模版 页面  模块
 * block 内含一组组件
 */
import itemAttachment from './cards/item-attachment';
import { ft, getRowPermission } from '../../lib/utils';
import { isMobile, validateNull } from '../../lib/validate';
import ThemeProvider from './widget/theme-provider';

const BLOCK_TYPE = {
  LIST: 'crud',
  FORM: 'form',
  DETAIL: 'detail',
  FIELD: 'field',
  BUTTONS: 'button',
  COMPONENT: 'block',
  DYNAMIC: 'dynamicBlock'
};

const LABELS = {
  addDetails: ft('i18n_common_add_details', '新增行'),
  correctMobile: ft(
    'i18n_common_please_enter_the_correct_mobile_phone_number',
    '请输入正确的手机号码'
  ),
  factoryAudit: ft('i18n_common_factory_audit', '验厂单'),
  qualificationAccess: ft('i18n_common_qualification_access', '资质准入'),
  sampleAccess: ft('i18n_common_sample_access', '样品准入'),
  subtotal: ft('i18n_common_subtotal', '小计'),
  unableToParseData: ft('i18n_common_unable_to_parse_data', '无法解析数据')
};

export default {
  name: 'ComponentRender',
  components: { itemAttachment, ThemeProvider },
  props: {
    addInCell: {
      type: Boolean,
      default: false
    },

    dataSource: {
      type: String,
      default: null
    },

    inTab: {
      type: Boolean,
      default: false
    },

    itemLinkList: {
      type: Array,
      default: function () {
        return [
          {
            label: `${LABELS.factoryAudit}`,
            prop: 'inspectionAccess',
            url: '/admission/#/v2/inspectTableAudit/detail/'
          },
          {
            label: `${LABELS.qualificationAccess}`,
            prop: 'aptitudesAccess',
            url: '/admission/#/v2/auditAdmission/view/'
          },
          {
            label: `${LABELS.sampleAccess}`,
            prop: 'sampleAccess',
            url: '/admission/#/v2/sampleAudit/view/'
          }
        ];
      }
    },

    labels: {
      type: Object,
      default: function () {
        return LABELS;
      }
    },

    list: {
      type: Array,
      default: () => {
        return [];
      }
    },

    mode: {
      type: String,
      default: null
    },

    permission: {
      type: Object,
      default: () => {
        return {
          tableJson: [],
          fieldJson: [],
          formulas: []
        };
      }
    },

    providerData: {
      type: Object,
      default: () => {
        return {
          tableData: [],
          formData: {}
        };
      }
    },

    readOnly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      BLOCK_TYPE,
      tableObj: {},
      tableData: [],
      formData: {},
      lockCalc: false,
      inited: false,
      count: 0
    };
  },
  computed: {
    hasFieldPermission() {
      if (validateNull(this.permission)) {
        return false;
      }
      return !validateNull(this.permission.fieldJson);
    },

    hasRowPermission() {
      if (validateNull(this.permission)) {
        return false;
      }
      return !validateNull(this.permission.tableJson);
    },

    tableCount() {
      let count = 0;
      this.providerData.tableData.forEach((item) => {
        if (Number(item.price)) {
          count += Number(item.price);
        }
      });
      return count.toFixed(2);
    }
  },
  watch: {
    providerData: {
      handler: function (newVal, oldVal) {
        if (newVal.formData) {
          const formula = this.$getFormulaItem(this.dataSource);
          const result = this.$getFormulaValue(formula, newVal.formData);
          if (!result.formulaVauleResult) {
            this.count = 0;
          } else {
            this.count = result.price;
          }
        }
      },
      immediate: true,
      deep: true
    },

    readOnly: function () {
      this.initList();
    }
  },
  mounted() {
    this.initList();
  },
  methods: {
    checkFormulas(data) {
      if (this.permission.formules && data) {
        const obj = this.$util.doCalc(this.permission.formules, data);
        return obj;
      }
      return data;
    },

    getComponent(type, component) {
      const KEY_COMPONENT_NAME = 'item-';
      let result = 'normal';
      if (!this.validatenull(component)) {
        result = component;
      } else if (type === 'attachment') {
        result = type;
      } else if (type === 'business-rule-config') {
        return type;
      }
      this.mycomponent = KEY_COMPONENT_NAME + result;
      return this.mycomponent;
    },

    getRowPermission(data) {
      return getRowPermission(data);
    },

    go(item, row) {
      if (window.parent) {
        const router = {
          name: item.label,
          src: item.url + row[item.prop]
        };
        const event = {
          name: 'openNewTag',
          props: router
        };

        window.parent.postMessage(event, '*');
      } else {
        window.location.href = item.url;
      }
    },

    initList() {
      this.list = this.list.map((item) => {
        item.data.labelPosition = 'top';
        item.data.submitBtn = false;
        if (this.readOnly) {
          item.data.detail = true;
        } else {
          item.data.menuBtn = false;
        }
        return item;
      });

      this.inited = true;

      this.$nextTick(() => {
        if (!this.$refs.table || !this.$refs.table[0]) {
          return false;
        }
        const list = this.$refs.table[0].option?.column;
        this.itemLinkList.map((item) => {
          const linkItem = this.findObject(list, item.prop);
          if (linkItem !== -1) {
            linkItem.slot = true;
          }
        });
      });
    },

    listRowAdd() {
      if (this.addInCell) {
        const lenth = this.providerData.tableData?.length || 0;
        if (!this.lockCalc) {
          this.providerData.tableData.splice(lenth + 1, 0, { $cellEdit: true });
        } else {
          setTimeout(this.listRowAdd, 1000);
        }
      } else {
        this.$refs.table[0].rowAdd();
      }
    },

    listRowSave(payload, done) {
      const calcPayload = this.checkFormulas(payload);
      this.providerData.tableData.push(calcPayload);
      if (payload.telphone && isMobile(payload.telphone)) {
        this.updateRootTable(this.providerData.tableData);
        done();
      } else if (!payload.telphone) {
        this.updateRootTable(this.providerData.tableData);
        done();
      } else {
        this.$message.error(`${this.labels.correctMobile}`);
        return false;
      }
    },

    listRowUpdate(row, index, done, loading) {
      // 行修改
      const calcPayload = this.checkFormulas(row);
      this.$set(this.providerData.tableData, index, calcPayload);
      if (row.telphone && isMobile(row.telphone)) {
        loading();
        this.updateRootTable(this.providerData.tableData);
        done();
      } else if (!row.telphone) {
        loading();
        this.updateRootTable(this.providerData.tableData);
        done();
      } else {
        this.$message.error(`${this.labels.correctMobile}`);
        loading();
        return false;
      }
    },

    updateRootTable(tableData) {
      let data = { tableData };
      if (this.dataSource) {
        data = {
          [this.dataSource]: tableData
        };
      }
      this.$root.$emit('change-table', data);
    }
  }
};
</script>
