<template>
  <div>
    <my-card title="搜索条件" search>
      <n-form inline>
        <n-form-item label="设备编码">
          <n-input v-model:value="searchForm.equipmentCode" placeholder="请输入设备编码"></n-input>
        </n-form-item>
        <n-form-item label="故障类型">
          <n-input v-model:value="searchForm.breakdownName" placeholder="请输入故障类型"></n-input>
        </n-form-item>
        <n-form-item label="故障描述">
          <n-input v-model:value="searchForm.breakdownDescription" placeholder="请输入故障描述"></n-input>
        </n-form-item>
        <n-form-item label="维修方法">
          <n-input v-model:value="searchForm.repairMethod" placeholder="请输入维修方法"></n-input>
        </n-form-item>
        <n-form-item label="报修时间">
          <n-date-picker v-model:value="range" type="datetimerange" clearable />
        </n-form-item>
        <n-form-item label="状态">
          <n-select
            v-model:value="searchForm.status"
            class="w-180px"
            :options="[
              { label: '全部', value: '' },
              { label: '维修中', value: '0' },
              { label: '审批中', value: '1' },
              { label: '已完成', value: '2' }
            ]"
          ></n-select>
        </n-form-item>
        <n-form-item>
          <component
            :is="
              useSearchBtn(
                () => {
                  handleSearch();
                },
                () => {
                  resetThen();
                }
              )
            "
          ></component>
        </n-form-item>
      </n-form>
    </my-card>
    <my-card title="报修列表">
      <template #right>
        <div>
          <n-button size="small" type="info" style="margin-right: 10px" @click="openAddRepairs">
            <icon-mdi-add />
            新增报修
          </n-button>
          <CxColumns v-model:columns="columns" />
        </div>
      </template>
      <n-data-table
        :loading="loading"
        :columns="columns"
        :data="data"
        :max-height="dataTableConfig.maxHeight"
        :scroll-x="dataTableConfig.scrollWidth(columns)"
      ></n-data-table>
      <my-pagination v-model:search-form="searchForm" @init="init"></my-pagination>
    </my-card>

    <my-dialog
      title="新增报修单"
      width="800px"
      :show="showDialog"
      @cancel="() => (showDialog = false)"
      @submit="handleSubmit"
    >
      <template #content>
        <div>
          <n-form
            ref="addFormRef"
            :rules="rules"
            style="width: 700"
            :model="addForm"
            label-placement="left"
            label-width="auto"
          >
            <n-grid :cols="1" :x-gap="20">
              <n-form-item-grid-item label="报修设备" path="equipmentId">
                <n-select
                  v-model:value="addForm.equipmentId"
                  class="w-560px"
                  :options="equipmentList"
                  placeholder="请选择报修设备"
                  filterable
                  :disabled="!completeRequest"
                  @update:value="changeEquipment"
                />
              </n-form-item-grid-item>
              <n-form-item-grid-item label="故障类别" path="breakdownId">
                <n-select
                  v-model:value="addForm.breakdownId"
                  class="w-560px"
                  :options="faultCategoryList"
                  placeholder="请选择故障类别"
                  filterable
                  @update:value="changeBreakdown"
                />
              </n-form-item-grid-item>
              <n-form-item-grid-item label="故障描述" path="breakdownDescription">
                <n-input
                  v-model:value="addForm.breakdownDescription"
                  placeholder="请输入故障描述"
                  class="w-560px"
                  type="textarea"
                  size="small"
                  :autosize="{
                    minRows: 3,
                    maxRows: 5
                  }"
                />
              </n-form-item-grid-item>

              <n-form-item-grid-item label="上传图片" name="breakdownImage" required>
                <n-upload
                  class="w-560px"
                  :show-file-list="true"
                  :default-file-list="fileList"
                  :headers="{ Authorization: 'Bearer ' + useAuthStore().token }"
                  :default-upload="true"
                  :max="3"
                  multiple
                  :action="baseurl + '/file/upload'"
                  list-type="image-card"
                  :on-error="errorFile"
                  @finish="finish"
                  @remove="removeFile"
                ></n-upload>
              </n-form-item-grid-item>
            </n-grid>
          </n-form>
        </div>
      </template>
    </my-dialog>

    <div v-if="imageList.length > 0" class="image-box" @click="closeLookImages($event)">
      <n-image-group :theme-overrides="imageGroupThemeOverrides">
        <n-space>
          <n-image v-for="(item, index) in imageList" :key="index" width="100" :src="item" />
        </n-space>
      </n-image-group>
    </div>
  </div>
</template>

<script setup lang="tsx">
import type { Ref } from 'vue';
import { ref, onMounted, computed } from 'vue';
import type { DataTableColumns, GlobalThemeOverrides, FormInst, UploadFileInfo } from 'naive-ui';
import { useMessage, useThemeVars, useDialog } from 'naive-ui';
import { ArrowRedo } from '@vicons/ionicons5';
import { createRequiredFormRule } from '@/utils';
import {
  getRepairReportList,
  deleteRepairReport,
  addKnowledgeRepairReport,
  addRepairReport
} from '@/service/api/device/repairForm';
import { getBreakdownTypeList } from '@/service/api/device/facilityFaultCategory';
import { dataTableConfig } from '@/config/dataTableConfig';
import { useSearchBtn } from '~/src/hooks/common/useBtn';
import { useLoading } from '~/src/hooks/index';
import { formatDate } from '~/src/utils/form/rule';
import { useResetSearch } from '~/src/utils/common/searchReset';
import { getEquipmentAll } from '~/src/service/api/device/equipmentLedger';
import { serviceEnv } from '~/.env-config';
import { useAuthStore } from '~/src/store/modules/auth';
const { loading, startLoading, endLoading } = useLoading();
const message = useMessage();
const { searchForm, reset } = useResetSearch({
  pageNum: 1,
  pageSize: 10,
  status: '',
  equipmentCode: '',
  total: 0,
  breakdownName: '',
  breakdownDescription: '',
  repairMethod: '',
  params: {
    beginTime: null,
    endTime: null
  }
});

const imageList = ref<Array<string>>([]);

const addForm = ref<{
  equipmentId: null | number;
  equipmentName: string;
  equipmentCode: string;
  breakdownId: null;
  breakdownName: string;
  breakdownDescription: string;
  breakdownImage: string;
  status: string;
}>({
  equipmentId: null,
  equipmentName: '',
  equipmentCode: '',
  breakdownId: null,
  breakdownName: '',
  breakdownDescription: '',
  breakdownImage: '',
  status: '0'
});

const rules = {
  equipmentId: createRequiredFormRule('请选择报修机台'),
  breakdownId: createRequiredFormRule('请选择报修机台'),
  breakdownDescription: createRequiredFormRule('请输入故障描述'),
  breakdownImage: createRequiredFormRule('请选择故障图片')
};

type selectList = {
  value: number;
  label: string;
};

const data = ref<DataType[]>([]);

const completeRequest = ref<boolean>(true);
const baseurl = ref<string>(serviceEnv[import.meta.env.VITE_SERVICE_ENV as string].url);
const range = ref<[number, number] | null>(null);

const fileList = ref<UploadFileInfo[]>([]);
const showDialog = ref<boolean>(false);
const submitImages = ref<Array<selectList>>([]);

const equipmentList = ref<Array<selectList>>([]);
const faultCategoryList = ref<Array<selectList>>([]);
const addFormRef = ref<FormInst | null>(null);

const dialog = useDialog();
const statusMap = {
  0: {
    key: 'default',
    label: '确认到货'
  },
  1: {
    key: 'warning',
    label: '确认完成'
  },
  2: {
    key: 'success',
    label: '已到货'
  }
};

function handleInfo(row) {
  addKnowledgeRepairReport(row).then(res => {
    if (res.code === 200) {
      message.success('写入知识库成功');
      init();
    }
  });
}
type DataType = {
  id?: number;
  equipmentCode: string;
  breakdownName: string;
  breakdownDescription: string;
  breakdownImage: string;
  applyTime: Date;
  applyBy: string;
  repairTime: Date;
  repairBy: string;
  repairMethod: string;
  status: string;
  isKnowledge: number;
  approveTime: Date;
  maintainTime: string;
};
// const rowKey = (row: any) => row.id;
const columns: Ref<DataTableColumns<DataType>> = ref([
  {
    type: 'selection'
  },
  {
    title: '序号',
    key: 'index',
    width: 100,
    align: 'center',
    render: (_row, index) => (searchForm.value.pageNum - 1) * searchForm.value.pageSize + index + 1
  },
  {
    title: '设备编码',
    align: 'center',
    width: 100,
    key: 'equipmentCode'
  },
  {
    title: '故障类型',
    align: 'center',
    width: 100,
    key: 'breakdownName'
  },
  {
    title: '故障描述',
    align: 'center',
    width: 180,
    key: 'breakdownDescription',
    ellipsis: {
      tooltip: true
    }
  },
  {
    title: '故障图片',
    align: 'center',
    width: 180,
    key: '',
    ellipsis: {
      tooltip: true
    },
    render: row => {
      let images: Array<string> = [];
      if (row.breakdownImage) {
        images = row.breakdownImage.split(',');
      }
      if (images.length > 1) {
        images = images.slice(0, 1);
      }
      return (
        <n-image-group>
          <n-space>
            {images.map((item, index) => {
              return (
                <n-image
                  width="100"
                  src={item}
                  key={index}
                  preview-disabled={true}
                  onClick={() => {
                    previewImages(row.breakdownImage);
                  }}
                />
              );
            })}
          </n-space>
        </n-image-group>
      );
    }
  },
  {
    title: '报修时间',
    align: 'center',
    width: 180,
    key: 'applyTime'
  },
  {
    title: '报修人',
    align: 'center',
    width: 100,
    key: 'applyBy'
  },
  {
    title: '维修时间',
    align: 'center',
    width: 180,
    key: 'repairTime'
  },
  {
    title: '维修人',
    align: 'center',
    width: 150,
    key: 'repairBy'
  },
  {
    title: '维修方法',
    align: 'center',
    width: 180,
    key: 'repairMethod',
    ellipsis: {
      tooltip: true
    }
  },
  {
    title: '维修时长',
    align: 'center',
    width: 180,
    key: 'maintainTime',
    ellipsis: {
      tooltip: true
    }
  },
  {
    title: '审批人',
    align: 'center',
    width: 100,
    key: 'approveBy'
  },
  {
    title: '审批时间',
    align: 'center',
    width: 180,
    key: 'approveTime',
    render: row => (row.approveTime ? formatDate(new Date(row.approveTime), 'yyyy-MM-dd hh:mm:ss') : '')
  },
  {
    title: '审批结论',
    align: 'center',
    width: 180,
    key: 'attr1'
  },
  {
    title: '状态',
    align: 'center',
    width: 100,
    key: 'status',
    render(row) {
      return <n-tag type={statusMap[row.status].key}>{getStatus(row.status)}</n-tag>;
    }
  },
  {
    title: '操作',
    align: 'center',
    width: 280,
    fixed: 'right',
    key: '',
    render: row => {
      // let images: Array<string> = [];
      // if (row.breakdownImage) {
      //   images = row.breakdownImage.split(',');
      // }
      return (
        <n-space>
          <n-button
            size={'small'}
            type="info"
            onClick={() => {
              const url = `https://huaerda-jimu.24yt.com/jmreport/view/1017315497049653248?id=${row.id}`;
              window.open(url, '_blank');
            }}
          >
            打印单据
          </n-button>
          <n-button
            size={'small'}
            type="error"
            onClick={() => {
              deleteOne(row);
            }}
          >
            删除
          </n-button>
          <n-button
            color="#85E05B"
            size="small"
            v-show={row.status === '2' && row.isKnowledge === 0}
            onClick={() => handleInfo(row)}
          >
            <ArrowRedo class="mr-1px text-15px w-13px" />
            写入知识库
          </n-button>
          {/* <n-button
            attr-type="button"
            size={'small'}
            type="info"
            v-show={row.breakdownImage && !row.breakdownImage.includes('undefined') && images.length > 1}
            onClick={() => {
              previewImages(row.breakdownImage);
            }}
          >
            <icon-mdi-search />
            预览全部图片
          </n-button> */}
        </n-space>
      );
    }
  }
]);

function getStatus(status: string) {
  switch (status) {
    case '0':
      return '维修中';
    case '1':
      return '审批中';
    case '2':
      return '已完成';
    default:
      return '';
  }
}

function errorFile({ file, event }) {
  console.log(file, event);
  const response = JSON.parse(event.currentTarget.response);
  if (response.code !== 200) {
    message.error(response.msg);
  }
}

function finish({ file, event }) {
  const type = file?.type.split('/');
  if (type[0] === 'image') {
    const response = JSON.parse(event.currentTarget.response);
    if (response.code === 200) {
      submitImages.value.push({
        label: response.data.url,
        value: file.id
      });
    } else {
      message.error(response.msg);
    }
  } else {
    message.warning('请选择图片进行上传');
  }
}

function removeFile(e) {
  submitImages.value = submitImages.value.filter(item => item.value !== e.file.id);
}

function changeEquipment(value: number, item: any) {
  console.log('value ==>', value);
  addForm.value.equipmentCode = item.label;
  completeRequest.value = false;
  faultCategoryList.value = [];
  getBreakdownTypeList({ pageSize: 999999, typeName: item.workbenchType }).then(res => {
    completeRequest.value = true;
    if (res.code === 200) {
      const resultData = res.rows || [];
      resultData.forEach((val: any) => {
        faultCategoryList.value.push({
          label: val.breakdownName,
          value: val.id
        });
      });
    }
  });
}

const changeBreakdown = (value: number, item: selectList) => {
  console.log(value);
  addForm.value.breakdownName = item.label;
};

function openAddRepairs() {
  showDialog.value = true;
  addForm.value = {
    equipmentId: null,
    equipmentName: '',
    equipmentCode: '',
    breakdownId: null,
    breakdownName: '',
    breakdownDescription: '',
    breakdownImage: '',
    status: '0'
  };
  submitImages.value = [];
}

function handleSearch() {
  searchForm.value.pageNum = 1;
  if (range.value !== null) {
    searchForm.value.params.beginTime = formatDate(new Date(range.value[0]), 'yyyy-MM-dd');
    searchForm.value.params.endTime = formatDate(new Date(range.value[1]), 'yyyy-MM-dd');
  } else {
    searchForm.value.params.beginTime = null;
    searchForm.value.params.endTime = null;
  }
  init();
}
function resetThen() {
  reset();
  init();
}

function deleteOne(row: DataType) {
  const d = dialog.warning({
    title: '删除',
    content: '确认要删除吗?',
    positiveText: '确认',
    negativeText: '取消',
    onPositiveClick: () => {
      d.loading = true;
      deleteRepairReport(row).then(res => {
        if (res.code === 200) {
          window.$message?.success('删除成功');
          init();
        }
        return false;
      });
    }
  });
}

const imageGroupThemeOverrides = computed(() => {
  const { popoverColor, boxShadow2, textColor2, borderRadius } = useThemeVars().value;
  const themeOverrides: NonNullable<GlobalThemeOverrides['Image']> = {
    toolbarColor: popoverColor,
    toolbarBoxShadow: boxShadow2,
    toolbarIconColor: textColor2,
    toolbarBorderRadius: borderRadius
  };
  return themeOverrides;
});

function previewImages(imageUrl: string) {
  imageList.value = imageUrl.split(/,/);
}

function closeLookImages(event: any) {
  if (event.target.tagName.toLowerCase() === 'div') {
    imageList.value = [];
  }
}
function handleSubmit() {
  if (submitImages.value.length === 0) {
    message.warning('请选择图片进行上传');
    return;
  }
  addFormRef.value?.validate(errors => {
    if (!errors) {
      submitImages.value.forEach(item => {
        addForm.value.breakdownImage += `${item.label},`;
      });
      addForm.value.breakdownImage = addForm.value.breakdownImage.slice(0, -1);
      addRepairReport(addForm.value).then(res => {
        if (res.code === 200) {
          showDialog.value = false;
          init();
          message.success('添加成功');
        }
      });
    }
  });
}

function formatTimeDifference(timestamp) {
  // 获取毫秒差
  const diffInMs = Math.abs(timestamp);

  // 计算年差
  const years = Math.floor(diffInMs / (1000 * 60 * 60 * 24 * 365));

  // 计算月份差（按实际天数）
  let remainingMsAfterYears = diffInMs % (1000 * 60 * 60 * 24 * 365); // 剩余毫秒数
  const startDate = new Date(0); // 从 Unix 纪元开始
  startDate.setFullYear(startDate.getFullYear() + years);

  const months = Math.floor(remainingMsAfterYears / (1000 * 60 * 60 * 24 * 30.436875)); // 平均每月30.436875天，计算月份

  remainingMsAfterYears -= months * (1000 * 60 * 60 * 24 * 30.436875); // 更新剩余毫秒数

  // 计算天数差
  const days = Math.floor(remainingMsAfterYears / (1000 * 60 * 60 * 24));
  remainingMsAfterYears -= days * (1000 * 60 * 60 * 24); // 更新剩余毫秒数

  // 计算小时差
  const hours = Math.floor(remainingMsAfterYears / (1000 * 60 * 60));
  remainingMsAfterYears -= hours * (1000 * 60 * 60); // 更新剩余毫秒数

  // 计算分钟差
  const minutes = Math.floor(remainingMsAfterYears / (1000 * 60));
  remainingMsAfterYears -= minutes * (1000 * 60); // 更新剩余毫秒数

  // 计算秒差
  const seconds = Math.floor(remainingMsAfterYears / 1000);

  // 将时间数据按单位存储
  const timeData = [
    { time: years, test: '年' },
    { time: months, test: '月' },
    { time: days, test: '日' },
    { time: hours, test: '时' },
    { time: minutes, test: '分' },
    { time: seconds, test: '秒' }
  ];

  // 构建结果字符串
  let result = '';
  timeData.forEach(item => {
    if (item.time > 0) {
      result += item.time + item.test;
    }
  });

  return result || '0秒'; // 如果时间差为0，则返回'0秒'
}

function getList() {
  getEquipmentAll().then(res => {
    if (res.code === 200) {
      const resultData = res.data || [];
      resultData.forEach((item: any) => {
        equipmentList.value.push({
          label: item.equipmentCode,
          value: item.id,
          ...item
        });
      });
    }
  });
}

function init() {
  startLoading();
  getRepairReportList(searchForm.value).then(res => {
    const resultData = res.rows || [];
    data.value = resultData.map(item => {
      if (item.applyTime && item.repairTime) {
        const timestamp = new Date(item.repairTime).getTime() - new Date(item.applyTime).getTime();
        item.maintainTime = formatTimeDifference(timestamp);
      }
      return item;
    });
    searchForm.value.total = res.total;
    endLoading();
  });
}
onMounted(() => {
  init();
  getList();
});
</script>

<style lang="scss" scoped>
.image-box {
  width: 100%;
  height: 100vh;
  position: absolute;
  left: 0;
  top: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 99;
  display: flex;
  align-items: center;
  justify-content: center;
}

:deep(.n-space) {
  justify-content: flex-start !important;
}
</style>
