<template>
  <div style="background-color: #fff; padding: 15px">
    <baseTableHeader title="销售统计报表" @resetSearch="reset" @search="query">
      <template #content>
        <el-form v-model="searchForm">
          <el-row :gutter="25">
            <el-col :span="12">
              <el-form-item label="统计日期">
                <el-date-picker
                  v-model="searchForm.dateRange"
                  type="datetimerange"
                  range-separator="至"
                  start-placeholder="选择开始日期"
                  end-placeholder="选择结束日期"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  @change="dateChange" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="服务名称">
                <el-input
                  v-model="searchForm.serviceName"
                  placeholder="输入服务名称" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="项目分类">
                <el-select
                  v-model="searchForm.categoryName"
                  placeholder="选择分类"
                  clearable>
                  <el-option
                    v-for="category in categories"
                    :key="category.id"
                    :label="category.name"
                    :value="category.name" />
                  <el-option label="其他服务" value="其他服务" />
                </el-select>
              </el-form-item>
            </el-col>
            <!-- <div>
              <el-button
                type="primary"
                style="margin-left: 15px"
                @click="query"
                :loading="loading">
                查询
              </el-button>
              <el-button type="warning" @click="reset">重置</el-button>
            </div> -->
          </el-row>
        </el-form>
      </template>
      <template #operateBtns>
        <el-button size="small" v-print="print"
          ><img
            src="/assets/icon/打印机.svg"
            style="margin-right: 5px"
            width="20"
            height="20" />打印单据</el-button
        >
        <el-button @click="exportTableToExcel"
          ><img
            src="/assets/images/Excel.svg"
            alt=""
            width="20"
            height="20" />导出</el-button
        >
      </template>
    </baseTableHeader>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-mask">
      <el-icon class="is-loading" color="#409EFC" :size="30">
        <Loading />
      </el-icon>
      <span style="margin-left: 10px">数据加载中...</span>
    </div>
    <div id="print-container">
      <h2
        style="
          color: #000;
          text-align: center;
          font-size: 20pt;
          padding: 15px;
          font-weight: bold;
        ">
        销售统计报表
      </h2>
      <table
        v-show="!loading"
        style="
          table-layout: fixed;
          width: 100%;
          border-collapse: collapse;
          font-family: 宋体;
        ">
        <!-- 表头 -->
        <thead>
          <tr>
            <th style="border: 1px solid #000; padding: 8px">序号</th>
            <th style="border: 1px solid #000; padding: 8px">服务项目</th>
            <th style="border: 1px solid #000; padding: 8px">单价（元）</th>
            <th style="border: 1px solid #000; padding: 8px">数量</th>
            <th style="border: 1px solid #000; padding: 8px">小计（元）</th>
          </tr>
        </thead>
        <tbody>
          <!-- 新增空状态 -->
          <tr v-if="showEmpty">
            <td
              colspan="4"
              style="text-align: center; color: #999; padding: 20px">
              未查询到相关数据
            </td>
          </tr>
          <!-- 分类数据 -->
          <template
            v-for="category in statsData.categories"
            :key="category.categoryName">
            <tr>
              <td
                colspan="5"
                style="font-weight: bold; padding: 8px; text-align: center">
                {{ category.categoryName }}
              </td>
            </tr>
            <tr
              v-for="(service, index) in category.services"
              :key="service.serviceName">
              <td style="padding: 8px">{{ index + 1 }}</td>
              <td style="border: 1px solid #000; padding: 8px">
                {{ service.serviceName }}
              </td>
              <td
                style="border: 1px solid #000; text-align: right; padding: 8px">
                {{ service.price.toFixed(2) }}
              </td>
              <td
                style="border: 1px solid #000; text-align: right; padding: 8px">
                {{ service.quantity }}
              </td>
              <td
                style="border: 1px solid #000; text-align: right; padding: 8px">
                {{ service.subtotal.toFixed(2) }}
              </td>
            </tr>
            <!-- <tr style="font-weight: bold">
              <td colspan="2" style="border: 1px solid #000; padding: 8px">
                分类合计
              </td>
              <td
                style="border: 1px solid #000; text-align: right; padding: 8px">
                {{ category.totalQuantity }}
              </td>
              <td
                style="border: 1px solid #000; text-align: right; padding: 8px">
                {{ category.totalAmount.toFixed(2) }}
              </td>
            </tr> -->
          </template>

          <!-- 其他服务 -->
          <tr v-if="statsData.otherCategory.services.length">
            <td colspan="5" style="font-weight: bold; padding: 8px">
              {{ statsData.otherCategory.categoryName }}
            </td>
          </tr>
          <tr
            v-if="statsData.otherCategory.services.length"
            v-for="(service, index) in statsData.otherCategory.services"
            :key="'other-' + service.serviceName">
            <td style="padding: 8px">{{ index + 1 }}</td>
            <td style="border: 1px solid #000; padding: 8px">
              {{ service.serviceName }}
            </td>
            <td style="border: 1px solid #000; text-align: right; padding: 8px">
              {{ service.price.toFixed(2) }}
            </td>
            <td style="border: 1px solid #000; text-align: right; padding: 8px">
              {{ service.quantity }}
            </td>
            <td style="border: 1px solid #000; text-align: right; padding: 8px">
              {{ service.subtotal.toFixed(2) }}
            </td>
          </tr>

          <!-- 总计行 -->
          <tr>
            <td
              colspan="3"
              style="
                border: 1px solid #000;
                padding: 8px;
                font-weight: bold;
                font-size: 20px;
              ">
              数量和金额总计
            </td>
            <td
              style="
                border: 1px solid #000;
                text-align: right;
                padding: 8px;
                font-weight: bold;
                font-size: 20px;
              ">
              {{ statsData.grandTotalQuantity }}
            </td>
            <td
              style="
                border: 1px solid #000;
                text-align: right;
                padding: 8px;
                font-weight: bold;
                font-size: 20px;
              ">
              {{ statsData.grandTotalAmount.toFixed(2) }} 元
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { Loading } from "@element-plus/icons-vue";
import request from "@/lib/request";
import dayjs from "dayjs";
import * as XLSX from "xlsx";

interface ServiceStatsItem {
  serviceName: string;
  price: number;
  unit: string;
  quantity: number;
  subtotal: number;
}

interface CategoryStats {
  categoryName: string;
  services: ServiceStatsItem[];
  totalQuantity: number;
  totalAmount: number;
}

interface StatsResponse {
  categories: CategoryStats[];
  otherCategory: CategoryStats;
  grandTotalQuantity: number;
  grandTotalAmount: number;
}
const print = {
  id: "print-container",
};
// 保持原有响应式数据结构
const loading = ref(false);
const searchForm = ref({
  dateRange: [
    dayjs().startOf("day").format("YYYY-MM-DD 00:00:00"),
    dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"),
  ] as string[],
  serviceName: "",
  categoryName: "",
});

const statsData = ref<StatsResponse>({
  categories: [],
  otherCategory: {
    categoryName: "其他服务",
    services: [],
    totalQuantity: 0,
    totalAmount: 0,
  },
  grandTotalQuantity: 0,
  grandTotalAmount: 0,
});

const categories = ref<Array<{ id: number; name: string }>>([]);
const showEmpty = computed(
  () =>
    statsData.value?.categories?.length === 0 &&
    statsData.value.otherCategory.services.length === 0
);

onMounted(async () => {
  try {
    await fetchCategories();
    await query();
  } catch (error) {
    handleError(error);
  }
});

const fetchCategories = async () => {
  try {
    const res = await request().get("/public/service-categories");
    categories.value = res.data.map((item: any) => ({
      id: item.value,
      name: item.label,
    }));
  } catch (error) {
    ElMessage.error("分类加载失败");
  }
};

const query = async () => {
  try {
    loading.value = true;

    const params = {
      startDate: searchForm.value.dateRange[0],
      endDate: searchForm.value.dateRange[1],
      serviceName: searchForm.value.serviceName,
      categoryName: searchForm.value.categoryName,
    };

    const res = await request().get("/stats/servicesStats", { params });
    statsData.value = res.data || res;
  } catch (error) {
    ElMessage.error(`查询失败: ${(error as Error).message}`);
  } finally {
    loading.value = false;
  }
};

const reset = () => {
  searchForm.value = {
    dateRange: [
      dayjs().startOf("day").format("YYYY-MM-DD 00:00:00"),
      dayjs().format("YYYY-MM-DD 23:59:59"),
    ],
    serviceName: "",
    categoryName: "",
  };
  query();
};

const dateChange = (val: string[]) => {
  if (val?.length === 2) {
    searchForm.value.dateRange = val;
  }
};

const handleError = (error: unknown) => {
  ElMessage({
    type: "error",
    message: "系统异常，请稍后重试",
    duration: 3000,
  });
};

function exportTableToExcel() {
  const table = document.querySelector(
    "#print-container table"
  ) as HTMLTableElement;
  if (!table) {
    console.error("找不到表格");
    return;
  }

  // 将 HTML 表格转换为 worksheet
  const worksheet = XLSX.utils.table_to_sheet(table, {
    raw: true,
  });

  // 获取范围
  const range = XLSX.utils.decode_range(worksheet["!ref"]!);

  // 遍历每个单元格，设置样式
  for (let R = range.s.r; R <= range.e.r; ++R) {
    for (let C = range.s.c; C <= range.e.c; ++C) {
      const cellAddress = XLSX.utils.encode_cell({ r: R, c: C });
      const cell = worksheet[cellAddress];
      if (!cell || !cell.v) continue;

      // 是否是最后一行（数量和金额总计行）
      const isLastRow = R === range.e.r;

      cell.s = {
        alignment: {
          horizontal: "center",
          vertical: "center",
          wrapText: true,
        },
        font: {
          bold: isLastRow, // 最后一行加粗
          sz: 12,
        },
        border: {
          top: { style: "thin", color: { rgb: "000000" } },
          bottom: { style: "thin", color: { rgb: "000000" } },
          left: { style: "thin", color: { rgb: "000000" } },
          right: { style: "thin", color: { rgb: "000000" } },
        },
      };
    }
  }

  // 创建工作簿并导出
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, "销售统计");
  XLSX.writeFile(workbook, "销售统计报表.xlsx");
}
</script>

<style scoped lang="scss">
.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.is-loading {
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

th,
td {
  border: 1px solid #000;
  padding: 8px;
  font-size: 14px;
  text-align: center !important;
}
@media print {
  /* 移除全局布局影响 */
  body,
  html {
    display: block !important;
    height: auto !important;
    margin: 2mm !important; /* 添加安全边距 */
  }

  #print-container {
    width: auto !important; /* 改为自动宽度 */
    margin: 0 auto !important; /* 居中显示 */
    font-size: 12pt !important; /* 调整字号 */
    min-height: 297mm;
  }

  table {
    table-layout: fixed;
    width: 100% !important;
  }

  /* 优化单元格内边距 */
  td,
  th {
    padding: 4px 2mm !important;
    line-height: 1.4 !important;
  }
}

tr,
td {
  font-size: 14px !important;
}

#print-container {
  width: 100% !important;
  margin: 0 !important;
  padding: 0 5mm !important;
  font-size: 14pt;
  color: #000 !important;
  font-family: Microsoft YaHei, "SimSun", serif !important;
}
/* 添加表格布局优化 */
table {
  width: 100% !important;
  table-layout: fixed;
  border-collapse: collapse !important;

  td,
  th {
    padding: 10px 2mm !important;
    word-wrap: break-word;
  }
}
</style>
