<template>
  <view class="asset-page balance-page" @click="closePanels">
    <asset-page-shell title="余额" />

    <view class="asset-scroll balance-scroll">
      <view class="balance-header">
        <view class="balance-header__card">
          <image
            class="balance-header__bg"
            src="https://imgs.agrimedia.cn/shop/header-yongjin.png"
            mode="aspectFill"
          ></image>

          <view class="balance-header__content">
            <view class="balance-header__summary">
              <view class="balance-header__summary-item">
                <text class="balance-header__label">余额</text>
                <text class="balance-header__value asset-number-font">{{
                  summary.balance
                }}</text>
              </view>

              <view class="balance-header__summary-item">
                <text class="balance-header__label">冻结佣金</text>
                <text class="balance-header__value asset-number-font">{{
                  summary.frozen
                }}</text>
              </view>
            </view>

            <image
              class="balance-header__icon"
              src="https://imgs.agrimedia.cn/shop/yongjin-icon.png"
              mode="aspectFit"
            ></image>
          </view>
        </view>
      </view>

      <view class="balance-toolbar">
        <view class="balance-toolbar__row">
          <view class="balance-toolbar__item" @click.stop="openDatePopup">
            <text class="balance-toolbar__text">{{ currentDateLabel }}</text>
            <image
              class="balance-toolbar__icon"
              src="https://imgs.agrimedia.cn/shop/select-icon.png"
              mode="widthFix"
            ></image>
          </view>

          <view class="balance-toolbar__item" @click.stop="openStatusPopup">
            <text class="balance-toolbar__text">{{
              statusOptions[pmIndex].label
            }}</text>
            <image
              class="balance-toolbar__icon"
              src="https://imgs.agrimedia.cn/shop/select-icon.png"
              mode="widthFix"
            ></image>
          </view>
        </view>
      </view>

      <view class="balance-list">
        <view v-if="sections.length" class="balance-records">
          <view
            v-for="section in sections"
            :key="section.key"
            class="balance-group"
          >
            <text class="balance-group__date">{{ section.label }}</text>

            <view class="balance-group__items">
              <view
                v-for="item in section.items"
                :key="item.id"
                class="balance-item"
              >
                <view class="balance-item__head">
                  <view class="balance-item__title-row">
                    <text class="balance-item__title">{{ item.title }}</text>
                    <text
                      class="balance-item__amount asset-number-font"
                      :class="
                        item.amountTone === 'income'
                          ? 'balance-item__amount--income'
                          : 'balance-item__amount--expense'
                      "
                    >
                      {{ item.amount }}
                    </text>
                  </view>

                  <view
                    v-for="row in item.detailRows"
                    :key="row.label + row.value"
                    class="balance-item__line"
                  >
                    <text class="balance-item__line-label">{{ row.label }}</text>
                    <text class="balance-item__line-value asset-number-font">{{
                      row.value
                    }}</text>
                  </view>

                  <view v-if="item.merchantName" class="balance-item__line">
                    <text class="balance-item__line-label"></text>
                    <text class="balance-item__line-value">{{
                      item.merchantName
                    }}</text>
                  </view>

                  <text
                    v-if="item.note"
                    class="balance-item__note"
                    :class="{
                      'balance-item__note--refund': item.noteTone === 'expense',
                      'balance-item__note--danger': item.noteTone === 'danger',
                    }"
                  >
                    {{ item.note }}
                  </text>
                </view>
              </view>
            </view>
          </view>

          <view class="balance-loading">
            <text class="balance-loading__text asset-number-font">{{
              loadMoreText
            }}</text>
          </view>
        </view>

        <view v-else class="balance-empty">
          <image
            class="balance-empty__image"
            src="https://imgs.agrimedia.cn/shop/no-datas.png"
            mode="aspectFit"
          ></image>
          <text class="balance-empty__text">暂无数据</text>
        </view>
      </view>
    </view>

    <view
      v-if="datePopupVisible"
      class="sheet-mask"
      @click="datePopupVisible = false"
    ></view>
    <view
      v-if="datePopupVisible"
      class="sheet-panel date-sheet"
      @click.stop
    >
      <view class="date-sheet__title">
        <text>交易日期</text>
        <text class="date-sheet__close" @click="datePopupVisible = false">×</text>
      </view>

      <view class="date-sheet__block">
        <text class="date-sheet__block-title">选择时间</text>

        <view class="date-sheet__preset-row">
          <view
            v-for="(item, index) in timeRanges"
            :key="item.key"
            class="date-sheet__preset"
            :class="{ 'is-active': clickIndex === index }"
            @click="clickTime(index)"
          >
            {{ item.label }}
          </view>
        </view>

        <view class="date-sheet__custom" @click="clickTime(4)">
          <view
            class="date-sheet__custom-tag"
            :class="{ 'is-active': clickIndex === 4 }"
          >
            自定义时间
          </view>
          <text class="date-sheet__custom-desc">
            最长可查询时间跨度一年的交易
          </text>
        </view>
      </view>

      <view v-if="clickIndex === 4" class="date-sheet__range">
        <picker
          class="date-sheet__picker"
          mode="date"
          :value="startValue"
          @change="handleStartDateChange"
        >
          <view class="date-sheet__picker-inner">{{ startValue }}</view>
        </picker>

        <text class="date-sheet__range-separator">至</text>

        <picker
          class="date-sheet__picker"
          mode="date"
          :value="endValue"
          @change="handleEndDateChange"
        >
          <view class="date-sheet__picker-inner">{{ endValue }}</view>
        </picker>
      </view>

      <view class="date-sheet__confirm" @click="confirmDateFilter">确定</view>
    </view>

    <view
      v-if="statusPopupVisible"
      class="sheet-mask"
      @click="statusPopupVisible = false"
    ></view>
    <view
      v-if="statusPopupVisible"
      class="sheet-panel status-sheet"
      @click.stop
    >
      <view
        v-for="(item, index) in statusOptions"
        :key="item.value + item.label"
        class="status-sheet__item"
        :class="{ 'is-active': pmIndex === index }"
        @click="confirmStatus(index)"
      >
        {{ item.label }}
      </view>
    </view>
  </view>
</template>

<script>
import AssetPageShell from "../../components/asset-page-shell.vue";
import { fetchBalanceCenterPage } from "../../api/assets";

function padDateUnit(value) {
  return value < 10 ? "0" + value : String(value);
}

function formatDate(date) {
  return [
    date.getFullYear(),
    padDateUnit(date.getMonth() + 1),
    padDateUnit(date.getDate()),
  ].join("-");
}

function createTodayDate() {
  const date = new Date();
  date.setHours(0, 0, 0, 0);
  return date;
}

export default {
  components: {
    AssetPageShell,
  },
  data() {
    const today = formatDate(createTodayDate());

    return {
      summary: {
        balance: "0",
        totalExtract: "0",
        frozen: "0",
      },
      form: {
        pm: "",
        start_time: "",
        end_time: "",
      },
      statusOptions: [
        { label: "全部", value: "" },
        { label: "佣金获得", value: "1" },
        { label: "佣金支出", value: "0" },
      ],
      timeRanges: [
        { key: "today", label: "今天" },
        { key: "yesterday", label: "昨天" },
        { key: "week", label: "近7天" },
        { key: "month", label: "近30天" },
      ],
      pmIndex: 0,
      clickIndex: "",
      startValue: today,
      endValue: today,
      datePopupVisible: false,
      statusPopupVisible: false,
      sections: [],
      page: 1,
      pageSize: 10,
      hasMore: false,
      loadingMore: false,
    };
  },
  computed: {
    currentDateLabel() {
      if (this.clickIndex === "" || this.clickIndex === 4) {
        return this.startValue + "~" + this.endValue;
      }

      return this.timeRanges[this.clickIndex]
        ? this.timeRanges[this.clickIndex].label
        : this.startValue + "~" + this.endValue;
    },
    loadMoreText() {
      if (this.loadingMore) {
        return "加载中...";
      }

      if (this.hasMore) {
        return "加载更多";
      }

      return "暂无更多";
    },
  },
  onLoad() {
    this.loadPage(true, 1);
  },
  onReachBottom() {
    this.loadMore();
  },
  methods: {
    closePanels() {
      this.datePopupVisible = false;
      this.statusPopupVisible = false;
    },
    openDatePopup() {
      this.statusPopupVisible = false;
      this.datePopupVisible = true;
    },
    openStatusPopup() {
      this.datePopupVisible = false;
      this.statusPopupVisible = true;
    },
    getRangeDates(index) {
      const endDate = createTodayDate();
      const startDate = new Date(endDate.getTime());

      if (index === 0) {
        return {
          start: formatDate(startDate),
          end: formatDate(endDate),
        };
      }

      if (index === 1) {
        startDate.setDate(startDate.getDate() - 1);
        return {
          start: formatDate(startDate),
          end: formatDate(startDate),
        };
      }

      startDate.setDate(startDate.getDate() - (index === 2 ? 6 : 29));
      return {
        start: formatDate(startDate),
        end: formatDate(endDate),
      };
    },
    clickTime(index) {
      this.clickIndex = index;

      if (index === 4) {
        this.form.start_time = this.startValue;
        this.form.end_time = this.endValue;
        return;
      }

      const range = this.getRangeDates(index);
      this.form.start_time = range.start;
      this.form.end_time = range.end;
    },
    handleStartDateChange(event) {
      const value = event && event.detail ? event.detail.value : "";
      this.startValue = value || this.startValue;
      this.form.start_time = this.startValue;
    },
    handleEndDateChange(event) {
      const value = event && event.detail ? event.detail.value : "";
      this.endValue = value || this.endValue;
      this.form.end_time = this.endValue;
    },
    confirmDateFilter() {
      if (this.clickIndex === 4) {
        this.form.start_time = this.startValue;
        this.form.end_time = this.endValue;
      }

      this.datePopupVisible = false;
      this.reloadList();
    },
    confirmStatus(index) {
      const target = this.statusOptions[index];
      this.pmIndex = index;
      this.form.pm = target ? target.value : "";
      this.statusPopupVisible = false;
      this.reloadList();
    },
    reloadList() {
      this.sections = [];
      this.page = 1;
      this.hasMore = false;
      this.loadingMore = false;
      this.loadPage(true, 1);
    },
    mergeSections(currentSections, nextSections) {
      const sectionMap = {};
      const mergedSections = [];
      const appendSection = (section) => {
        if (!section || !section.key) {
          return;
        }

        if (!sectionMap[section.key]) {
          sectionMap[section.key] = {
            key: section.key,
            label: section.label,
            items: [],
          };
          mergedSections.push(sectionMap[section.key]);
        }

        const targetSection = sectionMap[section.key];
        const itemMap = {};
        targetSection.items.forEach((item) => {
          itemMap[item.id] = true;
        });

        (section.items || []).forEach((item) => {
          if (!item || itemMap[item.id]) {
            return;
          }

          itemMap[item.id] = true;
          targetSection.items.push(item);
        });
      };

      (currentSections || []).forEach(appendSection);
      (nextSections || []).forEach(appendSection);

      return mergedSections;
    },
    async loadPage(showLoading, targetPage) {
      const page = Number(targetPage || 1);
      const isLoadMore = page > 1;

      if (isLoadMore && (this.loadingMore || !this.hasMore)) {
        return;
      }

      if (isLoadMore) {
        this.loadingMore = true;
      }

      try {
        const requestOptions =
          !isLoadMore && showLoading
            ? {
                showLoading: true,
                loadingText: "加载中",
              }
            : null;
        const result = await fetchBalanceCenterPage(
          {
            pm: this.form.pm,
            start_time: this.form.start_time,
            end_time: this.form.end_time,
          },
          {
            page: page,
            pageSize: this.pageSize,
          },
          requestOptions,
        );
        const nextSections = Array.isArray(result.sections) ? result.sections : [];

        this.summary = Object.assign({}, this.summary, result.summary || {});
        this.sections = isLoadMore
          ? this.mergeSections(this.sections, nextSections)
          : nextSections;

        const pagination = result.pagination || {};
        this.page = Number(pagination.page || page || 1);
        this.hasMore = Boolean(pagination.hasMore);
      } catch (error) {
        uni.showToast({
          title: error.message || (isLoadMore ? "加载更多失败" : "页面加载失败"),
          icon: "none",
        });
      } finally {
        if (isLoadMore) {
          this.loadingMore = false;
        }
      }
    },
    loadMore() {
      if (this.loadingMore || !this.hasMore) {
        return;
      }

      this.loadPage(false, this.page + 1);
    },
  },
};
</script>

<style lang="scss" scoped>
@import "../../styles/tokens.scss";
@import "../../styles/common.scss";

.balance-page {
  min-height: 100vh;
  background: #f5f5f5;
}

.balance-scroll {
  padding: 16rpx 12rpx calc(env(safe-area-inset-bottom) + 36rpx);
}

.balance-header {
  margin-top: 4rpx;
}

.balance-header__card {
  position: relative;
  width: 100%;
  height: 187rpx;
  overflow: hidden;
  border-radius: 24rpx;
}

.balance-header__bg {
  width: 100%;
  height: 187rpx;
}

.balance-header__content {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28rpx;
}

.balance-header__summary {
  display: flex;
  align-items: center;
  gap: 56rpx;
}

.balance-header__summary-item {
  min-width: 0;
}

.balance-header__label {
  display: block;
  font-weight: 600;
  font-size: 32rpx;
  color: #ffffff;
  text-align: center;
}

.balance-header__value {
  display: block;
  margin-top: 12rpx;
  font-size: 42rpx;
  font-weight: 800;
  color: #ffffff;
  line-height: 1;
}

.balance-header__icon {
  width: 176rpx;
  height: 160rpx;
  flex-shrink: 0;
}

.balance-toolbar {
  padding: 20rpx 10rpx 12rpx;
}

.balance-toolbar__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20rpx;
}

.balance-toolbar__item {
  display: flex;
  align-items: center;
  min-width: 0;
}

.balance-toolbar__text {
  font-size: 24rpx;
  color: #000;
}

.balance-toolbar__icon {
  width: 30rpx;
  height: 30rpx;
  margin-left: 10rpx;
  flex-shrink: 0;
}

.balance-list {
  width: 100%;
}

.balance-group {
  margin-bottom: 20rpx;
  padding: 28rpx 24rpx;
  border-radius: 22rpx;
  background: #ffffff;
}

.balance-group__date {
  display: block;
  padding: 0;
  font-weight: 500;
  font-size: 30rpx;
  color: #666666;
  line-height: 36rpx;
}

.balance-group__items {
  margin-top: 14rpx;
}

.balance-item + .balance-item {
  margin-top: 18rpx;
  padding-top: 18rpx;
  border-top: 1px solid rgba(20, 40, 72, 0.08);
}

.balance-item__title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20rpx;
  width: 100%;
  margin-bottom: 16rpx;
}

.balance-item__title {
  flex: 1;
  min-width: 0;
  font-weight: 500;
  font-size: 30rpx;
  color: #000000;
  line-height: 1.45;
}

.balance-item__amount {
  flex-shrink: 0;
  font-weight: 800;
  font-size: 36rpx;
  line-height: 1;
}

.balance-item__amount--income {
  color: #fc2838;
}

.balance-item__amount--expense {
  color: #07c261;
}

.balance-item__line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20rpx;
  margin-bottom: 12rpx;
  font-weight: 400;
  font-size: 26rpx;
  color: #666666;
  line-height: 36rpx;
}

.balance-item__line-label {
  min-width: 120rpx;
}

.balance-item__line-value {
  flex: 1;
  min-width: 0;
  text-align: right;
  word-break: break-all;
}

.balance-item__note {
  display: block;
  margin-top: 6rpx;
  font-size: 26rpx;
  line-height: 36rpx;
}

.balance-item__note--refund {
  color: #07c261;
}

.balance-item__note--danger {
  color: #ff7a45;
}

.balance-loading {
  display: flex;
  justify-content: center;
  padding: 8rpx 0 0;
}

.balance-loading__text {
  font-size: 24rpx;
  color: rgba(255, 255, 255, 0.72);
}

.balance-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 180rpx 0 60rpx;
}

.balance-empty__image {
  width: 328rpx;
  height: 338rpx;
}

.balance-empty__text {
  margin-top: 36rpx;
  font-weight: 400;
  font-size: 32rpx;
  color: #999999;
}

.sheet-mask {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(0, 0, 0, 0.42);
}

.sheet-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 81;
  background: #ffffff;
  border-radius: 20rpx 20rpx 0 0;
}

.date-sheet {
  padding: 20rpx 20rpx calc(env(safe-area-inset-bottom) + 30rpx);
}

.date-sheet__title {
  position: relative;
  text-align: center;
  font-size: 32rpx;
  font-weight: 500;
  color: #000000;
}

.date-sheet__close {
  position: absolute;
  top: 4rpx;
  right: 20rpx;
  font-size: 42rpx;
  line-height: 1;
}

.date-sheet__block {
  margin-top: 26rpx;
}

.date-sheet__block-title {
  display: block;
  margin-bottom: 20rpx;
  font-size: 28rpx;
  color: #000000;
}

.date-sheet__preset-row {
  display: flex;
  justify-content: space-between;
  gap: 12rpx;
}

.date-sheet__preset {
  flex: 1;
  height: 50rpx;
  line-height: 50rpx;
  text-align: center;
  border-radius: 10rpx;
  border: 2rpx solid #ed151b;
  font-size: 22rpx;
  color: #ed151b;
}

.date-sheet__preset.is-active {
  background: #ed151b;
  color: #ffffff;
}

.date-sheet__custom {
  display: flex;
  align-items: center;
  margin-top: 20rpx;
  margin-bottom: 30rpx;
  color: #ed151b;
}

.date-sheet__custom-tag {
  height: 50rpx;
  padding: 0 20rpx;
  line-height: 50rpx;
  text-align: center;
  border-radius: 10rpx;
  border: 2rpx solid #ed151b;
  font-size: 22rpx;
}

.date-sheet__custom-tag.is-active {
  background: #ed151b;
  color: #ffffff;
}

.date-sheet__custom-desc {
  margin-left: 20rpx;
  font-size: 22rpx;
  color: #666666;
}

.date-sheet__range {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.date-sheet__picker {
  width: 260rpx;
  height: 60rpx;
  border: 2rpx solid #ed151b;
  border-radius: 10rpx;
  overflow: hidden;
}

.date-sheet__picker-inner {
  width: 100%;
  height: 60rpx;
  line-height: 60rpx;
  text-align: center;
  font-size: 24rpx;
  color: #000000;
}

.date-sheet__range-separator {
  font-size: 24rpx;
  color: #000000;
}

.date-sheet__confirm {
  width: 100%;
  height: 70rpx;
  margin-top: 30rpx;
  margin-bottom: 30rpx;
  border-radius: 10rpx;
  background: #ed151b;
  line-height: 70rpx;
  text-align: center;
  font-size: 28rpx;
  color: #ffffff;
}

.status-sheet {
  padding: 16rpx 0 calc(env(safe-area-inset-bottom) + 20rpx);
}

.status-sheet__item {
  height: 88rpx;
  line-height: 88rpx;
  text-align: center;
  font-size: 28rpx;
  color: #333333;
}

.status-sheet__item.is-active {
  color: #ed151b;
  font-weight: 600;
}
</style>
