<template>
  <div class="app-container refund-reason-page">
    <el-card shadow="never" class="refund-reason-page__filter">
      <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
        <el-form-item label="一级原因" prop="reasonName">
          <el-input
            v-model="queryParams.reasonName"
            placeholder="请输入一级原因名称"
            clearable
            size="small"
            style="width: 220px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
      <p v-show="showSearch" class="refund-reason-page__hint">
        <i class="el-icon-info" />
        点击每行左侧箭头展开查看二级原因；同一时间仅展开一行，便于逐层浏览。
      </p>
    </el-card>

    <el-card shadow="never" class="refund-reason-page__table-card">
      <el-row :gutter="10" class="mb8">
        <el-col :span="1.5">
          <el-button
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
            v-hasPermi="['store:refundReason:add']"
          >新增一级原因</el-button>
        </el-col>
        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
      </el-row>

      <el-table
        ref="refundReasonTable"
        v-loading="loading"
        :data="refundReasonList"
        row-key="id"
        :expand-row-keys="expandedRowKeys"
        border
        stripe
        size="small"
        class="refund-reason-table"
        :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
        @expand-change="handleExpandChange"
      >
        <el-table-column type="expand" width="46">
          <template slot-scope="props">
            <div class="refund-expand-panel">
              <div class="refund-expand-panel__head">
                <span class="refund-expand-panel__title">
                  <i class="el-icon-tickets" />
                  下属二级原因
                </span>
                <span class="refund-expand-panel__parent">「{{ props.row.reasonName }}」</span>
                <el-tag size="mini" type="info" effect="plain">共 {{ props.row.childrenCount || 0 }} 条</el-tag>
              </div>
              <el-table
                :key="'refund-child-' + props.row.id"
                class="refund-reason-nested-table"
                row-key="id"
                :data="props.row.children"
                size="mini"
                border
                v-loading="props.row.loading"
                empty-text="暂无二级原因，可在该行操作列点击「新增二级原因」进行维护"
              >
                <el-table-column label="序号" type="index" width="56" align="center" />
                <el-table-column label="二级原因" prop="reasonName" min-width="160" show-overflow-tooltip />
                <el-table-column label="状态" align="center" prop="status" width="88">
                  <template slot-scope="scope">
                    <el-tag v-if="scope.row.status === 1" type="success" size="mini">正常</el-tag>
                    <el-tag v-else type="danger" size="mini">禁用</el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="操作" align="center" width="168" fixed="right">
                  <template slot-scope="scope">
                    <el-button
                      size="mini"
                      type="text"
                      icon="el-icon-edit"
                      @click="handleUpdateChild(scope.row, props.row)"
                      v-hasPermi="['store:refundReason:edit']"
                    >修改</el-button>
                    <el-button
                      size="mini"
                      type="text"
                      icon="el-icon-delete"
                      class="refund-text-danger"
                      @click="handleDeleteChild(scope.row, props.row)"
                      v-hasPermi="['store:refundReason:remove']"
                    >删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="一级原因" prop="reasonName" min-width="160" show-overflow-tooltip />
        <el-table-column label="二级原因数量" align="center" width="110">
          <template slot-scope="scope">
            <el-tag size="mini" type="info" effect="plain">{{ scope.row.childrenCount || 0 }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="status" width="88">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.status === 1" type="success" size="small">正常</el-tag>
            <el-tag v-else type="danger" size="small">禁用</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              v-hasPermi="['store:refundReason:edit']"
            >编辑</el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-plus"
              @click="handleAddChild(scope.row)"
              v-hasPermi="['store:refundReason:add']"
            >新增二级原因</el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              class="refund-text-danger"
              @click="handleDelete(scope.row)"
              v-hasPermi="['store:refundReason:remove']"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>

    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body custom-class="refund-reason-dialog">
      <el-form ref="form" :model="form" :rules="rules" label-width="100px" class="refund-reason-form">
        <el-form-item label="原因名称" prop="reasonName">
          <el-input v-model="form.reasonName" placeholder="请输入原因名称" maxlength="100" show-word-limit />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
            <el-option label="正常" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
        <el-form-item label="二级原因" v-if="form.typeLevel === 1 && form.id == null">
          <div class="refund-dialog-children">
            <el-button type="primary" size="mini" icon="el-icon-plus" @click="addChildReason">添加二级原因</el-button>
            <div v-for="(item, index) in form.childrenReasons" :key="index" class="refund-dialog-children__row">
              <el-input v-model="item.reasonName" placeholder="请输入二级原因名称" />
              <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeChildReason(index)">删除</el-button>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listRefundReason, getChildrenByParentId, getRefundReason, addRefundReason, updateRefundReason, delRefundReason } from "@/api/hisStore/refundReason";

export default {
  name: "RefundReason",
  data() {
    return {
      loading: true,
      showSearch: true,
      total: 0,
      refundReasonList: [],
      title: "",
      open: false,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        reasonName: null,
        typeLevel: 1
      },
      form: {},
      expandedRowKeys: [],
      rules: {
        reasonName: [
          { required: true, message: "原因名称不能为空", trigger: "blur" }
        ],
        status: [
          { required: true, message: "请选择状态", trigger: "change" }
        ]
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    normalizeGetListArg(arg) {
      if (arg != null && typeof arg === "object") {
        return null;
      }
      return arg != null ? arg : null;
    },
    getList(arg) {
      const syncChildrenParentId = this.normalizeGetListArg(arg);
      this.loading = true;
      listRefundReason(this.queryParams).then(response => {
        this.refundReasonList = response.rows.map(item => {
          return {
            ...item,
            children: [],
            loading: false
          };
        });
        this.total = response.total;
        this.loading = false;
        if (syncChildrenParentId != null) {
          const r = this.refundReasonList.find(x => x.id == syncChildrenParentId);
          this.expandedRowKeys = r ? [r.id] : [];
          this.$nextTick(() => {
            this.reloadRowChildren(syncChildrenParentId);
          });
        } else {
          this.expandedRowKeys = [];
        }
      });
    },
    reloadRowChildren(parentId) {
      const row = this.refundReasonList.find(r => r.id == parentId);
      if (!row) {
        return;
      }
      row.loading = true;
      getChildrenByParentId(parentId)
        .then(response => {
          const list = response.data || [];
          row.children = list;
          row.childrenCount = list.length;
        })
        .finally(() => {
          row.loading = false;
        });
    },
    handleExpandChange(row, expandedRows) {
      const isExpanded = expandedRows.some(r => r.id == row.id);
      if (isExpanded) {
        this.expandedRowKeys = [row.id];
        this.reloadRowChildren(row.id);
      } else {
        this.expandedRowKeys = [];
        this.$nextTick(() => {
          row.children = [];
        });
      }
    },
    cancel() {
      this.open = false;
      this.reset();
    },
    reset() {
      this.form = {
        id: null,
        parentId: 0,
        reasonName: null,
        typeLevel: 1,
        status: 1,
        childrenReasons: []
      };
      this.resetForm("form");
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleAdd() {
      this.reset();
      this.form.childrenReasons = [];
      this.open = true;
      this.title = "新增一级原因";
    },
    handleAddChild(row) {
      this.reset();
      this.form.parentId = row.id;
      this.form.typeLevel = 2;
      this.open = true;
      this.title = "新增二级原因";
    },
    addChildReason() {
      this.form.childrenReasons.push({
        reasonName: '',
        status: 1
      });
    },
    removeChildReason(index) {
      this.form.childrenReasons.splice(index, 1);
    },
    handleUpdate(row) {
      this.reset();
      getRefundReason(row.id).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "编辑一级原因";
      });
    },
    handleUpdateChild(row, parent) {
      this.reset();
      getRefundReason(row.id).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "编辑二级原因";
      });
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id != null) {
            updateRefundReason(this.form).then(response => {
              this.msgSuccess("修改成功");
              this.open = false;
              const syncId = this.form.typeLevel === 2 ? this.form.parentId : this.form.id;
              this.getList(syncId);
            });
          } else {
            addRefundReason(this.form).then(response => {
              if (this.form.typeLevel === 1 && this.form.childrenReasons && this.form.childrenReasons.length > 0) {
                const parentId = response.data;
                const promises = this.form.childrenReasons
                  .filter(item => item.reasonName && item.reasonName.trim() !== '')
                  .map(item => {
                    return addRefundReason({
                      parentId: parentId,
                      reasonName: item.reasonName,
                      typeLevel: 2,
                      status: item.status
                    });
                  });
                if (promises.length > 0) {
                  Promise.all(promises).then(() => {
                    this.msgSuccess("新增成功");
                    this.open = false;
                    this.getList(parentId);
                  });
                } else {
                  this.msgSuccess("新增成功");
                  this.open = false;
                  this.getList();
                }
              } else {
                this.msgSuccess("新增成功");
                this.open = false;
                const syncId = this.form.typeLevel === 2 ? this.form.parentId : null;
                this.getList(syncId);
              }
            });
          }
        }
      });
    },
    handleDelete(row) {
      this.$confirm('确定删除该一级原因吗，删除将影响其下属二级原因都被同步删除，请谨慎操作。', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return delRefundReason(row.id);
      }).then(() => {
        this.getList();
        this.msgSuccess("删除成功");
      }).catch(() => {});
    },
    handleDeleteChild(row, parent) {
      this.$confirm('是否确认删除该二级原因？', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return delRefundReason(row.id);
      }).then(() => {
        this.reloadRowChildren(parent.id);
        this.msgSuccess("删除成功");
      }).catch(() => {});
    }
  }
};
</script>

<style scoped>
.refund-reason-page__filter {
  margin-bottom: 12px;
}

.refund-reason-page__filter >>> .el-card__body {
  padding-bottom: 8px;
}

.refund-reason-page__hint {
  margin: 0 0 4px;
  padding: 8px 12px;
  font-size: 12px;
  line-height: 1.5;
  color: #909399;
  background: #f4f8ff;
  border-radius: 4px;
  border: 1px solid #d9ecff;
}

.refund-reason-page__hint .el-icon-info {
  margin-right: 6px;
  color: #409eff;
}

.refund-reason-page__table-card >>> .el-card__body {
  padding-top: 16px;
}

.refund-reason-table >>> .el-table__expanded-cell {
  padding: 0;
  background: transparent;
}

.refund-expand-panel {
  padding: 14px 16px 16px 20px;
  margin: 4px 12px 12px 8px;
  background: linear-gradient(180deg, #f8fafc 0%, #f0f4f8 100%);
  border-radius: 6px;
  border: 1px solid #e4e7ed;
  border-left: 3px solid #409eff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

.refund-expand-panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.refund-expand-panel__title {
  font-size: 13px;
  font-weight: 600;
  color: #303133;
}

.refund-expand-panel__title .el-icon-tickets {
  margin-right: 6px;
  color: #409eff;
}

.refund-expand-panel__parent {
  font-size: 12px;
  color: #606266;
}

.refund-reason-nested-table {
  border-radius: 4px;
  overflow: hidden;
}

/* 避免展开行内嵌套表格误渲染展开列，出现「多一个小箭头」 */
.refund-reason-nested-table >>> .el-table__expand-column {
  display: none !important;
  width: 0 !important;
  min-width: 0 !important;
}

.refund-text-danger {
  color: #f56c6c !important;
}

.refund-dialog-children__row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.refund-dialog-children__row .el-input {
  flex: 1;
  max-width: 400px;
}
</style>

<style>
.refund-reason-dialog .el-dialog__body {
  padding-top: 10px;
  padding-bottom: 8px;
}
</style>
