<template>
  <div class="p-2 h-full flex flex-col">
    <PageHeader></PageHeader>
    <div class="mb-[10px]">
      <el-card shadow="hover">
        <el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
          <div>
            <el-form-item label="小区" prop="villageId">
              <el-select @change="handleChangeVillage" v-model="queryParams.villageId" placeholder="请选择小区">
                <el-option v-for="(item, index) in villageList" :key="index" :value="item.villageId" :label="item.villageName"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="楼栋" prop="buildingId">
              <el-select @change="handleChangeBuilding" v-model="queryParams.buildingId" placeholder="请选择楼栋">
                <el-option v-for="(item, index) in buildingList" :key="index" :value="item.id" :label="item.buildingName"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="单元" prop="unitNoId">
              <el-select @change="handleChangeUnit" v-model="queryParams.unitNoId" placeholder="请选择单元">
                <el-option v-for="(item, index) in unitList" :key="index" :value="item.unitNoId" :label="item.unitNoName"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item @change="handleChangeHouseNo" label="房号" prop="houseId">
              <el-select v-model="queryParams.houseId" placeholder="请选择房号">
                <el-option-group v-for="group in houseList" :key="group.floorNo" :label="String(group.floorNo) + ' 楼'">
                  <el-option v-for="item in group.houses" :key="item.houseId" :label="item.houseNo" :value="item.houseId" />
                </el-option-group>
              </el-select>
            </el-form-item>
          </div>
          <div>
            <el-form-item label="收费项目" prop="itemId">
              <el-select multiple v-model="queryParams.chargeItemId" placeholder="请选择收费项目">
                <el-option
                  :disabled="item.status === '1'"
                  v-for="(item, index) in chargeItems"
                  :key="index"
                  :value="item.id"
                  :label="item.itemName"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="缴费周期" prop="chargePeriod">
              <el-date-picker
                v-model="chargePeriod"
                type="daterange"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                range-separator="到"
                start-placeholder="开始日期"
                @clear="handleClearChargePeriod"
                end-placeholder="结束日期"
                placeholder="请选择缴费日期"
              />
            </el-form-item>
            <el-form-item label="房屋分类" prop="houseUseTypeId">
              <el-select v-model="queryParams.houseUseTypeId">
                <el-option v-for="item in houseUseTypeList" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
            </el-form-item>
            <el-form-item label="缴费时间" prop="payTime">
              <el-date-picker
                v-model="payTime"
                type="datetimerange"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                range-separator="到"
                start-placeholder="开始日期"
                @clear="handleClearPayTime"
                end-placeholder="结束日期"
                placeholder="请选择缴费日期"
              />
            </el-form-item>
            <el-form-item label="业主姓名" prop="residentName">
              <el-input maxlength="30" v-model.trim="queryParams.residentName" placeholder="请选择业主姓名"></el-input>
            </el-form-item>
            <el-form-item>
              <div style="text-align: right">
                <el-button type="primary" @click="handleQuery">搜索</el-button>
                <el-button @click="resetQuery">重置</el-button>
              </div>
            </el-form-item>
          </div>
        </el-form>
      </el-card>
    </div>
    <div class="actionsBox">
      <div class="tabs-box">
        <div
          class="tabs-items"
          v-for="(item, index) in tabs"
          :key="index"
          :class="{
            active: activeTabs === item.value
          }"
          @click="changeTabs(item.value)"
        >
          {{ item.type }}
        </div>
      </div>
      <div class="actions">
        <el-button @click="handleIncome(false)" :disabled="!single">收费</el-button>
        <el-button @click="printPIaoJuByOnly(false)" :disabled="!printSingle">打印票据</el-button>
      </div>
    </div>
    <el-card class="flex-1" shadow="never">
      <el-table v-loading="loading" border :data="tableData" @selection-change="handleSelectionChange">
        <el-table-column type="selection" fixed="left" width="55" align="center" />
        <el-table-column label="房屋/车位/车辆" fixed="left" align="center" prop="unitNo" width="120">
          <template #default="scope">
            {{ scope.row.unitNo }}
          </template>
        </el-table-column>
        <el-table-column label="收费项目" fixed="left" align="center" prop="billCode" width="120">
          <template #default="scope">
            {{ scope.row.chargeItemName }}
          </template>
        </el-table-column>
        <el-table-column label="收费周期" align="center" prop="periodDisplay" width="280">
          <template #default="scope">
            <span>{{ scope.row.periodDisplay }}</span>
          </template>
        </el-table-column>

        <el-table-column label="单价" width="100" align="center" prop="fixedPrice">
          <template #default="scope">
            <div class="flex justify-center">
              <span>
                {{ scope.row.fixedPrice }}
              </span>
              <span v-if="scope.row.unit"> / </span>
              <dict-tag v-if="scope.row.unit" :options="com_charge_item_unit" :value="scope.row.unit"></dict-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="数量" width="80" align="center" prop="quantity">
          <template #default="scope">
            <span>{{ scope.row.quantity }}</span>
          </template>
        </el-table-column>
        <el-table-column label="应收金额" width="100" align="center" prop="amount" />
        <el-table-column label="缴费状态" width="100" align="center" prop="payStatus">
          <template #default="scope">
            <span v-if="scope.row.payStatus === '0'">未缴纳</span>
            <span v-else-if="scope.row.payStatus === '1'">已缴纳</span>
            <span v-else-if="scope.row.payStatus === '2'">缴纳失败</span>
            <span v-else>部分缴纳</span>
          </template>
        </el-table-column>
        <el-table-column label="应缴金额" width="100" align="center" prop="amount" />
        <el-table-column label="优惠金额" width="100" align="center" prop="singleDiscountAmount" />
        <el-table-column label="实缴金额" width="100" align="center" prop="actualAccount" />
        <el-table-column label="缴费人" width="120" align="center" prop="residentName" />
        <el-table-column label="缴费时间" width="200" align="center" prop="payTime" />
        <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
        <el-table-column label="操作" width="110" align="center" fixed="right" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button link type="primary" v-if="scope.row.payStatus !== '1'" @click="handleIncome(scope.row)" v-has-permi="['bill:bill:edit']"
              >收款</el-button
            >
            <el-button link type="success" v-if="scope.row.payStatus === '1'" @click="printPIaoJuByOnly(scope.row)" v-has-permi="['bill:bill:query']"
              >打印票据</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <div class="footerBox">
        <div class="totalBox">
          <span>合计：</span>
          <span>应收：{{ totalAll.totalAccount }}元</span>
          <span style="padding: 0 20px">实收：{{ totalAll.TotalPaymentAmount }}元</span>
          <span>优惠：{{ totalAll.totalDiscountAmount }}元</span>
        </div>
        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
      </div>
    </el-card>
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="650px" append-to-body>
      <div class="payInfo">
        <div>
          <div class="flex flex-items-center justify-between">
            <span>缴费人： {{ inComeFrom.residentName }}</span>
            <span style="color: #ff9947">待缴纳</span>
          </div>
        </div>
        <div class="flex">
          <span>收费名称： </span>
          <div>
            <div
              v-for="(item, index) in inComeFrom.billResidentId"
              :key="index"
              class="flex flex-items-center"
              style="text-wrap: wrap; margin-bottom: 5px"
            >
              <div class="flex flex-items-center">
                <div style="text-decoration: underline; padding-right: 5px; text-align: center">
                  {{ item.detailsName }} &nbsp;&nbsp;(应缴：￥{{ item.needPayAmount }})
                </div>
                <el-tooltip class="box-item" effect="light" placement="top" v-if="item.payStatus === '3'">
                  <el-icon color="#909399"><QuestionFilled /></el-icon>
                  <template #content>
                    <div style="line-height: 1.8; font-size: 13px; width: 180px">
                      <div style="text-align: right" class="flex justify-between">
                        <span>总金额</span>
                        <span>{{ item.amount }}￥</span>
                      </div>
                      <div style="text-align: right" class="flex justify-between">
                        <span>累计优惠金额</span>
                        <span>− {{ item.singleDiscountAmount }}￥</span>
                      </div>
                      <div style="text-align: right" class="flex justify-between">
                        <span>累计已交金额</span>
                        <span>− {{ item.paidAmount }}￥</span>
                      </div>
                      <div
                        class="flex justify-between cursor-pointer"
                        style="margin-top: 6px; border-top: 1px solid #ccc; text-align: right; padding-top: 6px"
                      >
                        <span>待缴金额</span>
                        <span style="font-weight: bold; color: red">{{ item.needPayAmount }}￥</span>
                      </div>
                    </div>
                  </template>
                </el-tooltip>
              </div>
              <span v-if="item.payStatus === '1'">（已缴费，不计入金额）</span>
            </div>
          </div>
        </div>
        <div>
          <span>应收合计：￥{{ inComeFrom.allCost }}</span>
        </div>
        <div
          :class="{
            DiscountColorRed: gtMoney(totalDiscountAmount, inComeFrom.allCost)
          }"
          class="flex flex-items-center"
        >
          <div>优惠合计：￥{{ totalDiscountAmount }}</div>
          <div v-if="totalDiscountAmount !== totalReadDiscount && totalReadDiscount !== '0' && inComeFrom.discountMethod === 2">
            &nbsp;&nbsp;
            <span>(实际优惠合计：￥{{ totalReadDiscount }})</span>
            <el-tooltip class="box-item" effect="light" placement="top">
              <el-icon color="#909399" style="vertical-align: middle"><QuestionFilled /></el-icon>
              <template #content>
                <span>有账单 应缴费用 不足 优惠金额</span>
              </template>
            </el-tooltip>
          </div>
        </div>
        <div>
          <span>预计实缴合计：￥{{ totalPayAmount }}</span>
        </div>
        <div>
          <span>实际实缴合计：￥{{ payListAllAmount }}</span>
        </div>
      </div>
      <el-form ref="formRef" :model="inComeFrom" label-width="100px">
        <el-form-item label="费用合计" prop="allCost">
          <el-input v-model="inComeFrom.allCost" disabled style="width: 400px">
            <template #suffix>
              <span>元</span>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="缴纳状态" prop="payStatus">
          <el-radio-group v-model="inComeFrom.payStatus">
            <el-radio value="1" label="已缴纳"></el-radio>
            <el-radio value="2" label="部分缴纳"></el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="优惠方式" prop="discountMethod" v-if="inComeFrom.payStatus !== '0'">
          <el-select style="width: 400px" @change="handleChangeDisCountMethod" v-model="inComeFrom.discountMethod" placeholder="请选择">
            <el-option label="不优惠" :value="0"></el-option>
            <el-option label="金额" :value="2"></el-option>
            <el-option label="比例" :value="1"></el-option>
          </el-select>
        </el-form-item>
        <div v-if="inComeFrom.discountMethod !== 0">
          <div v-if="inComeFrom.discountMethod === 2">
            <el-form-item label="单笔优惠金额" prop="discount">
              <el-input style="width: 400px" v-model.trim.number="inComeFrom.discount" @input="debouncedHandleDiscountMoney">
                <template #append>
                  <span>￥</span>
                </template>
              </el-input>
            </el-form-item>
          </div>
          <el-form-item label="优惠比例" prop="discountRate" v-else>
            <el-input
              style="width: 400px"
              v-model.trim.number="inComeFrom.discountRate"
              placeholder="0~100：0=无优惠，80=优惠80%，100=全免"
              @input="debounceDiscountRate"
            >
              <template #append>
                <span>%</span>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item label="总优惠金额" prop="totalDiscountAmount">
            <el-input style="width: 400px" disabled v-model="totalDiscountAmount">
              <template #append>
                <span>￥</span>
              </template>
            </el-input>
          </el-form-item>
        </div>
        <el-form-item label="支付方式" prop="payType" v-if="inComeFrom.payStatus !== '0'">
          <div class="flex-1">
            <div class="flex flex-items-center" v-for="(item, index) in payList" :key="index">
              <div class="flex-1 flex">
                <el-select @change="handleChangePayTypeId($event, index)" v-model="item.payType" placeholder="请选择">
                  <el-option
                    :disabled="isOptionDisabled(dict.value, item.payType)"
                    v-for="dict in com_pay_method"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  ></el-option>
                </el-select>
                <el-input @change="(val: string) => handleChangePay(val, index)" v-model.number.trim="item.payAmount" style="margin: 0 10px">
                  <template #append>￥</template>
                </el-input>
              </div>
              <div style="width: 80px; text-align: left">
                <el-icon
                  color="blue"
                  size="24"
                  v-if="index === payList.length - 1 && payList.length < com_pay_method.length"
                  @click="addPayList"
                  style="margin-right: 10px; cursor: pointer"
                  ><CirclePlus
                /></el-icon>
                <el-icon color="red" style="cursor: pointer" size="24" v-if="payList.length > 1" @click="removePayList(index)"><Delete /></el-icon>
              </div>
            </div>
          </div>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input style="width: 400px" type="textarea" show-word-limit maxlength="100" :rows="5" v-model="inComeFrom.remark"></el-input>
        </el-form-item>
        <div class="flex justify-end">
          <el-button @click="closer">取消</el-button>
          <el-button @click="submitForm" :loading="buttonLoading" type="primary">提交</el-button>
        </div>
      </el-form>
    </el-dialog>
    <el-dialog :title="dialog_print.title" v-model="dialog_print.visible" width="1200px" append-to-body>
      <template #header>
        <div class="flex" style="justify-content: space-between; padding: 0 20px">
          <div class="title">票据打印</div>
          <el-button type="primary" v-print="printOption" :loading="isLoading" @click="conFimPrint">打印</el-button>
        </div>
      </template>
      <div class="printBox" id="printBox-Bill" style="margin: 0; color: rgba(0, 0, 0, 1); padding: 5px">
        <div class="title" style="font-size: 1.2rem; margin-bottom: 10px; text-indent: 5em">{{ print_form.title }}</div>
        <div style="font-size: 12px; display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-gap: 10px; grid-template-rows: 1fr">
          <div>单据日期：{{ print_form.printDate }}</div>
          <div>房号：{{ print_form.HouseName }}</div>
          <div>产权人：{{ print_form.residentName }}</div>
          <div>No.</div>
        </div>
        <div class="tableBox" style="font-size: 10px">
          <table class="printTable" style="border-collapse: collapse; border: 1px solid #000; width: 90%">
            <thead>
              <tr>
                <th style="min-width: 50px">收费项目</th>
                <th>收费标准</th>
                <th>账单时间</th>
                <th style="min-width: 50px">面积</th>
                <th style="min-width: 50px">应收金额</th>
                <th style="min-width: 50px">优免金额</th>
                <th style="min-width: 50px">实收金额</th>
                <th>收款方式</th>
                <th style="min-width: 100px">备注</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item, index) in print_form.detailsList" :key="index">
                <td>{{ item.chargeItemName }}</td>
                <td>{{ item.billName }}</td>
                <td>{{ item.detailsTime }}</td>
                <td>{{ item.useCount }}</td>
                <td>{{ item.account }}</td>
                <td>{{ item.singleDiscountAmount }}</td>
                <td>{{ item.actualAccount }}</td>
                <td>{{ item.payType }}</td>
                <td style="text-wrap: wrap; white-space: wrap">{{ item.remark }}</td>
              </tr>
              <tr>
                <td>合计</td>
                <td></td>
                <td></td>
                <td></td>
                <td>{{ print_form.totalAccount }}</td>
                <td>{{ print_form.totalDiscountAmount }}</td>
                <td>{{ print_form.totalActualAccount }}</td>
                <td></td>
                <td></td>
              </tr>
            </tbody>
          </table>
          <p style="font-size: 10px">说明：本收据收款单位和收款具签章方为有效，本收据手写无效</p>
          <div style="font-size: 12px; margin-bottom: 0; display: flex; align-items: center">
            <div style="flex: 1">交款人：</div>
            <div style="flex: 1; display: flex; align-items: center">
              <span style="white-space: nowrap">收款人： </span>
              <el-input v-model="inHomelyUse" v-if="!isPrint" placeholder="请输入收款人姓名" style="width: 150px"></el-input>
              <span style="white-space: nowrap" v-else> {{ inHomelyUse }}</span>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import PageHeader from '@/components/Pageheader/index.vue';
import pagination from '@/components/Pagination/index.vue';
import DictTag from '@/components/DictTag/index.vue';
import { getBuildinglistAPI, getHouselistAPI } from '@/api/system/house';
import { getCommunitylistAPI } from '@/api/system/community';
import { billEdit, billlistType, billPrint, BillPrintType, billQuery } from '@/api/system/SdbCashier';
import { listChargeItem } from '@/api/system/SdbChargeItem';
import { ref } from 'vue';
import { add, div, eq, eqMoney, gtMoney, ltMoney, minMoney, moneyAdd, mul, sub, sum, toBig } from '@/utils/money';
import { BuildingUnitlist, BuildingVo, FloorsType } from '@/api/system/house/type';
import { ChargeItemVO } from '@/api/system/SdbChargeItem/type';
import { communitylist_rows_type } from '@/api/system/community/type';
import { debounce } from '@/utils';
import { listHouseUseType_add_house } from '@/api/system/houseUse';
import { CirclePlus, Delete, QuestionFilled } from '@element-plus/icons-vue';
import { useUserStore } from '@/store/modules/user';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_pay_method, com_charge_item_unit } = toRefs<any>(proxy?.useDict('com_pay_method', 'com_charge_item_unit'));

const userStore = useUserStore();
const loading = ref(false);
const ids = ref<Array<billlistType>>([]);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const activeTabs = ref(null);
const tabs = [
  {
    value: null,
    type: '全部'
  },
  {
    value: 0,
    type: '待缴纳'
  },
  {
    value: 1,
    type: '已缴纳'
  },
  {
    value: 3,
    type: '部分缴纳'
  }
];
const villageId = localStorage.getItem('villageid') ?? undefined;
const queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  // 收款状态
  payStatus: null,
  // 小区id
  villageId: villageId,
  // 楼栋id
  buildingId: undefined,
  // 单元id
  unitNoId: undefined,
  // 房屋id
  houseId: undefined,
  // 缴费周期
  chargePeriod: undefined,
  // 房屋类型id
  houseUseTypeId: undefined,
  // 缴费时间
  payTime: undefined,
  // 缴费人
  residentName: undefined,
  // 缴费项目id
  chargeItemId: undefined,
  period: undefined,
  // 缴费时间开始
  payTimeBegin: undefined,
  // 缴费时间结束
  payTimeEnd: undefined,
  // 开始时间
  startDate: undefined,
  // 结束时间
  endDate: undefined
});

// 缴费周期
const chargePeriod = ref([]);

// 缴费时间
const payTime = ref([]);
const villageList = ref<communitylist_rows_type[]>([]); // 小区列表
const buildingList = ref<BuildingVo[]>([]); // 楼栋列表
const unitList = ref<BuildingUnitlist[]>([]); // 单元列表
const houseList = ref<FloorsType[]>([]); // 房屋列表
const chargeItems = ref<ChargeItemVO[]>([]);
const tableData = ref([]);
const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});
const houseUseTypeList = ref([]);
function getHouseTypeList() {
  listHouseUseType_add_house().then((res) => {
    houseUseTypeList.value = res.data;
  });
}
// 切换 账单类型
function changeTabs(value: number) {
  activeTabs.value = value;
  queryParams.value.payStatus = value;
  getList();
}
// 选择小区
function handleChangeVillage(val: string) {
  queryParams.value.unitNoId = undefined;
  queryParams.value.buildingId = undefined;
  queryParams.value.chargeItemId = undefined;
  queryParams.value.houseId = undefined;
  buildingList.value = [];
  unitList.value = [];
  if (val) {
    getBuildinglistAPI({
      villageId: val
    }).then((res) => {
      buildingList.value = res.data;
      handleChargeItem(val);
    });
    return;
  }
}
// 获取收费项目
function handleChargeItem(id: string) {
  listChargeItem({
    villageId: id,
    status: '0'
  }).then((res) => {
    chargeItems.value = res.rows;
  });
}
// 选择楼栋
function handleChangeBuilding(val: string): void {
  queryParams.value.unitNoId = undefined;
  queryParams.value.houseId = undefined;
  unitList.value = [];
  getHouselistAPI(val).then((res) => {
    unitList.value = res.data.units;
  });
}
// 选择 单元
function handleChangeUnit(val: string) {
  const find = unitList.value.find((item) => item.unitNoId === val);
  houseList.value = [];
  if (find) {
    houseList.value = find.floors;
  }
}
// 选择房屋
function handleChangeHouseNo() {}

// 清空缴费时间
function handleClearPayTime() {
  payTime.value = [];
}
// 清空缴费周期
function handleClearChargePeriod() {
  chargePeriod.value = [];
}
// 获取列表
function getList() {
  loading.value = true;
  queryParams.value.payTimeBegin = payTime.value[0] ? payTime.value[0] : undefined;
  queryParams.value.payTimeEnd = payTime.value[1] ? payTime.value[1] : undefined;

  queryParams.value.startDate = chargePeriod.value[0] ? chargePeriod.value[0] : undefined;
  queryParams.value.endDate = chargePeriod.value[1] ? chargePeriod.value[1] : undefined;
  billQuery(queryParams.value)
    .then((res) => {
      tableData.value = res.rows;
      total.value = res.total;
      handleSelectBill(res.rows);
    })
    .finally(() => {
      loading.value = false;
    });
}
/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  payTime.value = [];
  chargePeriod.value = [];
  queryParams.value = {
    chargePeriod: undefined,
    payTime: undefined,
    pageNum: 1,
    pageSize: 20,
    payStatus: null,
    villageId: undefined,
    buildingId: undefined,
    unitNoId: undefined,
    houseId: undefined,
    chargeItemId: undefined,
    period: undefined,
    houseUseTypeId: undefined,
    residentName: undefined,
    payTimeBegin: undefined,
    payTimeEnd: undefined,
    startDate: undefined,
    endDate: undefined
  };
  queryParams.value.villageId = villageId;
  handleQuery();
};
// 控制收费 按钮  不能有已缴纳的（后端会校验）
const single = ref(true);
// 控制打印票据的 按钮 不能有收费的
const printSingle = ref(true);
/** 多选框选中数据 */
const handleSelectionChange = (selection: billlistType[]) => {
  ids.value = selection.map((item) => item);
  // 不能全部都是已缴纳的 0待缴纳 1已缴纳  2缴纳失败 3混合缴纳
  single.value = ids.value.every((item) => item.payStatus === '0' || item.payStatus === '3');
  // 必须都要缴费后打印
  printSingle.value = ids.value.every((item) => item.payStatus === '1');
};
const buttonLoading = ref(false);
// 是否多选
let isMore = false;

const inComeFrom = ref({
  allCost: null, // 金额
  billResidentId: [], // 账单id
  /** 0:未缴 1:已缴 2: 缴纳失败 3: 混合缴纳*/
  payStatus: '1',
  /** 0:微信 1:支付宝 2 线下 */
  payType: '0', //
  remark: '', // 备注
  /**优惠方式 0 不优惠 1 比例 2 金额*/
  discountMethod: 0, //
  discountRate: '0', // 优惠比例 10 === 10%
  discount: '0', // 优惠金额
  residentName: '' // 缴费人
});
// 总计算优惠金额
const totalDiscountAmount = ref('0.00');
// 总实际优惠金额
const totalReadDiscount = ref('0.00');
// 总实际支付金额
const totalPayAmount = ref('0.00');

// 初始化
function initInComeFrom() {
  inComeFrom.value = {
    allCost: 0, // 总金额
    billResidentId: [], // 账单id
    payStatus: '1', // 0:未缴 1:已缴 2: 缴纳失败 3: 部分缴纳
    payType: '2', // 0:微信 1:支付宝 2 线下
    remark: '',
    discountMethod: 0, // 优惠方式 0 不优惠 1 比例 2 金额
    discountRate: '0', // 优惠比例 10 === 10%
    discount: '0', // 优惠金额
    residentName: '' // 缴费人
  };
  totalAll.value = {
    totalDiscountAmount: 0,
    TotalPaymentAmount: 0,
    totalAccount: 0
  };
  payList.value = [
    {
      payType: '',
      payAmount: null
    }
  ];
  totalDiscountAmount.value = '0.00';
  totalPayAmount.value = '0.00';
  totalReadDiscount.value = '0.00';
  isMore = false;
}
// 改变优惠方式
function handleChangeDisCountMethod(val: number) {
  inComeFrom.value.discountRate = '0'; // 优惠比例
  inComeFrom.value.discount = '0.00'; // 优惠金额
  totalReadDiscount.value = '0.00'; // 实际优惠金额
  totalDiscountAmount.value = '0.00'; // 总优惠金额
  totalPayAmount.value = inComeFrom.value.allCost; // 总实际付款金额
  if (val === 0) return;
  if (val === 2) {
    // 金额
    handleChangeDiscountMoney(inComeFrom.value.discount);
  } else {
    // 比例
    handleChangeDiscountRate(inComeFrom.value.discount);
  }
}
// 输入折扣固定金额
function handleChangeDiscountMoney(val: string) {
  // 1. 清洗输入：空、纯符号、非数字兜底为0
  const cleanVal = val.trim();
  if (!checkMoney(cleanVal)) {
    return ElMessage.warning('金额格式错误');
  }
  let discount = toBig(cleanVal).toNumber();
  if (Number.isNaN(discount)) discount = 0;
  const allCost = inComeFrom.value.allCost ?? 0;
  if (discount < 0) {
    ElMessage.warning('优惠金额不能为负数');
    return;
  }
  // 折扣为0直接赋值原总价，无需计算
  if (eq(discount, 0)) {
    totalDiscountAmount.value = '0.00';
    totalReadDiscount.value = '0.00';
    totalPayAmount.value = allCost.toString();
    return;
  }

  if (isMore) {
    // 过滤：只保留未支付账单，已支付直接丢弃
    const unPaidList = ids.value.filter((item) => {
      return item.payStatus !== '1';
    });

    // 计算优惠总额
    const allDiscount = mul(unPaidList.length, discount);
    if (gtMoney(allDiscount, inComeFrom.value.allCost)) {
      ElMessage.warning('优惠总金额不能超过总费用');
    }
    // 实际优惠总额
    let readDiscount = 0;
    unPaidList.forEach((item) => {
      readDiscount = add(readDiscount, minMoney(item.needPayAmount, discount));
    });
    totalDiscountAmount.value = `${allDiscount}`;
    totalReadDiscount.value = `${readDiscount}`;
    totalPayAmount.value = sub(allCost, readDiscount).toString();
  } else {
    // 单笔优惠不能超过整体总费用
    if (gtMoney(discount, allCost)) {
      ElMessage.warning('单笔优惠金额不能超过总费用');
    }
    totalDiscountAmount.value = discount.toString();
    totalReadDiscount.value = `${discount}`;
    totalPayAmount.value = sub(allCost, discount).toString();
  }
  validatePayAmountSufficiency();
}

const debouncedHandleDiscountMoney = debounce(handleChangeDiscountMoney, 550);
// 输入折扣固定比例
function handleChangeDiscountRate(val: string) {
  const inputStr = val.trim();
  let discountPercent = toBig(inputStr).toNumber();
  if (Number.isNaN(discountPercent)) discountPercent = 0;

  // 百分比校验
  if (discountPercent < 0 || discountPercent > 100) {
    ElMessage.warning('请输入0-100之间的优惠打折百分比');
    return;
  }
  const allCost = inComeFrom.value.allCost ?? 0;
  const rate = div(discountPercent, 100);
  // 1. 输入0：优惠总额为0，全价支付
  if (eq(rate, 0)) {
    totalDiscountAmount.value = '0.00';
    totalReadDiscount.value = '0.00';
    totalPayAmount.value = allCost;
    return;
  }
  // 2. 输入100：全免价格，免费送
  if (eq(rate, 1)) {
    totalDiscountAmount.value = allCost;
    totalReadDiscount.value = allCost;
    totalPayAmount.value = '0.00';
    return;
  }
  // 批量多选模式
  if (isMore) {
    const unPaidList = ids.value.filter((item) => {
      return item.payStatus !== '1';
    });
    // 总价格
    const sourceTotal = sum(unPaidList.map((item) => item.needPayAmount ?? 0));
    // 优惠总额 = 未付原价总和 - 打折后实付总和
    const discountTotal = mul(sourceTotal, rate);
    // 优惠总额
    totalDiscountAmount.value = discountTotal.toString();
    totalReadDiscount.value = `${discountTotal}`;
    totalPayAmount.value = mul(sourceTotal, 1 - rate).toString();
  } else {
    // 单选单条账单
    totalDiscountAmount.value = mul(allCost, rate).toString();
    totalReadDiscount.value = mul(allCost, rate).toString();
    totalPayAmount.value = mul(allCost, 1 - rate).toString();
  }
  validatePayAmountSufficiency();
}
const debounceDiscountRate = debounce(handleChangeDiscountRate);

function validatePayAmountSufficiency() {
  if (payList.value.length > 0) {
    if (gtMoney(payListAllAmount.value, 0)) {
      payList.value.forEach((item) => (item.payAmount = 0));
      ElMessage.warning(`优惠变更，请重新填写支付金额`);
    }
  }
}

// 收费 --------------------------------------------------------------
/** 收费 */
function handleIncome(row: billlistType | false) {
  initInComeFrom();
  if (row) {
    inComeFrom.value.allCost = row.needPayAmount;
    inComeFrom.value.billResidentId = [row];
    inComeFrom.value.remark = row.remark;
    inComeFrom.value.residentName = row.residentName;
    totalPayAmount.value = row.needPayAmount;
  } else {
    if (ids.value.length <= 0) return ElMessage.warning('请选择账单');
    const set = new Set();
    ids.value.forEach((item) => {
      set.add(item.residentId);
    });
    if (ids.value.some((item) => item.payStatus === '1')) {
      return ElMessage.warning('存在已支付账单，请重新选择');
    }
    if (set.size > 1) {
      ElMessage.warning('缴费人不一致，重新选择');
      return;
    } else if (set.size === 1) {
      inComeFrom.value.remark = '';
      inComeFrom.value.residentName = ids.value[0].residentName;
      ids.value.forEach((item) => {
        inComeFrom.value.billResidentId.push(item);
        if (item.payStatus === '0' || item.payStatus === '3') {
          inComeFrom.value.allCost = moneyAdd(inComeFrom.value.allCost || 0, item.needPayAmount);
        }
      });
      totalPayAmount.value = inComeFrom.value.allCost;
      isMore = true;
    }
  }
  dialog.visible = true;
}
// 关闭模态框
const closer = () => {
  dialog.visible = false;
  dialog.title = '';
  initInComeFrom();
};
// 提交
const submitForm = () => {
  if (!handlePayListIsEmpt()) {
    ElMessage.warning('请填写完整支付方式和支付金额');
    return;
  }
  buttonLoading.value = true;
  // 部分缴纳时 不管
  // 已缴纳时 判断 支付金额 和 预计支付金额 是否相等
  if (inComeFrom.value.payStatus === '1') {
    if (!eqMoney(totalPayAmount.value, payListAllAmount.value)) {
      buttonLoading.value = false;
      return ElMessage.warning('支付金额不足，可选择 部分缴纳 方式');
    }
  }
  const obj = {
    'detailsId': inComeFrom.value.billResidentId.map((item) => item.detailsId),
    'payType': inComeFrom.value.payType,
    'payStatus': inComeFrom.value.payStatus,
    discountMethod: inComeFrom.value.discountMethod, //优惠方式： 0不优惠  1 比例 2 金额
    discountRate: inComeFrom.value.discountRate, //  优惠比例（优惠方式为比例时使用，如 10 表示 10%
    singleDiscountAmount: inComeFrom.value.discount, // 单笔优惠金额（优惠方式为金额时使用
    remark: inComeFrom.value.remark,
    payItems: payList.value
  };
  billEdit(obj)
    .then(() => {
      ElMessage.success('缴费成功');
      getList();
      closer();
    })
    .finally(() => {
      buttonLoading.value = false;
    });
};
//
// 打印票据--------------------------------------------------------------
const isPrint = ref(false);
const dialog_print = reactive<DialogOption>({
  visible: false,
  title: '票据打印'
});
// 收款人
const inHomelyUse = ref('');
// 票据表单
const print_form = ref<BillPrintType>({
  totalDiscountAmount: '',
  totalActualAccount: '',
  'totalAccount': '',
  'residentName': '',
  'detailsList': [],
  'printDate': '',
  'HouseName': '',
  'title': ''
});
// 打印票据
function printPIaoJuByOnly(row: billlistType | false) {
  isPrint.value = false;
  inHomelyUse.value = userStore.nickname;
  let query = null;
  if (row) {
    query = {
      'residentId': row.residentId,
      'detailsIds': [row.detailsId]
    };
  } else {
    if (ids.value.length <= 0) {
      return ElMessage.warning('请选择账单！');
    }
    let residentId = null;
    const set = new Set();
    ids.value.forEach((item) => {
      set.add(item.residentId);
    });
    if (set.size > 1) {
      ElMessage.warning('缴费人不一致，重新选择');
      return;
    } else if (set.size === 1) {
      residentId = Array.from(set).at(0);
      query = {
        'residentId': residentId,
        'detailsIds': ids.value.map((item) => item.detailsId)
      };
    }
  }
  billPrint(query).then((res) => {
    print_form.value = res.data;
    dialog_print.visible = true;
  });
}
const isLoading = ref(false);
const printOption = {
  id: 'printBox-Bill',
  popTitle: '票据打印',
  printStyle: `
    @page {
      size: 25cm 10cm;
      margin: 0;
    }
    * {
      box-sizing: border-box;
      margin: 0 !important;
      padding: 0 !important;
    }
    @media print {
      html {
        height: 10cm !important;
        overflow: hidden !important;
      }
      body {
        height: 10cm !important;
        overflow: hidden !important;
        position: absolute;
        left:0;
        top:0;
        transform-origin: top left;
        transform: scale(0.999);
      }
      #printBox-Bill {
        width: 25cm !important;
        height: 10cm !important;
      }
      table {
        border-collapse: collapse;
        width: 100% !important;
        table-layout: auto;
      }
      table th, table td {
        border: 1px solid #333;
        font-size: 10px;
        min-height: 32px;
        text-align: center;
        padding: 1px 2px;
        line-height: 1.1;
        white-space: normal;
      }
    }
  `,
  afterCloseCallback: () => {
    isPrint.value = false;
    isLoading.value = false;
  }
};
// 打印状态恢复函数
function resetPrintState() {
  isPrint.value = false;
  isLoading.value = false;
}
function conFimPrint() {
  isLoading.value = true;
  isPrint.value = true;
  setTimeout(() => {
    // printTicketDiv('printBox-Bill', '票据打印', () => {
    //   console.log('打印完成');
    //   isPrint.value = false;
    //   isLoading.value = false;
    // });
    // printTicket('printBox-Bill', '票据打印', () => {
    //     console.log('打印完成');
    //     isPrint.value = false;
    //     isLoading.value = false;
    // });
    resetPrintState();
  }, 100);
}

onMounted(() => {
  queryParams.value.villageId = villageId;
  getList();
  getHouseTypeList();
  // 全部小区
  getCommunitylistAPI().then((res) => {
    villageList.value = res.rows;
    handleChangeVillage(queryParams.value.villageId);
  });
});

// 总 表单
const totalAll = ref({
  totalDiscountAmount: 0,
  TotalPaymentAmount: 0,
  totalAccount: 0
});
// 多选时 统计总金额，优惠总金额，实付总金额
function handleSelectBill(val: billlistType[]) {
  totalAll.value.totalAccount = sum(val.map((item) => item.amount ?? 0));
  totalAll.value.TotalPaymentAmount = sum(val.map((item) => item.actualAccount ?? 0));
  totalAll.value.totalDiscountAmount = sum(val.map((item) => item.singleDiscountAmount ?? 0));
}
function handleChangePayTypeId(val: string, index: number) {
  // 【可选兜底校验】防止异常数据出现重复
  const repeatCount = usedPayValues.value.filter((v) => v === val).length;
  if (repeatCount > 1) {
    payList.value[index].payType = null;
  }
}
const usedPayValues = computed(() => {
  return payList.value.map((item) => item.payType).filter((v) => v !== null && v !== undefined && v !== '');
});
const isOptionDisabled = (optVal: string, currentVal: any) => {
  // 当前行自己选中的，不禁用；其他行占用的，禁用
  if (optVal === currentVal) return false;
  return usedPayValues.value.includes(optVal);
};

// 混合支付 列表
const payList = ref([
  {
    payType: '',
    payAmount: null
  }
]);
// 混合支付 总金额
const payListAllAmount = computed(() => {
  return sum(payList.value.map((item) => item.payAmount ?? 0));
});
// 添加支付方式
function addPayList() {
  payList.value.push({
    payType: '',
    payAmount: null
  });
}
// 移除支付方式
function removePayList(index: number) {
  payList.value.splice(index, 1);
}
// 数据框改变时 检测数据是否大于 总金额
function handleChangePay(val: string, index: number = -1) {
  if (!checkMoney(val)) {
    ElMessage.warning('金额格式错误');
    payList.value[index].payAmount = null;
    return;
  }
  if (gtMoney(payListAllAmount.value, totalPayAmount.value)) {
    ElMessage.warning('输入金额 总和 不能大于 总实缴金额');
    if (index > -1) {
      payList.value[index].payAmount = 0;
      // 自动回填
      payList.value[index].payAmount = sub(totalPayAmount.value, payListAllAmount.value);
    }
  }
  // 已缴纳状态时，输入金额 总和 不能小于 总实缴金额
  if (inComeFrom.value.payStatus === '1') {
    if (ltMoney(payListAllAmount.value, totalPayAmount.value)) {
      ElMessage.warning('输入金额 总和 不能小于 总实缴金额');
    }
  }
}

function handlePayListIsEmpt() {
  if (payList.value.length === 0) {
    ElMessage.warning('请添加支付方式');
    return false;
  }
  const invalidIndex = payList.value.findIndex(
    (item) =>
      item.payType === null ||
      item.payType === undefined ||
      item.payType === '' ||
      item.payAmount === null ||
      item.payAmount === undefined ||
      item.payAmount === ''
  );
  if (invalidIndex !== -1) {
    return false;
  }
  return true;
}

// 校验数字
function checkMoney(value: string) {
  if (!value) return false;
  const reg = /^(0|[1-9]\d*)(\.\d{1,2})?$/;
  return reg.test(value);
}
</script>

<style lang="scss" scoped>
.DiscountColorRed {
  color: red;
}

.el-table {
  height: calc(100% - 80px);
}
.actionsBox {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #fff;
  height: 50px;
  box-sizing: border-box;
  padding: 0 20px;
  margin-bottom: 10px;
  border-radius: 5px;
}

.tabs-box {
  display: flex;
  align-items: center;

  .tabs-items {
    width: 70px;
    height: 40px;
    line-height: 40px;
    border-bottom: 2px solid transparent;
    text-align: center;
    font-size: 14px;
    cursor: pointer;
    margin-right: 10px;

    &:hover {
      opacity: 0.5;
      color: #1a75ff;
      border-bottom-color: #1a75ff;
    }
    &.active {
      border-bottom-color: #1a75ff;
      color: #1a75ff;
    }
  }
}
.payInfo {
  color: rgba(0, 0, 0, 1);
  margin-top: 20px;
  padding-bottom: 10px;
  margin-bottom: 30px;
  border-bottom: 1px solid #d2d2d2;
  & > div {
    margin-bottom: 10px;
  }
}

.printBox {
  .tableBox {
    .printTable {
      th,
      td {
        text-align: center;
        height: 40px;
        border: 1px solid #000;
      }
    }
  }
}

.footerBox {
  display: flex;
  align-items: center;
  justify-content: space-between;
  .totalBox {
    font-size: 14px;
  }
}
</style>
