
<template>
  <el-dialog
    :visible.sync="dialogVisible"
    :title="`管理付款账户 - ${customerName}`"
    width="1200px"
    :close-on-click-modal="false"
    append-to-body
    @closed="handleClosed">
    <!-- 筛选区 -->
    <el-form
      :inline="true"
      size="mini"
      :model="searchForm"
      ref="searchFormRef"
      class="search_form">
      <el-form-item label="账户名称">
        <el-input
          v-model="searchForm.accountName"
          style="width: 160px"
          clearable
          placeholder="请输入账户名称" />
      </el-form-item>
      <el-form-item label="账号">
        <el-input
          v-model="searchForm.accountNumber"
          style="width: 160px"
          clearable
          placeholder="请输入账号" />
      </el-form-item>
      <el-form-item label="账户币种">
        <el-select
          v-model="searchForm.currencyCode"
          style="width: 130px"
          clearable
          placeholder="全部">
          <el-option label="CNY" value="CNY" />
          <el-option label="USD" value="USD" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="success" @click="handleAdd">新增账户</el-button>
      </el-form-item>
    </el-form>

    <!-- 列表 -->
    <div class="table-wrap" v-loading="loading">
      <table-view
        :tableColumns="tableColumns"
        :sourceData="sourceData" />
    </div>
    <div class="pagination">
      <el-pagination
        layout="total, prev, pager, next, jumper"
        background
        :total="pageOptions.total"
        :page-size="pageOptions.pageSize"
        :current-page="pageOptions.currentPage"
        @size-change="sizeChange"
        @current-change="currentChange" />
    </div>

    <!-- 新增/编辑账户 -->
    <el-dialog
      :visible.sync="addEditDialog.visible"
      :title="addEditDialog.title"
      width="450px"
      :close-on-click-modal="false"
      append-to-body>
      <el-form
        :model="addEditForm"
        size="small"
        ref="addEditFormRef"
        label-width="100px">
        <el-form-item label="账户名称" prop="accountName"
          :rules="{ required: true, message: '请输入账户名称', trigger: 'blur' }">
          <el-input
            v-model="addEditForm.accountName"
            style="width: 250px"
            placeholder="请输入账户名称" />
        </el-form-item>
        <el-form-item label="账户币种" prop="currency"
          :rules="{ required: true, message: '请选择账户币种', trigger: 'change' }">
          <el-select
            v-model="addEditForm.currency"
            style="width: 250px"
            :disabled="addEditDialog.type === 'edit'"
            placeholder="请选择账户币种">
            <el-option label="CNY" value="CNY" />
            <el-option label="USD" value="USD" />
          </el-select>
        </el-form-item>
        <el-form-item label="账号" v-if="addEditDialog.type === 'edit'">
          <el-input
            :value="addEditForm.accountNumber"
            style="width: 250px"
            disabled />
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="addEditDialog.visible = false" size="small">取消</el-button>
        <el-button
          type="primary"
          size="small"
          :loading="addEditDialog.loading"
          @click="submitAddEdit">
          确定
        </el-button>
      </span>
    </el-dialog>

    <!-- 手动调整余额 -->
    <el-dialog
      :visible.sync="adjustDialog.visible"
      :title="`手动调整${adjustForm.currency}账户余额`"
      width="400px"
      :close-on-click-modal="false"
      append-to-body>
      <el-form
        :model="adjustForm"
        size="small"
        ref="adjustFormRef"
        label-width="90px">
        <el-form-item label="账户余额" prop="amount"
          :rules="[
            { required: true, message: '请输入余额', trigger: 'blur' },
            {
              validator: validateAmount,
              trigger: 'blur'
            }
          ]">
          <el-input
            v-model="adjustForm.amount"
            placeholder="正数加款、负数扣款，如 100 或 -50"
            @input="handleAmountInput" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input
            v-model="adjustForm.remark"
            placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="adjust-footer">
        <el-button @click="adjustDialog.visible = false" size="small">取消</el-button>
        <el-button
          type="primary"
          size="small"
          :loading="adjustDialog.loading"
          @click="submitAdjust">
          确定
        </el-button>
      </span>
    </el-dialog>

    <!-- 充值记录 -->
    <el-dialog
      :visible.sync="rechargeDialog.visible"
      :title="`${rechargeDialog.accountName}充值记录 `"
      width="1100px"
      :close-on-click-modal="false"
      append-to-body>
      <div class="table-wrap" v-loading="rechargeDialog.loading">
        <table-view
          :tableColumns="rechargeColumns"
          :sourceData="rechargeDialog.list" />
      </div>
      <div class="pagination">
        <el-pagination
          layout="total, prev, pager, next, jumper"
          background
          :total="rechargeDialog.total"
          :page-size="rechargeDialog.pageSize"
          :current-page="rechargeDialog.currentPage"
          @current-change="(p) => loadRechargeRecord(rechargeDialog.accountId, p)" />
      </div>
    </el-dialog>

    <!-- 删除确认 -->
    <el-dialog
      :visible.sync="deleteDialog.visible"
      title="删除付款账户"
      width="450px"
      :close-on-click-modal="false"
      append-to-body>
      <div class="delete-tip">
        <span>{{ deleteDialog.tip }}</span>
      </div>
      <span slot="footer">
        <el-button @click="deleteDialog.visible = false" size="small">取消</el-button>
        <el-button
          type="primary"
          size="small"
          :loading="deleteDialog.loading"
          :disabled="deleteDialog.hasDetail"
          @click="submitDelete">
          确定删除
        </el-button>
      </span>
    </el-dialog>

    <!-- 操作日志 -->
    <el-dialog
      :visible.sync="logDialog.visible"
      :title="`操作日志 - ${logDialog.accountName}`"
      width="650px"
      :close-on-click-modal="false"
      append-to-body>
      <ul class="log-list" v-loading="logDialog.loading">
        <li v-for="item in logDialog.list" :key="item.id">
          <span class="log-time">{{ item.createTime }}</span>
          <span class="log-desc">{{ item.description }}</span>
        </li>
        <li v-if="!logDialog.list.length" class="empty">暂无数据</li>
      </ul>
    </el-dialog>
  </el-dialog>
</template>

<script>
import tableView from '@/common/components/base/tableView.vue'
import { get, post, remove } from '@/common/api/axios'

export default {
  name: 'paymentAccountManageDialog',
  components: { tableView },
  props: {
    visible: { type: Boolean, default: false },
    customerId: { type: [Number, String], default: null },
    customerName: { type: String, default: '' }
  },
  data() {
    return {
      dialogVisible: false,
      loading: false,
      searchForm: {
        accountName: '',
        accountNumber: '',
        currencyCode: ''
      },
      sourceData: [],
      pageOptions: {
        pageSize: 10,
        currentPage: 1,
        total: 0
      },

      // 新增/编辑账户
      addEditDialog: {
        visible: false,
        type: 'add', // add | edit
        title: '新增账户',
        loading: false
      },
      addEditForm: {
        id: null,
        accountName: '',
        accountNumber: '',
        currency: 'CNY'
      },

      // 手动调整
      adjustDialog: {
        visible: false,
        loading: false
      },
      adjustForm: {
        id: null,
        accountName: '',
        currentBalance: 0,
        currency: 'CNY',
        amount: '',
        remark: ''
      },

      // 充值记录
      rechargeDialog: {
        visible: false,
        accountId: null,
        accountName: '',
        list: [],
        total: 0,
        pageSize: 10,
        currentPage: 1,
        loading: false
      },

      // 删除确认
      deleteDialog: {
        visible: false,
        hasDetail: false,
        tip: '',
        id: null,
        accountName: '',
        accountNumber: '',
        loading: false
      },

      // 操作日志
      logDialog: {
        visible: false,
        accountId: null,
        accountName: '',
        list: [],
        loading: false
      }
    }
  },
  computed: {
    tableColumns() {
      return [
        { label: '账户名称', key: 'accountName', minWidth: 160, align: 'center' },
        { label: '账号', key: 'accountNumber', width: 150, align: 'center' },
        {
          label: '账户余额',
          key: 'amount',
          width: 120,
          align: 'center',
          render: (row) => (
            <span style={{ color: row.amount < 0 ? '#F56C6C' : '#67C23A' }}>
              {row.amount}
            </span>
          )
        },
        {
          label: '累计充值金额',
          key: 'accumulatedRecharge',
          width: 130,
          align: 'center'
        },
        {
          label: '欠费金额',
          key: 'arrears',
          width: 110,
          align: 'center',
          render: (row) => (
            <span style={{ color: row.arrears > 0 ? '#F56C6C' : '#909399' }}>
              {row.arrears}
            </span>
          )
        },
        {
          label: '账户币种',
          key: 'currencyCode',
          width: 140,
          align: 'center',
          render: (row) => {
            const colorMap = { CNY: '#E6A23C', USD: '#409EFF' }
            return (
              <el-tag size="small" style={{ color: colorMap[row.currencyCode] }}>
                {row.currencyCode}
                {row.currencyName ? ` ${row.currencyName}` : ''}
              </el-tag>
            )
          }
        },
        { label: '创建人', key: 'creater', width: 100, align: 'center' },
        { label: '创建时间', key: 'createTime', width: 165, align: 'center' },
        { label: '修改时间', key: 'updateTime', width: 165, align: 'center' },
        {
          label: '操作',
          fixed: 'right',
          align: 'center',
          width: 160,
          render: (row) => (
            <div class="op-icons">
              <el-tooltip content="编辑" placement="top">
                <span class="op-item" onClick={() => this.handleEdit(row)}>
                  <img src={require('@/assets/images/edit_yellow.png')} />
                </span>
              </el-tooltip>
              <el-tooltip content="手动调整" placement="top">
                <span class="op-item" onClick={() => this.handleAdjust(row)}>
                  <img src={require('@/assets/images/minus.png')} />
                </span>
              </el-tooltip>
              <el-tooltip content="充值记录" placement="top">
                <span class="op-item" onClick={() => this.handleRechargeRecord(row)}>
                  <img src={require('@/assets/images/recharge_record.png')} />
                </span>
              </el-tooltip>
              <el-tooltip content="删除" placement="top">
                <span
                  class="op-item danger"
                  onClick={() => this.handleDelete(row)}>
                  <img src={require('@/assets/images/delete.png')} />
                </span>
              </el-tooltip>
              <el-tooltip content="操作日志" placement="top">
                <span class="op-item" onClick={() => this.handleOperationLog(row)}>
                  <img src={require('@/assets/images/operation_log.png')} />
                </span>
              </el-tooltip>
            </div>
          )
        }
      ]
    },
    rechargeColumns() {
      return [
        { label: '充值单号', key: 'rechargeOrderNo', width: 160, align: 'center' },
        {
          label: '充值状态',
          key: 'statusName',
          width: 100,
          align: 'center'
        },
        {
          label: '充值方式',
          key: 'transactionTypeName',
          width: 110,
          align: 'center'
        },
        { label: '充值币种', key: 'currency', width: 90, align: 'center' },
        { label: '充值金额', key: 'rechargeAmount', width: 110, align: 'center' },
        { label: '手续费', key: 'fee', width: 90, align: 'center' },
        { label: '入账金额', key: 'creditedAmount', width: 110, align: 'center' },
        { label: '变动前余额', key: 'balanceBefore', width: 110, align: 'center' },
        { label: '变动后余额', key: 'balanceAfter', width: 110, align: 'center' },
        {
          label: '收款备注',
          key: 'remark',
          minWidth: 120,
          align: 'center'
        },
        { label: '创建人', key: 'createName', width: 90, align: 'center' },
        { label: '创建时间', key: 'createTime', width: 165, align: 'center' }
      ]
    }
  },
  watch: {
    visible(v) {
      this.dialogVisible = v
      if (v) {
        this.searchForm = { accountName: '', accountNumber: '', currencyCode: '' }
        this.pageOptions.currentPage = 1
        this.loadList()
      }
    },
    dialogVisible(v) {
      // 弹框被关闭时（点 X / 遮罩 / ESC），同步回父组件，保证再次打开可正常触发
      if (!v) {
        this.$emit('update:visible', false)
      }
    }
  },
  methods: {
    // 列表
    loadList() {
      this.loading = true
      post('customer/account/page-list', {
        customerId: this.customerId,
        ...this.searchForm,
        currentPage: this.pageOptions.currentPage,
        pageSize: this.pageOptions.pageSize
      })
        .then((res) => {
          if (res.code === 200) {
            this.sourceData = res.data.records
            this.pageOptions.total = res.data.total
          }
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleSearch() {
      this.pageOptions.currentPage = 1
      this.loadList()
    },
    sizeChange(size) {
      this.pageOptions.pageSize = size
      this.pageOptions.currentPage = 1
      this.loadList()
    },
    currentChange(page) {
      this.pageOptions.currentPage = page
      this.loadList()
    },

    // 新增/编辑
    handleAdd() {
      this.addEditForm = {
        id: null,
        accountName: '',
        accountNumber: '',
        currency: 'CNY'
      }
      this.addEditDialog.type = 'add'
      this.addEditDialog.title = '新增账户'
      this.addEditDialog.visible = true
      this.$nextTick(() => {
        this.$refs.addEditFormRef?.clearValidate()
      })
    },
    // 快速新增（基于当前行币种预填）
    handleQuickAdd(row) {
      const currency = row?.currencyCode || 'CNY'
      this.addEditForm = {
        id: null,
        accountName: '',
        accountNumber: '',
        currency
      }
      this.addEditDialog.type = 'add'
      this.addEditDialog.title = '新增账户'
      this.addEditDialog.visible = true
      this.$nextTick(() => {
        this.$refs.addEditFormRef?.clearValidate()
      })
    },
    handleEdit(row) {
      this.addEditForm = {
        id: row.id,
        accountName: row.accountName,
        accountNumber: row.accountNumber,
        currency: row.currencyCode
      }
      this.addEditDialog.type = 'edit'
      this.addEditDialog.title = '编辑账户'
      this.addEditDialog.visible = true
      this.$nextTick(() => {
        this.$refs.addEditFormRef?.clearValidate()
      })
    },
    submitAddEdit() {
      this.$refs.addEditFormRef.validate((valid) => {
        if (!valid) return
        this.addEditDialog.loading = true
        const params =
          this.addEditDialog.type === 'add'
            ? {
                customerId: this.customerId,
                accountName: this.addEditForm.accountName,
                currencyCode: this.addEditForm.currency
              }
            : {
                id: this.addEditForm.id,
                accountName: this.addEditForm.accountName,
                currencyCode: this.addEditForm.currency
              }
        const request =
          this.addEditDialog.type === 'add'
            ? post('customer/account/add', params)
            : post('customer/account/update', params)
        request
          .then((res) => {
            if (res.code === 200) {
              this.$message.success(res.message || '操作成功')
              this.addEditDialog.visible = false
              this.loadList()
            }
          })
          .finally(() => {
            this.addEditDialog.loading = false
          })
      })
    },

    // 手动调整
    handleAdjust(row) {
      this.adjustForm = {
        id: row.id,
        accountName: row.accountName,
        currentBalance: row.amount,
        currency: row.currencyCode,
        amount: '',
        remark: ''
      }
      this.adjustDialog.visible = true
      this.$nextTick(() => {
        this.$refs.adjustFormRef?.clearValidate()
      })
    },
    // 金额输入过滤：仅允许数字、小数点和开头负号，最多两位小数
    handleAmountInput(value) {
      let v = String(value).replace(/[^\d.-]/g, '')
      // 负号仅允许一个且必须在开头
      if (v.indexOf('-') === 0) {
        v = '-' + v.slice(1).replace(/-/g, '')
      } else if (v.indexOf('-') > 0) {
        v = v.replace(/-/g, '')
      }
      // 小数点仅保留一个
      const firstDot = v.indexOf('.')
      if (firstDot > -1) {
        v = v.slice(0, firstDot + 1) + v.slice(firstDot + 1).replace(/\./g, '')
      }
      // 最多两位小数
      const matched = v.match(/^-?\d*(\.\d{0,2})?/)
      this.adjustForm.amount = matched ? matched[0] : ''
    },
    validateAmount(_rule, value, callback) {
      if (value === '' || value === null || value === undefined) {
        callback()
        return
      }
      const num = Number(value)
      if (Number.isNaN(num)) {
        callback(new Error('请输入数字'))
        return
      }
      if (num === 0) {
        callback(new Error('调整金额不能为 0'))
        return
      }

      callback()
    },
    submitAdjust() {
      this.$refs.adjustFormRef.validate((valid) => {
        if (!valid) return
        this.adjustDialog.loading = true
        post('customer/account/manual-adjust', {
          accountId: this.adjustForm.id,
          amount: Number(this.adjustForm.amount),
          remark: this.adjustForm.remark
        })
          .then((res) => {
            if (res.code === 200) {
              this.$message.success(res.message || '调整成功')
              this.adjustDialog.visible = false
              this.loadList()
            }
          })
          .finally(() => {
            this.adjustDialog.loading = false
          })
      })
    },

    // 充值记录
    handleRechargeRecord(row) {
      this.rechargeDialog.accountId = row.id
      this.rechargeDialog.accountName = row.accountName
      this.rechargeDialog.currentPage = 1
      this.loadRechargeRecord(row.id, 1)
      this.rechargeDialog.visible = true
    },
    loadRechargeRecord(accountId, page = 1) {
      this.rechargeDialog.loading = true
      post('customer/account/transaction-list', {
        accountId,
        currentPage: page,
        pageSize: this.rechargeDialog.pageSize
      })
        .then((res) => {
          if (res.code === 200) {
            this.rechargeDialog.list = res.data.records
            this.rechargeDialog.total = res.data.total
            this.rechargeDialog.currentPage = page
          }
        })
        .finally(() => {
          this.rechargeDialog.loading = false
        })
    },

    // 删除
    handleDelete(row) {
      this.deleteDialog = {
        visible: true,
        hasDetail: row.hasDetail,
        tip: row.hasDetail
          ? `您要删除的账户${row.accountName}(${row.accountNumber})存在消费或充值明细，无法进行删除操作！`
          : '删除后无法恢复，确定删除当前选择的账户？',
        id: row.id,
        accountName: row.accountName,
        accountNumber: row.accountNumber,
        loading: false
      }
    },
    submitDelete() {
      if (this.deleteDialog.hasDetail) {
        this.$message.warning('该账户存在账户明细，无法删除')
        return
      }
      this.deleteDialog.loading = true
      remove(`customer/account/delete/${this.deleteDialog.id}`)
        .then((res) => {
          if (res.code === 200) {
            this.$message.success(res.message || '删除成功')
            this.loadList()
          }
        })
        .finally(() => {
          this.deleteDialog.loading = false
          this.deleteDialog.visible = false
        })
    },

    // 操作日志
    handleOperationLog(row) {
      this.logDialog = {
        visible: true,
        accountId: row.id,
        accountName: row.accountName,
        list: [],
        loading: true
      }
      get(`customer/account/logs/${row.id}`)
        .then((res) => {
          if (res.code === 200) {
            this.logDialog.list = res.data || []
          }
        })
        .finally(() => {
          this.logDialog.loading = false
        })
    },

    handleClosed() {
      this.sourceData = []
      this.pageOptions = { pageSize: 10, currentPage: 1, total: 0 }
      // 关闭主弹框时强制关闭所有内嵌子弹框，避免残留遮罩影响再次打开
      this.addEditDialog.visible = false
      this.adjustDialog.visible = false
      this.rechargeDialog.visible = false
      this.deleteDialog.visible = false
      this.logDialog.visible = false
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-dialog__body {
  padding: 15px 20px 0;
}
.search_form {
  margin-bottom: 5px;
  ::v-deep .el-form-item {
    margin-bottom: 10px;
  }
}
.table-wrap {
  background: #fff;
  padding: 5px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  min-height: 500px;
}
.pagination {
  text-align: right;
  margin-top: 10px;
}
.op-icons {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px;
  .op-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    width: 24px;
    height: 24px;
    img {
      width: 22px;
      height: 22px;
      vertical-align: middle;
    }
    &.danger {
      img {
        filter: hue-rotate(0deg);
      }
    }
    &:hover {
      opacity: 0.85;
      transform: scale(1.05);
      transition: all 0.2s;
    }
  }
}
.adjust-footer {
  display: flex;
  justify-content: center;
  align-items: center;
  padding-top: 10px;
  ::v-deep .el-button {
    min-width: 90px;
  }
}
.delete-tip {
  display: flex;
  align-items: center;
  font-size: 14px;
  color: #303133;
  padding: 10px 0;
  i {
    color: #f56c6c;
    font-size: 24px;
    margin-right: 10px;
  }
}
.log-list {
  max-height: 500px;
  overflow-y: auto;
  padding: 0 5px;
  li {
    line-height: 28px;
    color: #303133;
    font-size: 13px;
    padding: 6px 0;
    display: flex;
    align-items: center;
    .log-type {
      flex-shrink: 0;
      margin-right: 8px;
    }
    .log-name {
      color: #409eff;
      width: 80px;
      flex-shrink: 0;
      margin-right: 8px;
    }
    .log-desc {
      flex: 1;
      color: #606266;
    }
    .log-time {
      color: #909399;
      width: 160px;
      flex-shrink: 0;
    }
    &.empty {
      justify-content: center;
      color: #c0c4cc;
    }
  }
}
</style>
