<template>
  <el-card>
    <template #header>
      <div class="card-header">
        <PlusForm
          :key="queryKey"
          v-model="queryState"
          :group="queryGroup"
          label-position="right"
        >
          <template #footer="{}">
            <div></div>
          </template>

          <template #plus-group-one="scoped">
            <div>
              <el-date-picker
                v-model="queryState.queryTime"
                type="datetimerange"
                :shortcuts="queryTimeShortCuts"
                range-separator="至"
                start-placeholder="开始日期时间"
                end-placeholder="结束日期时间"
                :popper-options="{
                  placement: 'bottom-start'
                }"
                :size="dynamicSize"
                :disabled="size === 'disabled'"
              />

              <el-button
                style="margin-left: 10px"
                type="primary"
                :icon="useRenderIcon(Search)"
                @click="handleQuery"
                >查询</el-button
              >
              <el-button
                :icon="useRenderIcon(IconDownLoad)"
                @click="handleExport"
                >导出到Excel</el-button
              >

              <el-button type="primary" @click="isHideInGroup = !isHideInGroup">
                {{ isHideInGroup ? "显示筛选器" : "隐藏筛选器" }}
              </el-button>

              <el-button
                :icon="useRenderIcon(IconUpload)"
                @click="updateAttends"
                >更新到服务器</el-button
              >
            </div>
          </template>
        </PlusForm>
      </div>
    </template>

    <div>
      <pure-table
        align-whole="center"
        :header-cell-style="{
          background: 'var(--el-fill-color-light)',
          color: 'var(--el-text-color-primary)'
        }"
        :columns="columns"
        :table-key="tableKey"
        border
        adaptive
        :adaptiveConfig="adaptiveConfig"
        showOverflowTooltip
        :loading="false"
        :loading-config="loadingConfig"
        :data="
          dataFilter.slice(
            (pagination.currentPage - 1) * pagination.pageSize,
            pagination.currentPage * pagination.pageSize
          )
        "
        :pagination="pagination"
        @page-size-change="onSizeChange"
        @page-current-change="onCurrentChange"
        :has-toolbar="true"
      >
        <template #toolbar>
          <el-button plain size="small">查看日志</el-button>
          <el-button plain size="small">导出数据</el-button>
          <el-button type="primary" size="small">创建应用</el-button>
        </template>

        <template #operation="{ row, index }">
          <div v-if="!editMap[index]?.editable">
            <el-button
              class="reset-margin"
              link
              type="primary"
              :icon="useRenderIcon(Delete)"
              @click="onDel(row)"
            >
              删除
            </el-button>
            <el-button
              class="reset-margin"
              link
              type="primary"
              @click="onEdit(row, index)"
              :icon="useRenderIcon(EditFill)"
            >
              修改
            </el-button>
          </div>

          <div v-if="editMap[index]?.editable">
            <el-button
              class="reset-margin"
              link
              type="primary"
              @click="onSave(index)"
              :icon="useRenderIcon(SaveFill)"
            >
              保存
            </el-button>
            <el-button
              class="reset-margin"
              link
              @click="onCancel(index)"
              :icon="useRenderIcon(Close)"
            >
              取消
            </el-button>
          </div>
        </template>
      </pure-table>
    </div>
  </el-card>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from "vue";
import { useColumns } from "./columns";
import {
  type PlusColumn,
  type FieldValues,
  PlusForm,
  PlusFormGroupRow
} from "plus-pro-components";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import AddFill from "~icons/ep/plus";
import Delete from "~icons/ep/delete";
import EditFill from "~icons/ep/edit";
import SaveFill from "~icons/bi/save";
import Close from "~icons/ep/close";
import Search from "~icons/ep/search";
import IconDownLoad from "~icons/ep/download";
import IconUpload from "~icons/ep/upload";
import { ElNotification, ElMessageBox } from "element-plus";
import * as XLSX from "xlsx";
import Attend from "@/model/attend";
import {
  fetchHisAttend,
  deleteHisAttend,
  modifyHisAttends
} from "@/api/attend";
import { debounce } from "lodash";

const queryTimeShortCuts = [
  {
    text: "今天",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      const end = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() + 1
      );
      return [start, end];
    }
  },
  {
    text: "昨天",
    value: () => {
      const now = new Date();
      const start = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - 1
      );
      const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      return [start, end];
    }
  },
  {
    text: "本周",
    value: () => {
      const now = new Date();
      const start = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - now.getDay()
      );
      const end = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - now.getDay() + 6
      );
      return [start, end];
    }
  },
  {
    text: "本月",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), 1);
      const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
      return [start, end];
    }
  }
];

const isHideInGroup = ref(true);

const QC_IDX_PROJ = 0;

const queryGroup: PlusFormGroupRow[] = [
  {
    title: "记录搜索",
    icon: Search,
    // 自动生成 plus-group-one 插槽，v0.1.25 新增
    name: "one",
    // 当plus-group-one 插槽存在时，这里的配置将不会生效
    columns: [
      {
        label: "名称",
        prop: "name"
      }
    ]
  },
  {
    title: "记录筛选",
    // icon: Calendar,
    name: "two",
    hideInGroup: computed(() => {
      return isHideInGroup.value;
    }),
    columns: [
      {
        label: "项目名称",
        width: 120,
        prop: "queryProjectName",
        valueType: "input",
        colProps: {
          span: 6
        }
      },
      {
        label: "区域名称",
        width: 120,
        prop: "queryLocationName",
        valueType: "input",
        colProps: {
          span: 6
        }
      },
      {
        label: "人员名称",
        width: 120,
        prop: "queryPersonName",
        valueType: "input",
        colProps: {
          span: 6
        }
      },
      {
        label: "电话",
        width: 120,
        prop: "queryPhone",
        valueType: "input",
        colProps: {
          span: 6
        }
      }
    ]
  }
];

const dynamicSize = ref();
const queryState = ref({
  queryTime: [
    new Date(
      new Date().getFullYear(),
      new Date().getMonth(),
      new Date().getDate()
    ),
    new Date(
      new Date().getFullYear(),
      new Date().getMonth(),
      new Date().getDate() + 1
    )
  ],
  queryProjectName: "",
  queryLocationName: "",
  queryPersonName: "",
  queryPhone: ""
});
const queryKey = ref(0);

// 防抖处理，500ms内连续输入只执行一次
const debouncedDoFilter = debounce(() => {
  doFilter();
}, 200);

// 监听变化并使用防抖处理
watch(
  [
    () => queryState.value.queryPersonName,
    () => queryState.value.queryProjectName,
    () => queryState.value.queryLocationName,
    () => queryState.value.queryPhone
  ],
  debouncedDoFilter
);

const projects = ref([]);

const {
  editMap,
  columns,
  dataList,
  dataFilter,
  pagination,
  loadingConfig,
  adaptiveConfig,
  getProjectName,
  getLocName,
  onEdit,
  onSave,
  onCancel,
  onDel,
  onSizeChange,
  onCurrentChange
} = useColumns(projects);

const swEditable = ref(true);
const tableKey = ref(0);
const vGlobal = window.vueGlobal;
const dlgImportExcelVisible = ref(false);
const excelData = ref([]);

const attends = ref([]);

const reloadProjects = () => {
  vGlobal.refreshProjects(() => {
    projects.value = [];
    projects.value = vGlobal.vecProject.slice(0);
    console.log("reloadProjects 1", projects.value);
    queryKey.value += 1;
  });
};

const getAttendRecord = () => {
  const queryParams = {
    beginTime: queryState.value.queryTime[0].getTime(),
    endTime: queryState.value.queryTime[1].getTime()
  };
  fetchHisAttend(queryParams).then(res => {
    if (res.success) {
      attends.value = [];
      dataList.value = [];
      console.log("res ", res.items);
      for (const item of res.items) {
        const obj = JSON.parse(item.jstr);
        const attend = new Attend(obj);
        attends.value.push(attend);
        attend.ancAddr = Number(item["ancAddr"]) || 0;
        for (const attendItem of attend.items) {
          dataList.value.push(attendItem);
        }
      }

      doFilter();

      ElNotification.success({
        message: "查询成功"
      });
    }
  });
};

const doFilter = () => {
  dataFilter.value = dataList.value.filter(item => {
    if (
      queryState.value.queryPersonName.length > 0 &&
      item.name.indexOf(queryState.value.queryPersonName) < 0
    ) {
      return false;
    }
    if (
      queryState.value.queryProjectName.length > 0 &&
      getProjectName(item.projId).indexOf(queryState.value.queryProjectName) < 0
    ) {
      return false;
    }
    if (
      queryState.value.queryLocationName.length > 0 &&
      getLocName(item.projId, item.locId).indexOf(
        queryState.value.queryLocationName
      ) < 0
    ) {
      return false;
    }
    if (
      queryState.value.queryPhone.length > 0 &&
      item.phone.indexOf(queryState.value.queryPhone) < 0
    ) {
      return false;
    }

    return true;
  });
  pagination.total = dataFilter.value.length;
  // tableKey.value++;
};

const updateAttends = () => {
  ElMessageBox.confirm("确定更新考勤数据?更新后将无法撤回", "Warning", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(() => {
      ElNotification.info({
        message: "开始更新"
      });
      const vecAttend = [];
      for (const v of attends.value) {
        vecAttend.push(v.toJson());
      }
      modifyHisAttends({ attends: vecAttend }).then(res => {
        if (res.success) {
          ElNotification.success({
            message: "更新成功"
          });
        } else {
          ElNotification.error({
            message: "更新失败"
          });
        }
      });
    })
    .catch(() => {
      // ElMessage({
      //   type: 'info',
      //   message: 'Delete canceled',
      // })
    });
};

// 导出逻辑
const handleExport = () => {
  try {
    // 1. 处理导出数据
    const exportData = dataFilter.value.map(item => ({
      时间: new Date(item.tm).toLocaleString(),
      项目名称: getProjectName(item.projId),
      区域名称: getLocName(item.projId, item.locId),
      人员ID: item.id,
      人员名称: item.name,
      职位: item.job,
      电话: item.phone,
      标签ID: item.tagId,
      在线状态: item.rssi != 0 ? "在线" : "离线",
      到岗状态: item.confirm ? "到岗" : "缺岗"
    }));

    if (exportData.length === 0) {
      ElNotification.warning({ message: "没有可导出的数据" });
      return;
    }

    // 2. 创建工作表
    const worksheet = XLSX.utils.json_to_sheet(exportData);

    // 3. 计算列宽（关键步骤）
    const header = Object.keys(exportData[0]);
    const cols = header.map(key => {
      // 计算表头文字长度
      let maxLength = key.length * 2;

      // 计算数据列最大文字长度
      exportData.forEach(row => {
        const value = String(row[key] || "");
        // 中文字符宽度约为英文字符的2倍，这里做特殊处理
        const length = value.replace(/[^\x00-\xff]/g, "aa").length;
        if (length > maxLength) {
          maxLength = length;
        }
      });

      // 增加缓冲宽度（避免内容太满）
      return { width: maxLength + 2 };
    });

    // 设置列宽配置
    worksheet["!cols"] = cols;

    // 4. 创建工作簿并添加工作表
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, "考勤记录");

    // 5. 生成Excel文件并下载
    const fileName = `考勤记录_${new Date().getTime()}.xlsx`;
    XLSX.writeFile(workbook, fileName);
  } catch (error) {
    console.error("导出失败:", error);
    ElNotification.error({
      message: "导出失败，请重试"
    });
  }
};

const handleQuery = () => {
  getAttendRecord();
};

onMounted(() => {
  reloadProjects();
});
</script>
