<template>
  <view class="report-export-page">
    <view class="report-export-search-bar-container">
      <view class="report-export-search-bar">
        <view class="report-export-search-input-wrap">
          <image src="../../../static/images/search.png" mode="scaleToFill" class="report-export-search-icon" />
          <input class="report-export-search-input" v-model="keyword" placeholder="搜索公司" />
          <view class="report-export-search-btn" @click="onSearch">搜索</view>
        </view>
        <view class="report-export-filter-btn" @click="onFilter">
          <image src="../../../static/images/filter.png" mode="scaleToFill" class="report-export-filter-icon" />
          <text class="report-export-filter-text">筛选</text>
        </view>
      </view>
    </view>
    <view class="scan-rate-ranges-container">
      <view class="scan-rate-ranges">
        <view class="scan-rate-ranges-content">
          <view v-for="(value, i) in options.status" :key="value" class="scan-rate-range" :class="{
            'scan-rate-active': filterForm.status == value,
          }" @click.stop="pickFilterOption('status', value)">{{ value }}</view>
        </view>
      </view>
    </view>
    <view v-if="loading" class="report-export-list-scroll" :style="{ height: 'auto' }">
      <view class="report-export-loading-row">
        <view class="report-export-loading-wrapper">
          <image class="report-export-loading-icon" src="../../../static/images/loading.png" />
        </view>
      </view>
    </view>
    <scroll-view v-else-if="list.length > 0" class="report-export-list-scroll" scroll-y="true"
      :style="{ height: listViewHeight }" @scrolltolower="onScrollToLower">
      <view class="report-export-item-card" v-for="(item, i) in list" :key="item.id">
        <view class="report-export-item-header">
          <text class="report-export-item-title" @click="showModal(item)">{{ getCustomerName(item) }}报表</text>
          <text class="report-export-status" :class="'report-export-status-' + item.status">{{
            getStatusText(item.status) }}</text>
        </view>
        <view class="report-export-item-row">创建人：{{ item.userName || "" }}</view>
        <view class="report-export-item-row">品种：{{ item.physicName || "" }}</view>
        <view class="report-export-item-row">规格：{{ item.pkgSpec || "" }}</view>
        <view class="report-export-item-row">时间：{{ formatDate(item.beginTime) }}～{{
          formatDate(item.endTime)
        }}</view>
        <!-- <view
          class="report-export-item-row"
          style="color: red"
          v-if="item.remark !== ''"
          >任务失败：{{ item.remark || "" }}</view
        > -->
        <view v-if="item.status == 2" class="report-export-progress-wrap">
          <view class="report-export-progress">
            <view class="report-export-progress-fill" :style="{ width: `${item.progress || 10}%` }"></view>
            <text class="report-export-progress-text">{{
              item.progress || 10
              }}</text>
          </view>
        </view>
        <view v-if="item.status == 1" class="report-export-action-row">
          <view class="report-export-action-btn report-export-primary" @click="onStart(item)">
            确认开始计算
          </view>
        </view>
        <view v-else-if="item.status == 3" class="report-export-action-row">
          <view class="report-export-action-btn report-export-info" @click="toDetail(item)">查看</view>
          <view class="report-export-action-btn report-export-primary" @click="onSend(item)">
            导出
          </view>
        </view>
      </view>
      <view class="report-export-loading-row" v-if="hasmore">
        <view class="report-export-loading-wrapper">
          <image class="report-export-loading-icon" src="../../../static/images/loading.png" />
        </view>
      </view>
    </scroll-view>
    <EmptyView v-else text="暂无导出任务" />

    <view class="report-export-footer">
      <view class="report-export-footer-btn" @click="onCreate">新建任务</view>
    </view>

    <view v-show="createModalOpen || filterModalOpen || emailModalOpen" class="report-export-create-modal-mask"
      @click="closeCreate">
    </view>
    <view class="report-export-create-modal" :class="{ 'report-export-create-modal--open': createModalOpen }">
      <view class="report-export-create-modal-title" @click="closeDropdownAll">
        <text>{{ taskTitle }}</text>
        <view class="report-export-create-modal-close" @click.stop="closeCreate">×</view>
      </view>
      <view class="report-export-create-modal-body" :style="{ paddingBottom: 0 }" @click="closeDropdownAll">
        <scroll-view scroll-y="true" :style="{
          height: '750rpx',
          paddingBottom: '20rpx',
        }">
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">省份</text>
            <view class="report-export-create-modal-inputwrap"
              @click.stop="modalType !== 'read' && openDropdown('region')">
              <view class="report-export-create-modal-static">{{
                form.region && form.region.regionName
                  ? form.region.regionName
                  : "请选择省份"
              }}</view>

              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>

              <view class="report-export-create-modal-dropdown" v-if="dropdown.region" @click.stop
                :style="dropdownPosStyle()">
                <view class="report-export-dropdown-search-row">
                  <input class="report-export-dropdown-search-input" v-model="searchForm.region"
                    :disabled="modalType === 'read'" @input="modalType !== 'read' && onInput('region')"
                    @focus="onSearchFocus" @blur="onSearchBlur" />
                </view>
                <scroll-view class="report-export-create-modal-dropdown-list" scroll-y>
                  <view class="report-export-create-modal-dropdown-item" v-for="(op, i) in filteredOptions('region')"
                    :key="'r-' + i" @click.stop="
                      modalType !== 'read' && pickOption('region', op)
                      ">{{ op.regionName }}
                  </view>
                  <view v-if="
                    !filteredOptions('region') ||
                    filteredOptions('region').length === 0
                  " class="report-export-create-modal-dropdown-item">
                    未查找到该省份</view>
                </scroll-view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">客户类型</text>
            <view class="report-export-create-modal-inputwrap"
              @click.stop="modalType !== 'read' && openDropdown('customerType')">
              <view class="report-export-create-modal-static">{{
                form.customerType || "请选择客户类型"
                }}</view>
              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>
              <view class="report-export-create-modal-dropdown" v-if="dropdown.customerType" @click.stop
                :style="dropdownPosStyle()">
                <view class="report-export-create-modal-dropdown-item"
                  v-for="(op, i) in filteredOptions('customerType')" :key="'t-' + i" @click.stop="
                    modalType !== 'read' && pickOption('customerType', op)
                    ">{{ op }}</view>
                <view v-if="filteredOptions('customerType').length === 0"
                  class="report-export-create-modal-dropdown-item">未查找到该客户类型</view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">客户</text>
            <view class="report-export-create-modal-inputwrap"
              @click.stop="modalType !== 'read' && openDropdown('customer')">
              <view class="report-export-create-modal-static" :style="{ maxHeight: 'auto', overflowY: 'visible' }">
                <block v-if="Array.isArray(form.customer) && form.customer.length">
                  <view :style="{
                    maxHeight: '100rpx',
                    overflowY: 'auto',
                    paddingRight: '40rpx',
                  }">
                    <text v-for="(op, i) in form.customer" :key="'cust-tag-' + i" class="customer-chip">
                      {{ op.customerName }}
                      <text class="customer-chip-close" @click.stop="
                        modalType !== 'read' &&
                        removeCustomer(op.customerName)
                        ">×</text>
                    </text>
                  </view>
                </block>
                <text v-else>请选择客户</text>
                <text v-if="
                  form.customer &&
                  form.customer.length &&
                  modalType !== 'read'
                " class="customer-clear-all" @click.stop="modalType !== 'read' && clearAllCustomers()">×</text>
              </view>
              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>
              <view class="report-export-create-modal-dropdown" v-if="dropdown.customer" @click.stop :style="[
                dropdownPosStyle(),
                { maxHeight: 'none', overflow: 'visible' },
              ]">
                <view class="report-export-dropdown-search-row">
                  <input class="report-export-dropdown-search-input" v-model="customerSearch"
                    :disabled="modalType === 'read'" @input="modalType !== 'read' && onInput('customer')"
                    @focus="onSearchFocus" @blur="onSearchBlur" />
                </view>
                <scroll-view class="report-export-create-modal-dropdown-list" scroll-y lower-threshold="20"
                  @scrolltolower="getCustomerOptions">
                  <view class="report-export-create-modal-dropdown-item" :class="{
                    'report-export-selected': isCustomerSelected(
                      op.customerName,
                    ),
                  }" v-for="(op, i) in customers" :key="'cust-' + i" @click.stop="
                    modalType !== 'read' && pickOption('customer', op)
                    ">{{ op.customerName }}</view>
                  <view v-if="customers.length === 0 && !customerHasMore"
                    class="report-export-create-modal-dropdown-item">未查找到该客户</view>
                  <view v-if="customerHasMore" class="report-export-loading-row">
                    <view class="report-export-loading-wrapper">
                      <image class="report-export-loading-icon" src="../../../static/images/loading.png" />
                    </view>
                  </view>
                </scroll-view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">其它客户</text>
            <view
              class="report-export-create-modal-inputwrap"
              @click.stop="modalType !== 'read' && openDropdown('otherCustomer')"
            >
              <view class="report-export-create-modal-static" :style="{ maxHeight: 'auto', overflowY: 'visible' }">
                <block v-if="getOtherCustomerArray().length">
                  <view :style="{
                    maxHeight: '100rpx',
                    overflowY: 'auto',
                    paddingRight: '40rpx',
                  }">
                    <text
                      v-for="(name, i) in getOtherCustomerArray()"
                      :key="'other-cust-tag-' + i"
                      class="customer-chip"
                    >
                      {{ name }}
                      <text
                        class="customer-chip-close"
                        @click.stop="
                          modalType !== 'read' &&
                          removeOtherCustomer(name)
                        "
                      >×</text>
                    </text>
                  </view>
                </block>
                <text v-else>请选择其它客户</text>
                <text
                  v-if="
                    getOtherCustomerArray().length &&
                    modalType !== 'read'
                  "
                  class="customer-clear-all"
                  @click.stop="modalType !== 'read' && clearAllOtherCustomers()"
                >×</text>
              </view>
              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>
              <view
                class="report-export-create-modal-dropdown"
                v-if="dropdown.otherCustomer"
                @click.stop
                :style="[
                  dropdownPosStyle(),
                  { maxHeight: 'none', overflow: 'visible' },
                ]"
              >
                <view class="report-export-dropdown-search-row">
                  <input
                    class="report-export-dropdown-search-input"
                    v-model="otherCustomerSearch"
                    :disabled="modalType === 'read'"
                    @input="modalType !== 'read' && onInput('otherCustomer')"
                    @focus="onSearchFocus"
                    @blur="onSearchBlur"
                    placeholder="请输入客户名称"
                  />
                </view>
                <scroll-view class="report-export-create-modal-dropdown-list" scroll-y>
                  <view
                    class="report-export-create-modal-dropdown-item"
                    :class="{
                      'report-export-selected': isOtherCustomerSelected(op),
                    }"
                    v-for="(op, i) in otherCustomers"
                    :key="'other-cust-' + i"
                    @click.stop="
                      modalType !== 'read' && pickOption('otherCustomer', op)
                    "
                  >{{ op }}</view>
                  <view
                    v-if="!otherCustomerSearch.trim()"
                    class="report-export-create-modal-dropdown-item"
                  >请输入客户名称以搜索客户</view>
                  <view
                    v-else-if="otherCustomers.length === 0 && !otherCustomerLoading"
                    class="report-export-create-modal-dropdown-item"
                  >未查找到该客户</view>
                  <view v-if="otherCustomerLoading" class="report-export-loading-row">
                    <view class="report-export-loading-wrapper">
                      <image class="report-export-loading-icon" src="../../../static/images/loading.png" />
                    </view>
                  </view>
                </scroll-view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">其它客户信用代码</text>
            <view class="report-export-create-modal-inputwrap">
              <input class="report-export-dropdown-search-input" v-model="form.otherCustomerCode"
                placeholder="请填写信用代码(依照其他客户填写顺序用半角逗号隔开)" placeholder-class="report-export-dropdown-other-customer-input"
                :disabled="modalType === 'read'" :style="{ color: '#666', padding: 0, border: 'none' }" />
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">品种</text>
            <view class="report-export-create-modal-inputwrap"
              @click.stop="modalType !== 'read' && openDropdown('product')">
              <view class="report-export-create-modal-static">{{
                form.product?.physicName || "请选择品种"
                }}</view>
              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>
              <view class="report-export-create-modal-dropdown" :style="[{ top: 'auto', bottom: '84rpx' }]"
                v-if="dropdown.product" @click.stop>
                <view class="report-export-dropdown-search-row">
                  <input class="report-export-dropdown-search-input" v-model="searchForm.product"
                    :disabled="modalType === 'read'" @input="modalType !== 'read' && onInput('product')"
                    @focus="onSearchFocus" @blur="onSearchBlur" />
                </view>
                <scroll-view class="report-export-create-modal-dropdown-list" scroll-y
                  @scrolltolower="loadMoreProducts('create')">
                  <view class="report-export-create-modal-dropdown-item" v-for="(op, i) in displayProducts"
                    :key="'p-' + i" @click.stop="
                      modalType !== 'read' && pickOption('product', op)
                      ">{{ op.physicName }}
                  </view>
                  <view v-if="displayProducts?.length === 0" class="report-export-create-modal-dropdown-item">
                    未查找到该品种</view>
                </scroll-view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">规格</text>
            <view class="report-export-create-modal-inputwrap" :class="{
              'report-export-input-disabled':
                !form.product?.drugEntBaseInfoId,
            }" @click.stop="
              modalType !== 'read' &&
              form.product?.drugEntBaseInfoId &&
              openDropdown('pkgSpec')
              ">
              <view class="report-export-create-modal-static">{{
                form.pkgSpec || "请选择规格(请先选择品种)"
                }}</view>
              <view class="report-export-input-arrow" v-if="modalType !== 'read'"></view>
              <view class="report-export-create-modal-dropdown" v-if="dropdown.pkgSpec" @click.stop
                :style="[{ top: 'auto', bottom: '84rpx' }]">
                <view class="report-export-create-modal-dropdown-item" v-for="(op, i) in filteredOptions('pkgSpec')"
                  :key="'t-' + i" @click.stop="
                    modalType !== 'read' && pickOption('pkgSpec', op)
                    ">{{ op }}</view>
                <view v-if="filteredOptions('pkgSpec')?.length === 0" class="report-export-create-modal-dropdown-item">
                  未查找到该品种规格</view>
              </view>
            </view>
          </view>
          <view class="report-export-create-modal-row">
            <text class="report-export-create-modal-label">时间</text>
            <view class="report-export-create-modal-inputwrap" @click="openDatePicker">
              <view class="report-export-create-modal-static report-export-input-simulator" :style="{
                color: dateRange && dateRange.length ? '#333' : '#606266',
              }">
                <uni-icons type="calendar" size="22" color="#c0c4cc"></uni-icons>
                <view style="flex: 1; text-align: center">{{
                  dateRange && dateRange.length ? dateRange[0] : "开始时间"
                }}
                </view>
                <view>-</view>
                <view style="flex: 1; text-align: center">{{
                  dateRange && dateRange.length ? dateRange[1] : "结束时间"
                }}
                </view>
              </view>
              <view class="report-export-input-simulator-clear" v-if="dateRange && dateRange.length"
                @click.stop="dateRange = []">
                <uni-icons type="clear" size="22" color="#c0c4cc"></uni-icons>
              </view>
            </view>
          </view>
        </scroll-view>
        <!-- Hidden Picker for API access -->
        <view style="position: absolute; left: -10000px; top: 0">
          <uni-datetime-picker ref="datePicker" type="daterange" v-model="dateRange" @change="onDateChange" />
        </view>
      </view>
      <view class="report-export-create-modal-footer" @click="closeDropdownAll">
        <view class="report-export-create-modal-btn" @click.stop="confirmCreate" v-if="modalType !== 'read'">{{
          modalType === "create" ? "新建任务" : "修改任务" }}</view>
        <view :style="{ display: 'flex', 'justify-content': 'space-between' }" v-else>
          <view class="report-export-create-modal-btn" :style="currentItem.status !== '2'
            ? { flex: '0 0 40%' }
            : { flex: '0 0 100%' }
            " @click.stop="closeCreate">关闭</view>
          <view class="report-export-create-modal-btn" :style="{ background: 'red', flex: '0 0 40%' }"
            @click.stop="confirmDelete" v-if="currentItem.status !== '2'">删除</view>
        </view>
      </view>
    </view>
    <view class="report-export-create-modal" :class="{ 'report-export-create-modal--open': filterModalOpen }">
      <view class="report-export-create-modal-title" @click="closeDropdownAll">筛选条件</view>
      <view class="report-export-create-modal-body" @click="closeDropdownAll">
        <view class="report-export-create-modal-row">
          <text class="report-export-create-modal-label">品种：</text>
          <view class="report-export-create-modal-inputwrap" @click.stop="openFilterDropdown('product')">
            <view class="report-export-create-modal-static">{{
              filterForm.product?.physicName || "请选择品种"
              }}</view>
            <view class="report-export-create-modal-dropdown" :style="[{ top: 'auto', bottom: '84rpx' }]"
              v-if="filterDropdown.product" @click.stop>
              <view class="report-export-dropdown-search-row">
                <input class="report-export-dropdown-search-input" v-model="filterSearchForm.product"
                  @input="onFilterInput('product')" @focus="onSearchFocus" @blur="onSearchBlur" />
              </view>
              <scroll-view class="report-export-create-modal-dropdown-list" scroll-y
                @scrolltolower="loadMoreProducts('filter')">
                <view class="report-export-create-modal-dropdown-item" v-for="(op, i) in filterDisplayProducts"
                  :key="'prd-' + i" @click.stop="pickFilterOption('product', op)">{{ op.physicName }}</view>
                <view v-if="filterDisplayProducts?.length === 0" class="report-export-create-modal-dropdown-item">
                  未查找到该品种
                </view>
              </scroll-view>
            </view>
          </view>
        </view>
        <!-- <view class="report-export-create-modal-row">
          <text class="report-export-create-modal-label">规格</text>
          <view class="report-export-create-modal-inputwrap"
            :class="{ 'report-export-input-disabled': !filterForm.product?.drugEntBaseInfoId }"
            @click.stop="filterForm.product?.drugEntBaseInfoId && openFilterDropdown('pkgSpec')">
            <view class="report-export-create-modal-static">{{
              filterForm.pkgSpec || "请选择品种规格(请先选择品种)"
            }}</view>
            <view class="report-export-input-arrow"></view>
            <view class="report-export-create-modal-dropdown" v-if="filterDropdown.pkgSpec" @click.stop
              :style="[{ top: 'auto', bottom: '84rpx' }]">
              <view class="report-export-create-modal-dropdown-item" v-for="(op, i) in filteredOptions('pkgSpec')"
                :key="'t-' + i" @click.stop="
                  pickFilterOption('pkgSpec', op)
                  ">{{ op }}</view>
              <view v-if="filteredOptions('pkgSpec')?.length === 0" class="report-export-create-modal-dropdown-item">
                未查找到该品种规格</view>
            </view>
          </view>
        </view> -->
        <view class="report-export-create-modal-row">
          <text class="report-export-create-modal-label">时间：</text>
          <view class="report-export-create-modal-inputwrap" v-if="filterModalOpen">
            <uni-datetime-picker type="daterange" :border="false" v-model="filterDateRange"
              @change="onFilterDateChange" />
          </view>
        </view>
      </view>
      <view class="report-export-create-modal-footer" @click="closeDropdownAll"
        :style="{ display: 'flex', justifyContent: 'space-between' }">
        <view class="report-export-create-modal-btn" :style="{
          background: '#fff',
          color: '#666',
          border: '1rpx solid #dcdfe6',
          flex: '0 0 45%',
        }" @click.stop="resetFilter">重置</view>
        <view class="report-export-create-modal-btn" :style="{ flex: '0 0 45%' }" @click.stop="confirmFilter">确认</view>
      </view>
    </view>
    <view class="report-export-create-modal report-export-create-email-modal"
      :class="{ 'report-export-create-modal--open': emailModalOpen }" v-if="emailModalOpen">
      <view class="report-export-create-modal-title">
        <text>发送至邮箱</text>
        <view class="report-export-create-modal-close" @click.stop="closeEmailModal">×</view>
      </view>
      <view class="report-export-create-modal-body" :style="{ padding: '40rpx' }">
        <!-- <view class="report-export-email-input-wrap" :class="{ 'report-export-input-error': emailError }">
          <input class="report-export-email-input" v-model="emailForm.email" placeholder="请填写邮箱"
            placeholder-style="color: #c0c4cc" @input="emailError = false" />
          <text class="report-export-email-suffix">@999.com.cn</text>
        </view> -->
        <up-input v-model="emailForm.email" border="none" :customStyle="{
          backgroundColor: '#ebf3fb',
          height: '80rpx',
          paddingLeft: '20rpx',
        }" placeholder="请填写邮箱" disabled>
          <template #suffix style="margin-right: 30rpx"> @999.com.cn </template>
        </up-input>
        <text v-if="emailError" class="report-export-error-text">请输入邮箱</text>
      </view>
      <view class="report-export-create-modal-footer" :style="{
        padding: '20rpx 40rpx 40rpx',
        display: 'flex',
        'justify-content': 'space-between',
      }">
        <view class="report-export-create-modal-btn" :style="{
          background: '#fff',
          color: '#666',
          border: '1rpx solid #dcdfe6',
          flex: '0 0 45%',
        }" @click.stop="closeEmailModal">取消</view>
        <view class="report-export-create-modal-btn" :style="{ flex: '0 0 45%' }" @click.stop="handleSendEmail">发送
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import EmptyView from "../../../wigets/empty.vue";
import { formatDate, getPaginatedList } from "../../../utils/utils.js";
import request from "../../../request/index.js";
const customerTypeMap = {
  VIP客户: "VIP",
  二级客户: "二级",
  三级客户: "三级",
};
const customerTypeReverseMap = {
  VIP: "VIP客户",
  二级: "二级客户",
  三级: "三级客户",
};
const statusMap = {
  全部: 0,
  待开始: 1,
  进行中: 2,
  已完成: 3,
};
export default {
  components: {
    EmptyView,
  },
  data() {
    return {
      keyword: "",
      totalCount: 0,
      loading: true,
      hasmore: true,
      fetchLoading: false,
      pageNum: 1,
      pageSize: 10,
      list: [],
      listViewHeight: "400px",
      createModalOpen: false,
      form: {
        region: { regionName: "" },
        customerType: "",
        customer: [],
        product: { physicName: "" },
        otherCustomer: "",
        otherCustomerCode: "",
      },
      dateRange: [],
      computeTimer: null,
      dropdown: {
        region: false,
        customerType: false,
        customer: false,
        otherCustomer: false,
        product: false,
        pkgSpec: false,
      },
      options: {
        region: [],
        customerType: ["VIP客户", "二级客户", "三级客户"],
        product: [],
        pkgSpec: [],
        status: ["全部", "已完成", "待开始", "进行中"],
      },
      // dropdown search inputs (create modal)
      searchForm: {
        region: "",
        product: "",
      },
      // Pagination state for products
      productPage: 0,
      productPageSize: 10,
      displayProducts: [], // Currently displayed products

      // dropdown search inputs (filter modal)
      filterSearchForm: {
        product: "",
      },
      // Pagination state for filter products
      filterProductPage: 0,
      filterDisplayProducts: [],

      customers: [],
      customerPage: 1,
      customerPageSize: 10,
      customerTotal: null,
      customerHasMore: true,
      customerLoading: false,
      customerDebounceTimer: null,
      taskTitle: "创建任务",
      filterModalOpen: false,
      filterForm: {
        product: { physicName: "" },
        status: "全部",
        pkgSpec: "",
      },
      filterDropdown: { product: false, pkgSpec: false },
      filterDateRange: [],
      modalType: "",
      dropdownUpward: false,
      customerSearch: "",
      otherCustomerSearch: "",
      otherCustomers: [],
      otherCustomerLoading: false,
      otherCustomerDebounceTimer: null,
      currentItem: {},
      emailModalOpen: false,
      emailForm: {
        email: "",
      },
      emailError: false,
    };
  },
  created() {
    const userInfo = uni.getStorageSync("userInfo");
    // const staffEmail = userInfo?.ldap || "";
    // this.emailForm.email = staffEmail.split("@")[0];
    const userEmail = uni.getStorageSync('traceCode_useremail')
    this.emailForm.email = userEmail
    console.log("reportExport\index.vue，storage，userInfo", userInfo);
    this.initList();
    this.getProviceList();
    this.getDrugInfoName();
    this.fetchList();
    try {
      uni.onKeyboardHeightChange(({ height }) => {
        this.dropdownUpward = height > 0;
      });
    } catch (e) { }
  },
  computed: {
    taskTitle() {
      if (this.modalType === "create") {
        return "创建任务";
      } else if (this.modalType == "edit") {
        return "修改任务";
      } else if (this.modalType == "read") {
        return "查看任务";
      }
    },
  },
  watch: {
    "form.customerType"(val) {
      this.customerPage = 1;
      this.customerTotal = null;
      this.customerHasMore = true;
      this.customers = [];
      if (this.customerDebounceTimer) clearTimeout(this.customerDebounceTimer);
      this.getCustomerOptions();
    },
    "form.region": {
      handler() {
        this.customerPage = 1;
        this.customerTotal = null;
        this.customerHasMore = true;
        this.customers = [];
        if (this.customerDebounceTimer)
          clearTimeout(this.customerDebounceTimer);
        this.getCustomerOptions();
      },
      deep: true,
    },
    "emailForm.email": {
      handler(newVal, oldVal) {
        if (!oldVal && !newVal && newVal !== oldVal) {
          this.emailError = false;
        } else {
          this.emailError = !newVal;
        }
      },
      deep: true,
    },
    "filterForm.status"(val) {
      this.resetFetch();
    },
  },
  methods: {
    getCustomerName(data = {}) {
      const { customerName = "", otherCustomer = "" } = data;
      let name = customerName || "";
      if (otherCustomer) {
        if (name) {
          name += `,${otherCustomer}`;
        } else {
          name = otherCustomer;
        }
      }
      const arr = name?.split(",");
      if (arr.length == 0) return "--";
      return arr.length == 1
        ? arr[0].trim()
        : `${arr[0].trim()}等${arr.length - 1}家公司`;
    },
    formatDate(date) {
      return formatDate({ date }, "YYYY-MM-DD");
    },
    normalizeDateToYMD(value) {
      if (!value) return "";
      if (typeof value === "string") {
        const trimmed = value.trim();
        if (trimmed.length >= 10) return trimmed.slice(0, 10);
        return trimmed;
      }
      return this.formatDate(value);
    },
    getStatusText(status) {
      if (status == "1") {
        return "导出待开始";
      } else if (status == "2") {
        return "导出进行中";
      } else if (status == "3" || status == "4") {
        return "导出已完成";
      }
      return "未知状态";
    },
    getDrugInfoName() {
      request("/bills/getDrugInfoName", {
        path: "/reportExport/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          const _data = res.data;
          this.options.product = _data;
        }
      });
    },
    getGuigeList(physicName) {
      if (!physicName) return;
      request("/report/getDrugSpec", {
        physicName,
        path: "/reportExport/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          this.options.pkgSpec = res.data || [];
        }
      });
    },
    getProviceList() {
      request("/common/getProviceList", {
        path: "/reportExport/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          const _data = res.data;
          this.options.region = _data;
        }
      });
    },
    getCustomerOptions() {
      if (!this.customerHasMore || this.customerLoading) return;
      this.customerLoading = true;
      request("/customer/info/getCustomerInfo", {
        pageNum: this.customerPage,
        pageSize: this.customerPageSize,
        customerName: this.customerSearch || "",
        customerLevel: customerTypeMap?.[this.form.customerType] || undefined,
        provinceCode: this.form?.region?.regionCode || undefined,
        path: "/reportExport/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          const _data = res.data || {};
          this.customerTotal = _data.total || 0;
          const list = Array.isArray(_data.list) ? _data.list : [];
          this.customers = [...this.customers, ...list];
          if (this.customers.length >= this.customerTotal) {
            this.customerHasMore = false;
          } else {
            this.customerPage++;
            this.customerHasMore = true;
          }
        }
        this.customerLoading = false;
      });
    },
    getOtherCustomerOptions() {
      const keyword = String(this.otherCustomerSearch || "").trim();
      if (!keyword) {
        if (!keyword) this.otherCustomers = [];
        return;
      }
      this.otherCustomerLoading = true;
      request(
        "/report/getEntName?entName=" + encodeURIComponent(keyword),
        {
          entName: keyword,
          path: "/reportExport/index.vue",
        },
        "get",
      ).then((res) => {
        if (res.code == 200) {
          const raw = Array.isArray(res.data)
            ? res.data
            : Array.isArray(res.data?.list)
              ? res.data.list
              : [];
          const names = raw
            .map((item) =>
              typeof item === "string" ? item : item?.entName || item?.customerName || "",
            )
            .map((name) => String(name || "").trim())
            .filter(Boolean);
          this.otherCustomers = Array.from(new Set(names));
        } else {
          this.otherCustomers = [];
        }
        this.otherCustomerLoading = false;
      });
    },
    initList() {
      const info = uni.getSystemInfoSync();
      const h = info.windowHeight || 800;
      this.listViewHeight = Math.max(0, h - 280) + "px";
      // this.list = this.genItems(Math.min(10, this.totalCount));
      // this.animateAll();
    },
    onFilter() {
      this.filterModalOpen = true;
    },
    showModal(item = {}) {
      const map = {
        1: "edit",
        2: "read",
        3: "read",
      };
      this.modalType = map[item?.status] || "create";
      if (this.modalType === "create") {
        this.taskTitle = "创建任务";
      } else {
        if (this.modalType == "edit") {
          this.taskTitle = "修改任务";
        } else if (this.modalType == "read") {
          this.taskTitle = "查看任务";
        }
        const cNames = item.customerName ? item.customerName.split(",") : [];
        const cCodes = item.customerId
          ? String(item.customerId).split(",")
          : [];
        const regionCode = item.regionCode || item.provinceCode || "";
        let regionName = item.regionName || item.provinceName || "";
        if (!regionName && regionCode && Array.isArray(this.options.region)) {
          const regionItem = this.options.region.find(
            (r) => r.regionCode === regionCode || r.provinceCode === regionCode,
          );
          if (regionItem) {
            regionName = regionItem.regionName || regionItem.name || "";
          }
        }
        let customerTypeLabel = "";
        const cType = item.customerType;
        if (cType === 1 || cType === "1") {
          customerTypeLabel = "VIP客户";
        } else if (cType === 2 || cType === "2") {
          customerTypeLabel = "二级客户";
        } else if (cType === 3 || cType === "3") {
          customerTypeLabel = "三级客户";
        } else if (typeof cType === "string" && cType) {
          customerTypeLabel = customerTypeReverseMap[cType] || cType;
        }
        this.form = {
          customer: cCodes.map((i, index) => ({
            customerName: cNames[index],
            customerCode: i,
          })),
          region: {
            regionCode,
            regionName,
          },
          customerType: customerTypeLabel,
          product: {
            physicName: item.physicName,
            drugEntBaseInfoId: item.drugEntBaseInfoId,
          },
          pkgSpec: item?.pkgSpec || "",
          otherCustomer: item?.otherCustomer || "",
          otherCustomerCode: item?.otherCustomerCode || "",
        };
        if (item.physicName) {
          this.getGuigeList(item.physicName);
        }
        this.dateRange = [
          this.normalizeDateToYMD(item.beginTime),
          this.normalizeDateToYMD(item.endTime),
        ];
      }
      this.createModalOpen = true;
      this.currentItem = item;
    },
    fetchList() {
      // this.list = [];
      // setTimeout(() => {
      //   const n = Math.min(10, this.totalCount || 10);
      //   this.list = this.genItems(n);
      //   if (!this.totalCount) this.totalCount = this.list.length;
      //   this.animateAll();
      //   this.fetchLoading = false;
      // }, 1000);
      if (!this.hasmore) {
        setTimeout(() => {
          this.fetchLoading = false;
          this.loading = false;
        }, 500);
        return;
      }
      if (this.fetchLoading) return;
      this.fetchLoading = true;
      request("/report/getReportTaskPage", {
        reportType: 2,
        taskType: statusMap?.[this.filterForm?.status] || "",
        drugEntBaseInfoId: this.filterForm?.product?.drugEntBaseInfoId,
        pkgSpec: this.filterForm?.pkgSpec || "",
        beginTime: this.filterDateRange[0],
        endTime: this.filterDateRange[1],
        customerName: this.keyword || "",
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        path: "reportExport/index.vue",
      }).then((res) => {
        if (res.code == 200) {
          const _data = res.data || {};
          const { list, total } = _data;
          this.totalCount = total || 0;
          const incoming = Array.isArray(list) ? list : [];
          const existingIds = new Set(this.list.map((v) => v?.id));
          const merged = incoming.filter((v) => {
            const id = v?.id;
            return id === undefined ? true : !existingIds.has(id);
          });
          if (merged.length === 0 && incoming.length > 0) {
            this.hasmore = false;
          } else {
            this.list = [...this.list, ...merged];
          }
          if (this.list.length < this.totalCount) {
            this.hasmore = true;
            this.pageNum++;
          } else {
            this.hasmore = false;
          }
          // this.list.push({
          //   ...this.list[1],
          //   status: 3,
          // });
          // this.list.push({
          //   ...this.list[0],
          //   finishTime: "2025-12-15",
          //   status: 3,
          // });
          // this.animateAll();
        }
        this.fetchLoading = false;
        this.loading = false;
      });
    },
    resetFetch() {
      this.loading = true;
      this.list = [];
      this.pageNum = 1;
      this.hasmore = true;
      this.fetchList();
    },
    toDetail(item) {
      uni.navigateTo({
        url: `/traceCodePackages/traceabilityReport/pages/reportExport/detail/index?id=${item.id
          }&title=${encodeURIComponent(this.getCustomerName(item))}`,
      });
    },
    onSearch() {
      this.resetFetch();
    },
    onCreate() {
      this.modalType = "create";
      this.taskTitle = "创建任务";
      this.createModalOpen = true;
    },
    closeCreate() {
      this.filterModalOpen = false;
      this.createModalOpen = false;
      this.closeDropdownAll();
      this.form = {
        region: { regionName: "" },
        customerType: "",
        customer: [],
        product: { physicName: "" },
        otherCustomer: "",
        otherCustomerCode: "",
      };
      this.searchForm = {
        region: "",
        product: "",
      };
      this.otherCustomerSearch = "";
      this.otherCustomers = [];
      this.otherCustomerLoading = false;
      if (this.otherCustomerDebounceTimer) {
        clearTimeout(this.otherCustomerDebounceTimer);
        this.otherCustomerDebounceTimer = null;
      }
      this.dateRange = [];
      if (this.computeTimer) {
        clearTimeout(this.computeTimer);
        this.computeTimer = null;
      }
    },
    confirmCreate() {
      let flag = false;
      Object.values(this.dropdown).forEach((v) => {
        if (v) {
          flag = true;
        }
      });
      if (flag) {
        this.closeDropdownAll();
        return;
      }
      if (!this.isFormComplete()) {
        // uni.showToast({ title: "请完整填写任务内容", icon: "none" });
        return;
      }
      // uni.showToast({ title: "已创建", icon: "none" });
      uni.showLoading({
        title: this.modalType === "create" ? "创建中..." : "修改中...",
      });

      const url =
        this.modalType === "create" ? `/report/save` : `/report/update`;
      const customerId = (this.form?.customer || [])
        .map((v) => v?.customerCode || "")
        .join(",");
      const customerName = (this.form?.customer || [])
        .map((v) => v?.customerName || "")
        .join(",");

      request(url, {
        id:
          this.modalType === "create" ? undefined : this.currentItem?.id || "",
        reportType: 2,
        regionCode: this.form?.region?.regionCode || "",
        customerType: customerTypeMap?.[this.form?.customerType] || "",
        customerId,
        customerName,
        otherCustomer: this.form?.otherCustomer || "",
        otherCustomerCode: this.form?.otherCustomerCode || "",
        drugEntBaseInfoId: this.form?.product?.drugEntBaseInfoId || "",
        pkgSpec: this.form?.pkgSpec || "",
        physicName: this.form?.product?.physicName || "",
        beginTime: this.formatDate(this.dateRange[0], "YYYY-MM-DD"),
        endTime: this.formatDate(this.dateRange[1], "YYYY-MM-DD"),
        path: "",
      }).then((res) => {
        if (res.code == 200) {
          uni.hideLoading();
          uni.showToast({
            title: this.modalType === "create" ? "已创建" : "已修改",
            icon: "none",
          });
          this.resetFetch();
          this.closeCreate();
        }
      });
    },
    isFormComplete() {
      const f = this.form;
      const drOk =
        Array.isArray(this.dateRange) &&
        this.dateRange.length === 2 &&
        this.dateRange[0] &&
        this.dateRange[1];
      const hasSelectedCustomer = Array.isArray(f.customer)
        ? f.customer.length > 0
        : !!f.customer;
      const hasOtherCustomer = !!String(f.otherCustomer || "").trim();
      const hasOtherCustomerCode = !!String(f.otherCustomerCode || "").trim();
      const customerOk =
        hasSelectedCustomer || hasOtherCustomer || hasOtherCustomerCode;
      if (!customerOk) {
        uni.showToast({
          title: "请至少填写客户、其它客户、其它客户信用代码中的一项",
          icon: "none",
        });
        return false;
      }
      if (!f.product?.physicName) {
        uni.showToast({ title: "请选择品种", icon: "none" });
        return false;
      }
      if (!drOk) {
        uni.showToast({ title: "请选择时间范围", icon: "none" });
        return false;
      }
      return true;
      // return (
      //   f.region?.regionName &&
      //   f.customerType &&
      //   customerOk &&
      //   f.product?.physicName &&
      //   drOk
      // );
    },
    confirmDelete() {
      uni.showModal({
        title: "确认删除吗？",
        success: (res) => {
          if (res.confirm) {
            uni.showLoading();
            request("/report/delete", {
              id: this.currentItem?.id || "",
              path: "reportExport/index.vue",
            }).then((res) => {
              uni.hideLoading();
              if (res.code == 200) {
                uni.showToast({
                  title: "删除成功",
                  icon: "none",
                  duration: 2000,
                });
                this.resetFetch();
                this.closeCreate();
              } else {
                uni.showToast({
                  title: res?.msg || "删除失败",
                  icon: "none",
                  duration: 2000,
                });
              }
            });
          }
        },
      });
    },
    onInput(k) {
      this.closeDropdownAll();
      this.dropdown[k] = true;
      if (k === "customer") {
        this.customerPage = 1;
        this.customerTotal = null;
        this.customerHasMore = true;
        this.customers = [];
        if (this.customerDebounceTimer)
          clearTimeout(this.customerDebounceTimer);
        this.customerDebounceTimer = setTimeout(() => {
          this.getCustomerOptions();
        }, 500);
        return;
      }
      if (k === "product") {
        this.initProductList("create");
        return;
      }
      if (k === "otherCustomer") {
        const keyword = String(this.otherCustomerSearch || "").trim();
        if (!keyword) {
          this.otherCustomers = [];
          this.otherCustomerLoading = false;
          if (this.otherCustomerDebounceTimer) {
            clearTimeout(this.otherCustomerDebounceTimer);
            this.otherCustomerDebounceTimer = null;
          }
          return;
        }
        // 输入后先进入 loading，避免先闪“未查找到该客户”
        this.otherCustomerLoading = true;
        if (this.otherCustomerDebounceTimer)
          clearTimeout(this.otherCustomerDebounceTimer);
        this.otherCustomerDebounceTimer = setTimeout(() => {
          this.getOtherCustomerOptions();
        }, 500);
      }
    },
    closeDropdownAll() {
      this.dropdown = {
        region: false,
        customerType: false,
        customer: false,
        otherCustomer: false,
        product: false,
        pkgSpec: false,
      };
      this.filterDropdown.product = false;
      this.filterDropdown.pkgSpec = false;
    },
    openFilterDropdown(k) {
      this.closeDropdownAll();
      this.filterDropdown[k] = true;
      if (k === "product") {
        this.initProductList("filter");
      }
    },
    toggleFilterDropdown(k) {
      this.filterDropdown[k] = !this.filterDropdown[k];
    },
    onFilterInput(k) {
      this.closeDropdownAll();
      this.filterDropdown[k] = true;
      if (k === "product") {
        this.initProductList("filter");
      }
    },
    pickFilterOption(k, v) {
      if (!["status"].includes(k) && this.filterForm[k] === v) {
        this.filterForm[k] = "";
        this.filterDropdown[k] = false;
        return;
      }
      this.filterForm[k] = v;
      if (k === "product") {
        this.filterForm.pkgSpec = "";
        this.getGuigeList(v.physicName);
      }
      this.filterDropdown[k] = false;
    },
    filteredFilterOptions(k) {
      const arr = k === "product" ? this.products || [] : [];
      const q = String(this.filterForm[k] || "").trim();
      if (!q) return arr;
      return arr.filter((it) => it.indexOf(q) !== -1);
    },
    onFilterDateChange() { },
    confirmFilter() {
      this.filterModalOpen = false;
      this.resetFetch();
    },
    resetFilter() {
      this.filterForm = {
        product: { physicName: "" },
        status: "全部",
        pkgSpec: "",
      };
      this.filterSearchForm.product = "";
      this.filterProductPage = 0;
      this.filterDisplayProducts = [];
      this.filterDropdown = { product: false, pkgSpec: false };
      this.filterDateRange = [];
      this.resetFetch();
    },
    openDropdown(k) {
      this.closeDropdownAll();
      this.dropdown[k] = true;
      if (k === "customer") {
        if (!this.customers || this.customers.length === 0) {
          this.customerPage = 1;
          this.customerTotal = null;
          this.customerHasMore = true;
          this.getCustomerOptions();
        }
      }
      if (k === "product") {
        this.initProductList("create");
      }
      if (k === "otherCustomer" && !String(this.otherCustomerSearch || "").trim()) {
        this.otherCustomers = [];
      }
    },
    toggleDropdown(k) {
      this.dropdown[k] = !this.dropdown[k];
    },
    pickOption(k, v) {
      if (k === "customer") {
        if (!Array.isArray(this.form.customer)) this.form.customer = [];
        const idx = this.form.customer.indexOf(v);
        if (idx === -1) {
          this.form.customer.push(v);
        } else {
          this.form.customer.splice(idx, 1);
        }
        return;
      }
      if (k === "otherCustomer") {
        const name =
          typeof v === "string"
            ? v
            : v?.entName || v?.customerName || "";
        const selected = this.getOtherCustomerArray();
        const idx = selected.findIndex((item) => item === name);
        if (idx === -1) {
          selected.push(name);
        } else {
          selected.splice(idx, 1);
        }
        this.form.otherCustomer = selected.join(",");
        return;
      }
      this.form[k] = v;
      if (k === "product") {
        this.form.pkgSpec = "";
        this.getGuigeList(v.physicName);
      }
      this.dropdown[k] = false;
    },
    isCustomerSelected(name) {
      const arr = this.form.customer;
      if (!Array.isArray(arr)) return false;
      return arr.some((i) => i.customerName === name);
    },
    removeCustomer(name) {
      if (!Array.isArray(this.form.customer)) return;
      const idx = this.form.customer.findIndex((i) => i.customerName === name);
      if (idx !== -1) this.form.customer.splice(idx, 1);
    },
    clearAllCustomers() {
      this.form.customer = [];
    },
    getOtherCustomerArray() {
      return String(this.form.otherCustomer || "")
        .split(",")
        .map((i) => i.trim())
        .filter(Boolean);
    },
    isOtherCustomerSelected(name) {
      return this.getOtherCustomerArray().includes(name);
    },
    removeOtherCustomer(name) {
      const arr = this.getOtherCustomerArray().filter((i) => i !== name);
      this.form.otherCustomer = arr.join(",");
    },
    clearAllOtherCustomers() {
      this.form.otherCustomer = "";
    },
    filteredOptions(k, type) {
      const arr = this.options[k] || [];
      let q = "";
      if (type === "filter") {
        q = this.filterSearchForm[k] || "";
      } else {
        q = this.searchForm[k] || "";
      }
      q = String(q).trim().toLocaleLowerCase();
      if (!q) return arr;
      return arr.filter((it) => {
        if (typeof it === "string")
          return it.toLocaleLowerCase().indexOf(q) !== -1;
        if (it && typeof it === "object") {
          const name =
            k === "region"
              ? it.regionName || it.name || ""
              : it.physicName || it.productName || "";
          return String(name).toLocaleLowerCase().indexOf(q) !== -1;
        }
        return false;
      });
    },
    // Initialize product list for pagination
    initProductList(mode) {
      const allProducts = this.filteredOptions(
        "product",
        mode === "filter" ? "filter" : undefined,
      );
      const res = getPaginatedList({
        page: 0,
        size: 10,
        initData: allProducts,
        data: [],
      });

      if (mode === "filter") {
        this.filterProductPage = res.page;
        this.filterDisplayProducts = res.data;
      } else {
        this.productPage = res.page;
        this.displayProducts = res.data;
      }
    },
    // Load more products on scroll
    loadMoreProducts(mode) {
      const allProducts = this.filteredOptions(
        "product",
        mode === "filter" ? "filter" : undefined,
      );
      const isFilter = mode === "filter";
      const currentPage = isFilter ? this.filterProductPage : this.productPage;
      const currentData = isFilter
        ? this.filterDisplayProducts
        : this.displayProducts;

      const res = getPaginatedList({
        page: currentPage,
        size: 10,
        initData: allProducts,
        data: currentData,
      });

      if (res.data) {
        if (isFilter) {
          this.filterProductPage = res.page;
          this.filterDisplayProducts = res.data;
        } else {
          this.productPage = res.page;
          this.displayProducts = res.data;
        }
      }
    },
    onSearchFocus() {
      this.dropdownUpward = true;
    },
    onSearchBlur() {
      this.dropdownUpward = false;
    },
    dropdownPosStyle() {
      // if (this.dropdownUpward) {
      //   return { bottom: "84rpx" };
      // }
      return { top: "84rpx" };
    },
    openDatePicker() {
      if (this.modalType === "read") return;
      this.$refs.datePicker.show();
    },
    onDateChange(val) {
      const arr = Array.isArray(val) ? val : this.dateRange;
      if (!Array.isArray(arr) || arr.length !== 2) return;
      const startDate = new Date(arr[0].replace(/-/g, "/"));
      const endDate = new Date(arr[1].replace(/-/g, "/"));
      const diff = endDate.getTime() - startDate.getTime();
      const limit = 183 * 24 * 3600 * 1000; // Approx 6 months
      if (diff > limit) {
        uni.showToast({
          title: "时间范围不能超过半年",
          icon: "none",
        });
        this.dateRange = [];
        return;
      }
      this.dateRange = [
        this.normalizeDateToYMD(arr[0]),
        this.normalizeDateToYMD(arr[1]),
      ];
    },
    onStart(item) {
      uni.showModal({
        title: "是否开始导出报表？",
        success: (res) => {
          if (res.confirm) {
            uni.showLoading();
            request("/report/confirm", {
              id: item?.id || "",
              path: "reportExport/index.vue",
            }).then((res) => {
              uni.hideLoading();
              if (res.code == 200) {
                uni.showToast({
                  title: "已开始导出",
                  icon: "none",
                  duration: 2000,
                });
                this.resetFetch();
                this.closeCreate();
              } else {
                uni.showToast({
                  title: res?.msg || "请求失败",
                  icon: "none",
                  duration: 2000,
                });
              }
            });
          }
        },
      });
    },
    onSend(item) {
      this.currentItem = item;
      this.emailError = false;
      this.emailModalOpen = true;
    },
    closeEmailModal() {
      this.emailModalOpen = false;
    },
    handleSendEmail() {
      const email = String(this.emailForm.email || "").trim();
      if (!email) {
        this.emailError = true;
        return;
      }
      this.closeEmailModal();
      uni.showLoading({
        title: "发送中...",
      });
      const url = "/report/sendemail";
      request(url, {
        taskId: this.currentItem?.id,
        emailAddress: email + "@999.com.cn",
        path: "reportExport/index.vue",
      }).then((res) => {
        uni.hideLoading();
        if (res.code === 200) {
          uni.showToast({
            title: "发送成功",
            icon: "none",
            duration: 2000,
          });
        } else {
          uni.showToast({
            title: res?.msg || "发送失败",
            icon: "none",
            duration: 2000,
          });
        }
      });
    },
    onScrollToLower() {
      // if (this.isLoading) return;
      // if (this.list.length >= this.totalCount) return;
      // this.isLoading = true;
      // const remain = this.totalCount - this.list.length;
      // const toAdd = Math.min(10, remain);
      // setTimeout(() => {
      //   const more = this.genItems(toAdd);
      //   this.list = this.list.concat(more);
      //   this.animateNew(more);
      //   this.isLoading = false;
      // }, 800);
      this.fetchList();
    },
    genItems(n) {
      const res = [];
      const base = this.list.length;
      for (let i = 0; i < n; i++) {
        const idx = base + i + 1;
        const statusIdx = idx % 3;
        const target = [60, 0, 100][statusIdx];
        const sText = ["导出进行中", "导出待开始", "导出已完成"][statusIdx];
        const sClass = ["ing", "wait", "done"][statusIdx];
        const action = ["", "start", "done"][statusIdx];
        res.push({
          title: `第${idx}条公司报表`,
          product: "感冒灵",
          range: "2025-11-27—2025-12-27",
          statusText: sText,
          statusClass: sClass,
          showProgress: statusIdx !== 1,
          progress: 0,
          progressTarget: target,
          action,
        });
      }
      return res;
    },
    // animateAll() {
    //   this.list.forEach((it) => this.animateItem(it));
    // },
    // animateNew(arr) {
    //   arr.forEach((it) => this.animateItem(it));
    // },
    // animateItem(item) {
    //   if (!item.showProgress) return;
    //   item.progress = 60;
    //   const target = Number(item.progressTarget) || 0;
    //   const step = Math.max(1, Math.round(target / 60));
    //   const timer = setInterval(() => {
    //     item.progress += step;
    //     if (item.progress >= target) {
    //       item.progress = target;
    //       clearInterval(timer);
    //     }
    //   }, 16);
    // },
  },
};
</script>

<style>
.report-export-page {
  position: relative;
  box-sizing: border-box;
  /* padding: 170rpx 0 calc(50rpx + env(safe-area-inset-bottom)); */
  padding-top: 290rpx;
}

.report-export-search-bar-container {
  position: fixed;
  top: 100rpx;
  left: 0;
  padding: 24rpx 24rpx 16rpx;
  background-color: #f3f6f9;
  z-index: 10;
  box-sizing: border-box;
  width: 100%;
}

.report-export-search-bar {
  display: flex;
  align-items: center;
  background: #fff;
  border-radius: 16rpx;
  padding: 16rpx;
}

.report-export-search-input-wrap {
  flex: 1;
  position: relative;
  background: #f3f6f9;
  border-radius: 40rpx;
  display: flex;
  align-items: center;
  height: 90rpx;
  padding: 0 12rpx;
}

.report-export-search-icon {
  width: 28rpx;
  height: 28rpx;
  margin-left: 16rpx;
}

.report-export-search-input {
  flex: 1;
  height: 90rpx;
  padding: 0 16rpx;
  font-size: 28rpx;
}

.report-export-search-btn {
  height: 72rpx;
  line-height: 72rpx;
  padding: 0 34rpx;
  border-radius: 36rpx;
  background: #2c69ff;
  color: #fff;
  font-size: 34rpx;
  margin-left: 12rpx;
}

.report-export-filter-btn {
  margin-left: 12rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.report-export-filter-icon {
  width: 40rpx;
  height: 40rpx;
}

.report-export-filter-text {
  margin-top: 8rpx;
  font-size: 24rpx;
  color: #2c69ff;
}

.scan-rate-ranges-container {
  position: fixed;
  top: 262rpx;
  left: 0;
  width: 100%;
  height: 120rpx;
  background: #f3f6f9;
  z-index: 6;
}

.scan-rate-ranges {
  padding: 0rpx 24rpx 20rpx;
}

.scan-rate-ranges-content {
  display: flex;
  background: #fff;
  padding: 20rpx 30rpx;
  border-radius: 16rpx;
  justify-content: space-between;
}

.scan-rate-range {
  padding: 12rpx 35rpx;
  border-radius: 5rpx;
  background: rgb(240, 240, 240);
  font-size: 26rpx;
}

.scan-rate-range.scan-rate-active {
  background: #2c69ff;
  color: #fff;
}

.report-export-list-scroll {
  position: fixed;
  top: 380rpx;
  left: 0;
  box-sizing: border-box;
  width: 100%;
  padding: 0 24rpx;
  padding-bottom: calc(env(safe-area-inset-bottom) + 50rpx);
  box-sizing: border-box;
}

.report-export-item-card {
  background: #fff;
  border-radius: 16rpx;
  padding: 24rpx;
  margin-bottom: 16rpx;
}

.report-export-item-header {
  width: 100%;
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
}

.report-export-item-title {
  flex: 1;
  width: 0;
  word-break: break-word;
  margin-right: 20rpx;
  font-size: 38rpx;
  color: #2c69ff;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-decoration: underline;
}

.report-export-status {
  flex-shrink: 0;
  padding: 2rpx 10rpx;
  border-radius: 6rpx;
  font-size: 22rpx;
  border: 1rpx solid transparent;
}

.report-export-status.report-export-status-2 {
  background: rgba(103, 194, 58, 0.1);
  border-color: rgba(103, 194, 58, 0.2);
  color: #67c23a;
}

.report-export-status.report-export-status-1 {
  background: rgba(136, 136, 136, 0.1);
  border-color: rgba(136, 136, 136, 0.2);
  color: #888;
}

.report-export-status.report-export-status-3,
.report-export-status.report-export-status-4 {
  background: rgba(44, 105, 255, 0.1);
  border-color: rgba(44, 105, 255, 0.2);
  color: #2c69ff;
}

.report-export-item-row {
  margin-top: 12rpx;
  font-size: 28rpx;
  color: #999;
}

.report-export-progress-wrap {
  margin-top: 20rpx;
}

.report-export-progress {
  margin-top: 8rpx;
  height: 32rpx;
  background: #e6ebf5;
  border-radius: 999rpx;
  overflow: hidden;
  position: relative;
}

.report-export-progress-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background: #2c69ff;
  border-radius: 999rpx;
  width: 0;
  transition: width 0.2s linear;
}

.report-export-progress-text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 26rpx;
  color: #fff;
  z-index: 2;
}

.report-export-action-row {
  margin-top: 16rpx;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.report-export-action-btn {
  height: 50rpx;
  line-height: 50rpx;
  padding: 0 28rpx;
  border-radius: 12rpx;
  font-size: 30rpx;
  margin: 0;
}

.report-export-action-btn+.report-export-action-btn {
  margin-left: 12rpx;
}

.report-export-action-btn.report-export-primary {
  background: #2c69ff;
  color: #fff;
}

.report-export-action-btn.report-export-info {
  background: #67c23a;
  color: #fff;
}

.report-export-loading-row {
  justify-content: center;
}

.report-export-loading-wrapper {
  width: 100%;
  height: 76rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.report-export-loading-icon {
  width: 40rpx;
  height: 40rpx;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.report-export-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 12rpx 30rpx calc(50rpx + env(safe-area-inset-bottom));
  background: #fff;
}

.report-export-footer-btn {
  height: 86rpx;
  border-radius: 999rpx;
  background: #2c69ff;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30rpx;
  box-shadow: 0 8rpx 24rpx rgba(44, 105, 255, 0.35);
}

.report-export-create-modal-mask {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 90;
}

.report-export-create-modal {
  position: fixed;
  left: 0;
  right: 0;
  bottom: -100%;
  width: 100%;
  background: #fff;
  border-top-left-radius: 45rpx;
  border-top-right-radius: 45rpx;
  z-index: 92;
  box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.12);
  /* transform: translateY(100%); */
  transition: bottom 0.25s ease-out;
}

.report-export-create-modal--open {
  /* transform: translateY(0) !important; */
  bottom: 0 !important;
}

.report-export-create-modal-title {
  position: relative;
  padding: 28rpx 28rpx 12rpx;
  font-size: 34rpx;
  color: #333;
  text-align: center;
  line-height: 60rpx;
  font-weight: 500;
}

.report-export-create-modal-close {
  position: absolute;
  right: 32rpx;
  top: 50%;
  transform: translateY(-50%);
  padding: 10rpx;
  color: #909399;
  font-size: 55rpx;
  line-height: 1;
}

.report-export-create-modal-body {
  padding: 0 32rpx 100rpx;
}

.report-export-create-modal-row {
  display: flex;
  flex-direction: column;
  margin-top: 32rpx;
  position: relative;
}

.report-export-create-modal-label {
  width: auto;
  font-size: 28rpx;
  color: #333;
  margin-bottom: 16rpx;
  font-weight: 500;
}

.report-export-create-modal-inputwrap {
  flex: 1;
  position: relative;
  border: 1rpx solid #dcdfe6;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  min-height: 80rpx;
  padding: 0 24rpx;
  background-color: #fff;
}

.report-export-create-modal-static {
  position: relative;
  flex: 1;
  max-height: 115rpx;
  font-size: 28rpx;
  color: #606266;
  line-height: 40rpx;
  padding: 20rpx 0;
  overflow-y: auto;
  padding-right: 20rpx;
}

.report-export-input-simulator {
  display: flex;
  justify-content: center;
  align-items: center;
}

.report-export-create-modal-input {
  flex: 1;
  height: 80rpx;
  font-size: 28rpx;
  color: #606266;
}

.report-export-dropdown-other-customer-input {
  color: #666;
}

/* .report-export-create-modal-select-arrow {
  width: 18rpx;
  height: 18rpx;
  border: 5rpx solid #999;
  border-top: none;
  border-left: none;
  transform: rotate(45deg);
  margin: 0 8rpx 10rpx 12rpx;
}
.report-export-create-modal-select-arrow.disabled {
  opacity: 0.4;
  pointer-events: none;
} */
.report-export-create-modal-dropdown {
  position: absolute;
  left: 0;
  right: 0;
  background: #fff;
  border: 1rpx solid #eef0f4;
  border-radius: 12rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
  z-index: 6;
  max-height: 510rpx;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.report-export-create-modal-dropdown-list {
  max-height: 350rpx;
}

.report-export-dropdown-search-row {
  padding: 10rpx;
}

.report-export-dropdown-search-input {
  width: 100%;
  height: 60rpx;
  border: 1rpx solid #eaeef4;
  border-radius: 8rpx;
  box-sizing: border-box;
  padding: 0 16rpx;
  font-size: 28rpx;
}

.report-export-create-modal-dropdown-item {
  padding: 16rpx 20rpx;
  font-size: 28rpx;
  color: #333;
}

.report-export-selected {
  background: #f0f5ff;
}

.report-export-input-arrow {
  width: 16rpx;
  height: 16rpx;
  border-right: 3rpx solid #c0c4cc;
  border-bottom: 3rpx solid #c0c4cc;
  transform: rotate(45deg);
  margin-top: -6rpx;
}

.customer-chip {
  display: inline-block;
  position: relative;
  line-height: 50rpx;
  border: 1rpx solid #eaeef4;
  border-radius: 8rpx;
  padding: 0rpx 44rpx 0rpx 16rpx;
  margin-right: 8rpx;
  margin-bottom: 8rpx;
  font-size: 22rpx;
  color: #333;
}

.customer-chip-close {
  position: absolute;
  right: 6rpx;
  top: 0;
  color: #666;
  font-size: 28rpx;
  padding: 0 8rpx;
  border-radius: 6rpx;
}

.customer-clear-all {
  position: absolute;
  right: 6rpx;
  top: 50%;
  transform: translateY(-50%);
  line-height: 50rpx;
  padding: 8rpx 10rpx;
  font-size: 40rpx;
}

.report-export-create-modal-estimated {
  font-size: 28rpx;
  color: #666;
}

.report-export-create-modal-footer {
  padding: 18rpx 28rpx calc(50rpx + env(safe-area-inset-bottom));
}

.report-export-create-modal-btn {
  line-height: 90rpx;
  border-radius: 20rpx;
  background: #2c69ff;
  color: #fff;
  text-align: center;
  font-size: 30rpx;
}

.report-export-create-email-modal {
  /* transform: translateY(200%); */
  height: 420rpx;
  top: 30%;
  bottom: auto;
  border-radius: 16rpx;
  width: 600rpx;
  left: 75rpx;
}

.report-export-email-input-wrap {
  display: flex;
  align-items: center;
  background: #f5f7fa;
  border-radius: 8rpx;
  padding: 0 20rpx;
  height: 80rpx;
  border: 1rpx solid transparent;
}

.report-export-input-error {
  border-color: #ff4d4f;
}

.report-export-email-input {
  flex: 1;
  font-size: 28rpx;
  color: #333;
  height: 100%;
}

.report-export-email-suffix {
  font-size: 28rpx;
  color: #333;
  margin-left: 10rpx;
}

.report-export-error-text {
  font-size: 24rpx;
  color: #ff4d4f;
  margin-top: 10rpx;
  display: block;
}

.report-export-input-disabled {
  background-color: #f5f7fa;
  cursor: not-allowed;
  opacity: 0.7;
}
</style>
