<template>
  <div>
    <el-table
      ref="tableRef"
      :cell-style="{ padding: '0px', fontSize: '12px' }"
      :header-cell-style="tableHeaderCellStyle"
      :data="tableData"
      :border="true"
      show-summary
      :summary-method="summaryMethod"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      @row-click="rowClick"
      :row-style="rowStyle"
      :row-class-name="rowClassName"
    >
      <el-table-column fixed="left" type="selection" width="50" align="center"></el-table-column>
      <el-table-column type="index" width="40" align="center"> </el-table-column>
      <el-table-column prop="descr" label="摘要" min-width="150px" style="padding: 0" align="center">
        <template slot-scope="{ row }">
          <el-input
            style="width: 100%"
            type="text"
            v-model="row.descr"
            size="small"
            autocomplete="off"
            clearable
            placeholder="请输入摘要"
            :disabled="disabled"
          >
          </el-input>
        </template>
      </el-table-column>
      <el-table-column prop="accountCode" label="科目代码" width="360px">
        <template slot-scope="{ row }">
          <div style="display: flex; align-items: center; justify-content: space-between">
            <search-query
              v-if="!isARAPRow(row)"
              style="width: 100%"
              :datalist="accountData"
              :selectValue="row.accountCode"
              :filterable="true"
              :clearable="true"
              :remote="true"
              :buttonIf="false"
              :desc="true"
              :forParameter="{ key: 'code', label: 'code', value: 'code', desc: 'fullName' }"
              :disabled="disabled"
              @corpFocus="accountsListfun"
              @remoteMethod="accountsListfun"
              @corpChange="corpChange($event, 'accountId', row)"
            >
            </search-query>
            <span v-if="isARAPRow(row)">{{row.accountCode}}</span>

            <el-tooltip
              v-if="!disabled && (row.isEmpl === 1 || row.isCorp === 1 || row.isDept === 1 || row.isItem === 1) && !isARAPRow(row)"
              class="item"
              effect="dark"
              content="核算项目"
              placement="top"
            >
              <el-button size="mini" type="primary" icon="el-icon-edit" circle @click="auxiliaryAccountingfun(row)" :disabled="disabled"></el-button>
            </el-tooltip>
            <el-tooltip v-if="!disabled && row.isDc === 1" class="item" effect="dark" content="预收/预付核销" placement="top">
              <el-button size="mini" type="primary" icon="el-icon-scissors" circle @click="showOffRecordsfun(row)" :disabled="disabled"></el-button>
            </el-tooltip>
          </div>
          <div style="display: flex">
            <span>{{
              (row.accountCnName ? row.accountCnName : "　") +
                (row.isEmpl === 1 && row.emplName ? "/" + row.emplName : "") +
                (row.isDept === 1 && row.deptName ? "/" + row.deptName : "") +
                (row.isCorp === 1 && row.corpShortName ? "/" + row.corpShortName : "") +
                (row.isItem === 1 ? "/" + row.itemClassify + "-" + (row.itemName ? row.itemName : "") : "")
            }}</span>
          </div>
        </template>
      </el-table-column>

      <el-table-column prop="dc" label="方向" min-width="45px" style="padding: 0" align="center">
        <template slot-scope="{ row }">
          <span>{{ row.dc == "D" ? "借" : "贷" }}</span>
        </template>
      </el-table-column>

      <el-table-column label="本币金额">
        <el-table-column prop="amountDr" label="借方" min-width="90px" align="center">
          <template slot-scope="{ row }">
            <el-input-number
              v-if="!isARAPRow(row)"
              style="width: 100%"
              v-model="row.amountDr"
              size="small"
              autocomplete="off"
              :disabled="row.curCode !== 'CNY' || !row.accountId || disabled"
              placeholder="请输入借方"
              :precision="2"
              @change="amountBlur(row, 'D')"
              @keydown.native="handleKeydown($event, row, 'amountDr')"
              :controls="false"
            >
            </el-input-number>
            <span v-else>{{ fmtAmt(row.amountDr, 2) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="amountCr" label="货方" min-width="90px" align="center">
          <template slot-scope="{ row }">
            <el-input-number
              v-if="!isARAPRow(row)"
              style="width: 100%"
              v-model="row.amountCr"
              size="small"
              autocomplete="off"
              :disabled="row.curCode !== 'CNY' || !row.accountId || disabled"
              placeholder="请输入货方"
              :precision="2"
              @change="amountBlur(row, 'C')"
              @keydown.native="handleKeydown($event, row, 'amountCr')"
              :controls="false"
            >
            </el-input-number>
            <span v-else>{{ fmtAmt(row.amountCr, 2) }}</span>
          </template>
        </el-table-column>
      </el-table-column>
      <el-table-column label="外币金额">
        <el-table-column prop="curCode" label="币种" min-width="60px" align="center"> </el-table-column>
        <el-table-column prop="exrate" label="汇率" min-width="80px" align="center">
          <template slot-scope="{ row }">
            <el-input-number
              v-if="row.curCode === 'USD' && !isARAPRow(row)"
              style="width: 100%"
              v-model="row.exrate"
              size="small"
              autocomplete="off"
              clearable
              placeholder="请输入借方"
              :precision="4"
              @change="amountBlur(row, 'exrate')"
              :disabled="disabled"
              :controls="false"
            >
            </el-input-number>
            <span v-else-if="row.curCode === 'USD'">{{ fmtAmt(row.exrate, 2) }}</span>
            <span v-else></span>
          </template>
        </el-table-column>
        <el-table-column prop="amountDrUsd" label="借方" min-width="90px" align="center">
          <template slot-scope="{ row }">
            <el-input-number
              v-if="row.curCode === 'USD' && row.changeMode !== 'd' && !isARAPRow(row)"
              style="width: 100%; text-align: right"
              v-model="row.amountDrUsd"
              size="small"
              autocomplete="off"
              :disabled="row.curCode === 'CNY' || !row.accountId || disabled"
              clearable
              placeholder="请输入借方"
              :precision="2"
              @change="amountUSDBlur(row, 'Dusd')"
              :controls="false"
            >
            </el-input-number>
            <span v-else>{{ fmtAmt(row.amountDrUsd, 2) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="amountCrUsd" label="货方" min-width="90px" align="center">
          <template slot-scope="{ row }">
            <el-input-number
              v-if="row.curCode === 'USD' && row.changeMode !== 'd' && !isARAPRow(row)"
              style="width: 100%"
              v-model="row.amountCrUsd"
              size="small"
              autocomplete="off"
              :disabled="row.curCode === 'CNY' || !row.accountId || disabled"
              clearable
              placeholder="请输入货方"
              :precision="2"
              @change="amountUSDBlur(row, 'Cusd')"
              :controls="false"
            >
            </el-input-number>
            <span v-else>{{ fmtAmt(row.amountCrUsd, 2) }}</span>
          </template>
        </el-table-column>
      </el-table-column>
      <!--
      <el-table-column prop="remarks" label="备注" width="200px">
        <template slot-scope="{ row }">
          <el-input
            style="width: 100%;"
            type="textarea"
            v-model="row.remarks"
            size="small"
            autocomplete="off"
            clearable
            placeholder="请输入备注"
            :disabled="disabled"
          >
          </el-input>
        </template>
      </el-table-column>
      -->
      <el-table-column v-if="!disabled" label="操作" fixed="right" width="100px">
        <template slot-scope="scope">
          <el-tooltip class="item" effect="dark" content="添加" placement="top">
            <el-button
              size="mini"
              type="primary"
              icon="el-icon-plus"
              circle
              @click="addRowsfun(scope.row, scope.$index)"
              :disabled="disabled"
            ></el-button>
          </el-tooltip>
          <el-tooltip v-if="!isARAPRow(scope.row)" class="item" effect="dark" :content="scope.row.changeMode === 'd' ? '恢复' : '删除'" placement="top">
            <el-button
              size="mini"
              type="danger"
              icon="el-icon-delete"
              circle
              @click="deletefun(scope.row, scope.$index)"
              :disabled="disabled"
            ></el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import SearchQuery from "@/components/iosbasic-data/searchquery.vue";
import { accountsList } from "@/api/iosBasicData/accounts";
import { bcurrencyGetExrate } from "@/api/iosBasicData/rateManagement";
import { dateFormat } from "@/util/date";

export default {
  components: { SearchQuery },
  data() {
    return {
      accountData: [] // 科目数据
    };
  },
  props: {
    assemblyForm: {
      type: Object,
      default: {}
    },
    tableData: {
      type: Array,
      default: []
    },
    handleSelectionData: {
      type: Array,
      default: []
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  async created() {
    this.accountsListfun();
    // this.option = await this.getColumnData(this.getColumnName(321.1), this.optionBack);
  },
  methods: {
    forceNumber(s, d) {
      let N = Number(s);
      return isNaN(N) ? 0.0 : Number(N.toFixed(d ? d : 2));
    },
    fmtAmt(value, d){
      let N = this.forceNumber(value, d).toFixed(d);
      return N === '0.00' ? '' : N;
    },
    // 自定义合计
    summaryMethod(param) {
      const { columns, data } = param;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 2) {
          sums[index] = "合计";
          return;
        }
        const values = data.map(item => (item.changeMode === "d" ? 0.0 : Number(item[column.property])));
        // 显示列的统计 金额
        let arr = ["amountDr", "amountCr", "amountDrUsd", "amountCrUsd"];
        // 判断是否有这个数据
        if (arr.indexOf(column.property) != -1) {
          if (!values.every(value => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr);
              if (!isNaN(value)) {
                return prev + curr;
              } else {
                return prev;
              }
            }, 0);
            sums[index] = sums[index].toFixed(2); // 把合计的参数保留两位小数
            // sums[index] += " 元";
          } else {
            sums[index] = " ";
          }
        }
      });
      return sums;
    },
    isARAPRow(row) {
      let code = row && row.accountCode ? row.accountCode : "";
      return code.startsWith("1141") || code.startsWith("2121")
    },
    handleKeydown(e, row, name) {
      console.log("handleKeydown", e, name);
      if (e.key === "=") {
        e.preventDefault();
        // amountDr,amountCr
        let amtDr = 0.0,
          amtCr = 0.0;
        this.tableData.forEach(item => {
          if (item !== row) {
            amtDr = this.forceNumber(amtDr + this.forceNumber(item.amountDr, 2), 2);
            amtCr = this.forceNumber(amtCr + this.forceNumber(item.amountCr, 2), 2);
          }
        });
        console.log("amtDr", amtDr, "amtCr", amtCr);
        if (name === "amountDr") {
          this.$set(row, "amountCr", 0.0);
          this.$set(row, name, this.forceNumber(amtCr - amtDr, 2));
        }
        if (name === "amountCr") {
          this.$set(row, "amountDr", 0.0);
          this.$set(row, name, this.forceNumber(amtDr - amtCr, 2));
        }

        if (row.curCode === "USD") {
          this.$set(row, "exrate", this.forceNumber(row.exrate, 4));
          if (row.exrate.toFixed(4) === "0.0000") {
            this.$set(row, "exrate", 1);
          }

          this.$set(row, "amountDrUsd", this.forceNumber(this.forceNumber(row.amountDr, 2) / row.exrate, 2));
          this.$set(row, "amountCrUsd", this.forceNumber(this.forceNumber(row.amountCr, 2) / row.exrate, 2));
        }else{
          this.$set(row, "exrate", 1);
          this.$set(row, "amountDrUsd", 0.00);
          this.$set(row, "amountCrUsd", 0.00);
        }
      }
    },
    // 借方/贷方 本币的计算
    amountBlur(row, name) {
      console.log("amountBlur", row, name);
      if (name == "D") {
        this.$set(row, "amountCr", 0);
      }
      if (name == "C") {
        this.$set(row, "amountDr", 0);
      }
      // if (name == 'Dusd') {
      //     this.$set(row,'amountCrUsd',0)
      // }
      // if (name == 'Cusd') {
      //     this.$set(row,'amountDrUsd',0)
      // }
      if (row.curCode == "USD") {
        this.$set(row, "exrate", row.exrate ? Number(row.exrate) : 1);
        this.$set(row, "amountCr", row.amountCr ? Number(row.amountCr) : 0);
        this.$set(row, "amountDr", row.amountDr ? Number(row.amountDr) : 0);

        this.$set(row, "amountCrUsd", (row.amountCr / row.exrate).toFixed(2));
        this.$set(row, "amountDrUsd", (row.amountDr / row.exrate).toFixed(2));
      }
      // 合计本位币
      this.$set(row, "amountDrLoc", row.amountDr);
      this.$set(row, "amountCrLoc", row.amountCr);
    },
    // 外币的计算
    amountUSDBlur(row, name) {
      console.log("amountUSDBlur", row, name);
      if (name == "Dusd") {
        this.$set(row, "amountCrUsd", 0);
      }
      if (name == "Cusd") {
        this.$set(row, "amountDrUsd", 0);
      }
      this.$set(row, "exrate", row.exrate ? Number(row.exrate) : 1);
      this.$set(row, "amountCrUsd", row.amountCrUsd ? Number(row.amountCrUsd) : 0);
      this.$set(row, "amountDrUsd", row.amountDrUsd ? Number(row.amountDrUsd) : 0);

      this.$set(row, "amountCr", (row.amountCrUsd * row.exrate).toFixed(2));
      this.$set(row, "amountDr", (row.amountDrUsd * row.exrate).toFixed(2));
      // 合计本位币
      this.$set(row, "amountDrLoc", (row.amountDrUsd * row.exrate).toFixed(2));
      this.$set(row, "amountCrLoc", (row.amountCrUsd * row.exrate).toFixed(2));
    },
    // 获取科目类型数据
    accountsListfun(code) {
      // isManual == 1 的允许手工添加
      accountsList(1, 10, { code, isDetail: 1, isManual: 1 }).then(res => {
        console.log(res.data.data.records);
        this.accountData = res.data.data.records;
      });
    },
    // 行删除
    deletefun(row, index) {
      this.$emit("deletefun", row, index);
    },
    // 行添加
    addRowsfun(row, index) {
      this.$emit("addRowsfun", row, index);
    },
    // 辅助核算
    auxiliaryAccountingfun(row) {
      if (!row.accountId) {
        return this.$message.warning("请先选择科目代码");
      }
      this.$emit("auxiliaryAccountingfun", row);
    },
    showOffRecordsfun(row) {
      if (!row.accountId) {
        return this.$message.warning("请先选择科目代码");
      }
      if (!row.amountDr && !row.amountCr) {
        return this.$message.warning("请输入金额");
      }
      this.$emit("showOffRecordsfun", row);
    },
    // 下拉回调
    corpChange(value, name, row) {
      let found = false;
      if (name === "accountId") {
        for (let item of this.accountData) {
          console.log(item);
          if (item.code == value) {
            found = true;
            console.log(item, item.id);
            this.$set(row, "accountId", item.id);
            this.$set(row, "accountCode", item.code);
            this.$set(row, "accountCnName", item.cnName);
            this.$set(row, "accountEnName", item.enName);
            this.$set(row, "accountFullName", item.fullName);
            this.$set(row, "accountLevel", item.level);
            this.$set(row, "accountProperty", item.property);
            this.$set(row, "dc", item.dc);

            // 币种
            this.$set(row, "curCode", item.curCode === "USD" ? item.curCode : "CNY");
            // 汇率
            this.$set(row, "exrate", item.exrate);
            // 其他
            this.$set(row, "isForeign", item.isForeign);
            this.$set(row, "isQuantity", item.isQuantity);
            this.$set(row, "isCorp", item.isCorp);
            this.$set(row, "isDept", item.isDept);
            this.$set(row, "isEmpl", item.isEmpl);
            this.$set(row, "isItem", item.isItem);
            this.$set(row, "itemClassifyId", item.itemClassifyId);
            this.$set(row, "itemClassify", item.itemClassify);

            this.$set(row, "isDc", item.isDc);
            this.$set(row, "isArAp", item.isArAp);
            // 打开弹窗
            this.$emit("auxiliaryAccountingfun", row);
          }
        }
        if (!found) {
          console.log("not found");
          this.$set(row, "accountId", 0);
          this.$set(row, "accountCode", "");
          this.$set(row, "accountCnName", "");
          this.$set(row, "accountEnName", "");
          this.$set(row, "accountFullName", "");
          this.$set(row, "accountLevel", 0);
          this.$set(row, "accountProperty", 0);
          this.$set(row, "dc", "");

          // 币种
          this.$set(row, "curCode", "");
          // 汇率

          // 其他
          this.$set(row, "isForeign", 0);
          this.$set(row, "isQuantity", 0);
          this.$set(row, "isCorp", 0);
          this.$set(row, "isDept", 0);
          this.$set(row, "isEmpl", 0);
          this.$set(row, "isItem", 0);
          this.$set(row, "itemClassifyId", 0);
          this.$set(row, "itemClassify", "");

          this.$set(row, "isDc", 0);
          this.$set(row, "isArAp", 0);

          this.$set(row, "exrate", 0);
        }

        if (row.curCode === "USD") {
          bcurrencyGetExrate({
            date: this.assemblyForm.voucherDate
              ? this.assemblyForm.voucherDate.slice(0, 10) + " 00:00:00"
              : dateFormat(new Date(), "yyyy-MM-dd") + " 00:00:00", // 凭证日期
            dc: row.dc,
            type: 1
          }).then(res => {
            for (let item of res.data.data) {
              if (item.code === row.curCode) {
                this.$set(row, "exrate", this.forceNumber(item.exrate, 4));
                this.$set(row, "amountDr", this.forceNumber(row.amountDr, 2));
                this.$set(row, "amountCr", this.forceNumber(row.amountCr, 2));
                this.$set(row, "amountDrUsd", this.forceNumber(row.amountDrUsd, 2));
                this.$set(row, "amountCrUsd", this.forceNumber(row.amountCrUsd, 2));
                if (row.amountDrUsd !== 0.0) {
                  this.$set(row, "amountCrUsd", 0.0);
                  this.$set(row, "amountCr", 0.0);
                  this.$set(row, "amountDr", this.forceNumber(row.amountDrUsd * item.exrate, 2));
                } else {
                  this.$set(row, "amountDrUsd", 0.0);
                  this.$set(row, "amountDr", 0.0);
                  this.$set(row, "amountCr", this.forceNumber(row.amountCrUsd * item.exrate, 2));
                }
              }
            }
          });
        } else {
          this.$set(row, "exrate", 0);
          this.$set(row, "amountDrUsd", 0.0);
          this.$set(row, "amountCrUsd", 0.0);
        }
      }

      console.log(row);
    },
    // 表头样式
    tableHeaderCellStyle({ row, column, rowIndex, columnIndex }) {
      return "padding:4px 0px;fontSize:12px;color:#000;background:#ecf5ff;text-align:center";
    },
    // 列表多选
    // 多选选择的数据
    handleSelectionChange(arr) {
      this.$emit("handleSelectionChange", arr);
    },
    // 监听点击表格事件
    rowClick(row, column, event) {
      let refsElTable = this.$refs.tableRef; // 获取表格对象
      if (this.CtrlDown) {
        refsElTable.toggleRowSelection(row); // ctrl多选 如果点击两次同样会取消选中
        return;
      }
      if (this.shiftOrAltDown && this.handleSelectionData.length > 0) {
        // 通过rowIndex判断已选择的行中最上面和最下面的是哪行，再对比按住shift/alt点击的当前行得到新的最上面和最下面的行，把这两行中间的行进行循环选中。
        let topAndBottom = this.getTopAndBottom(row, this.bottomSelectionRow, this.topSelectionRow);
        refsElTable.clearSelection(); //先清空 不然会导致在这两行中间之外的行状态不变
        for (let index = topAndBottom.top; index <= topAndBottom.bottom; index++) {
          //选中两行之间的所有行
          refsElTable.toggleRowSelection(this.tableData[index], true);
        }
      } else {
        let findRow = this.handleSelectionData.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
        //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
        if (findRow && this.handleSelectionData.length === 1) {
          refsElTable.toggleRowSelection(row, false);
          return;
        }
        // refsElTable.clearSelection(); // 清空之前选择的数据(如果放开，选择之前会变成单选)
        refsElTable.toggleRowSelection(row); // 调用选中行方法
      }
    },
    // 行的 style 的回调方法
    rowStyle({ row, rowIndex }) {
      // 直接在一个对象上定义一个新属性，或者修改一个对象的现有属性，并返回此对象
      // object: 要添加或者修改属性的目标对象；prop: 要定义或修改属性的名称；descript: 是一个对象，里面是我们上述的对象属性的特性；
      Object.defineProperty(row, "rowIndex", {
        //给每一行添加不可枚举属性rowIndex来标识当前行
        value: rowIndex, // 设置age的值，不设置的话默认为undefined
        writable: true, // 表示属性的值true可以修改,false不可以被修改
        enumerable: false // 设置为false表示不能通过 for-in 循环返回
        // configurable: false, // configurable 设置为 false，意味着这个属性不能从对象上删除
      });
    },
    keyDown(event) {
      let key = event.keyCode;
      if (key == 17) this.CtrlDown = true;
      if (key == 16 || key == 18) this.shiftOrAltDown = true;
    },
    keyUp(event) {
      let key = event.keyCode;
      if (key == 17) this.CtrlDown = false;
      if (key == 16 || key == 18) this.shiftOrAltDown = false;
    },
    // 文章说明 https://www.jianshu.com/p/48f2c522d2a2
    getTopAndBottom(row, bottom, top) {
      let n = row.rowIndex,
        mx = bottom.rowIndex,
        mi = top.rowIndex;
      if (n > mx) {
        return {
          top: mi,
          bottom: n
        };
      } else if (n < mx && n > mi) {
        return {
          top: mi,
          bottom: n
        };
      } else if (n < mi) {
        return {
          top: n,
          bottom: mx
        };
      } else if (n == mi || n == mx) {
        return {
          top: mi,
          bottom: mx
        };
      }
    },
    // 给选中行加上current-row这个class类，所以要使用row-class-name这个属性（其实给每一行添加rowIndex也可以用这个属性），
    // 判断方式也是通过判断rowIndex对比
    rowClassName({ row, rowIndex }) {
      let rowName = "",
        findRow = this.handleSelectionData.find(c => c.rowIndex === row.rowIndex);
      if (findRow) {
        rowName = "current-row "; // elementUI 默认高亮行的class类 不用再样式了^-^,也可通过css覆盖改变背景颜色
      }
      return rowName; //也可以再加上其他类名 如果有需求的话
    }
  },
  mounted() {
    // 按住ctrl实现多选 设置监听keydown事件,以及keyup事件，
    addEventListener("keydown", this.keyDown, false);
    addEventListener("keyup", this.keyUp, false);
  },
  beforeDestroy() {
    //解绑
    removeEventListener("keydown", this.keyDown);
    removeEventListener("keyup", this.keyUp);
  },
  computed: {
    //实时得到最上行和最下行
    bottomSelectionRow() {
      if (this.handleSelectionData.length == 0) return null;
      return this.handleSelectionData.reduce((start, end) => {
        return start.rowIndex > end.rowIndex ? start : end;
      });
    },
    topSelectionRow() {
      if (this.handleSelectionData.length == 0) return null;
      return this.handleSelectionData.reduce((start, end) => {
        return start.rowIndex < end.rowIndex ? start : end;
      });
    }
  }
};
</script>

<style scoped>
::v-deep input::-webkit-outer-spin-button,
::v-deep input::-webkit-inner-spin-button {
  -webkit-appearance: none !important;
}
::v-deep input[type="number"] {
  -moz-appearance: textfield !important;
}
::v-deep .el-table td {
  padding: 0;
}
::v-deep .el-table .cell {
  padding-left: 2px !important;
  padding-right: 2px !important;
}
::v-deep .el-input-number .el-input__inner {
  text-align: right;
}
</style>
