<script setup lang="ts">
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
import { IotSapStockApi, IotSapStockVO } from '@/api/pms/iotsapstock'
import * as SapOrgApi from '@/api/system/saporg'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import CountTo from '@/components/count-to1.vue'

defineOptions({ name: 'IotSapStock' })

type StockRow = IotSapStockVO & {
  totalQuantity?: number | string
  totalAmount?: number | string
  createTime?: string
}

interface QueryParams extends PageParam {
  deptId?: number
  factoryId?: number
  factory?: string
  storageLocationId?: number
  projectDepartment?: string
  materialCode?: string
  materialName?: string
  materialGroupName?: string
  materialGroupId?: number
  quantity?: number
  unitPrice?: number
  unit?: string
  safetyStock?: number
  shelvesId?: number
  cargoLocationId?: number
  type?: number
  syncStatus?: number
  syncTime?: string[]
  syncError?: string
  sort?: number
  status?: number
  remark?: string
  configFlag?: string
  createTime?: string[]
}

interface SelectedFactoryReqVO {
  type: number
  factoryCodes: string[]
}

const { t } = useI18n()
const message = useMessage()
const { ZmTable, ZmTableColumn } = useTableComponents<StockRow>()

const initQuery: QueryParams = {
  pageNo: 1,
  pageSize: 10,
  deptId: undefined,
  factoryId: undefined,
  factory: undefined,
  storageLocationId: undefined,
  projectDepartment: undefined,
  materialCode: undefined,
  materialName: undefined,
  materialGroupName: undefined,
  materialGroupId: undefined,
  quantity: undefined,
  unitPrice: undefined,
  unit: undefined,
  safetyStock: undefined,
  shelvesId: undefined,
  cargoLocationId: undefined,
  type: undefined,
  syncStatus: undefined,
  syncTime: [],
  syncError: undefined,
  sort: undefined,
  status: undefined,
  remark: undefined,
  configFlag: 'A',
  createTime: []
}

const queryParams = reactive<QueryParams>({ ...initQuery })
const queryFormRef = ref()
const loading = ref(false)
const exportLoading = ref(false)
const list = ref<StockRow[]>([])
const total = ref(0)
const totalQuantity = ref(0)
const totalAmount = ref(0)
const factoryList = ref<SapOrgApi.SapOrgVO[]>([])
const storageLocationList = ref<SapOrgApi.SapOrgVO[]>([])

const resultOptions = computed(() => [
  { label: '全部', value: 'A' },
  { label: '是', value: 'Y' },
  { label: '否', value: 'N' }
])

const stockStatCards = computed(() => [
  {
    label: t('stock.totalQuantity'),
    value: totalQuantity.value,
    prefix: '',
    unit: '',
    decimals: 0,
    icon: 'i-tabler:packages text-sky'
  },
  {
    label: t('stock.totalAmount'),
    value: totalAmount.value,
    prefix: '¥',
    unit: '',
    decimals: 2,
    icon: 'i-material-symbols:payments-outline-rounded text-emerald'
  }
])

const getList = async () => {
  loading.value = true
  try {
    const data = await IotSapStockApi.getIotSapStockPage(queryParams)
    list.value = data.list
    total.value = data.total

    const firstRow = data.list?.[0]
    totalQuantity.value = Number(firstRow?.totalQuantity) || 0
    totalAmount.value = Number(firstRow?.totalAmount) || 0
  } finally {
    loading.value = false
  }
}

const loadSapOrgOptions = async () => {
  const [factories, storageLocations] = await Promise.all([
    SapOrgApi.SapOrgApi.getSimpleSapOrgList(1),
    SapOrgApi.SapOrgApi.getSimpleSapOrgList(3)
  ])
  factoryList.value = factories
  storageLocationList.value = storageLocations
}

const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

const resetQuery = () => {
  Object.assign(queryParams, { ...initQuery })
  queryFormRef.value?.resetFields()
  handleQuery()
}

const handleSizeChange = (val: number) => {
  queryParams.pageSize = val
  handleQuery()
}

const handleCurrentChange = (val: number) => {
  queryParams.pageNo = val
  getList()
}

const selectedFactoryChange = async (selectedId: number | undefined) => {
  queryParams.storageLocationId = undefined

  if (!selectedId) {
    storageLocationList.value = await SapOrgApi.SapOrgApi.getSimpleSapOrgList(3)
    return
  }

  const selectedFactory = factoryList.value.find((item) => item.id === selectedId)
  const selectedFactoryReqVO: SelectedFactoryReqVO = {
    type: 3,
    factoryCodes: selectedFactory?.factoryCode ? [selectedFactory.factoryCode] : []
  }
  storageLocationList.value = await SapOrgApi.SapOrgApi.getSelectedList(selectedFactoryReqVO)
}

const handleExport = async () => {
  try {
    exportLoading.value = true
    const data = await IotSapStockApi.exportIotSapStock(queryParams)
    download.excel(data, 'SPA库存.xls')
  } catch {
    message.error('导出失败')
  } finally {
    exportLoading.value = false
  }
}

onMounted(() => {
  loadSapOrgOptions()
  getList()
})
</script>

<template>
  <div
    class="iot-sap-stock-page grid grid-rows-[auto_auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
  >
    <el-form
      ref="queryFormRef"
      :model="queryParams"
      size="default"
      label-width="82px"
      class="iot-sap-stock-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0"
    >
      <div class="query-row">
        <el-form-item :label="t('workOrderMaterial.factory')" prop="factoryId">
          <el-select
            v-model="queryParams.factoryId"
            clearable
            filterable
            :placeholder="t('faultForm.choose')"
            class="query-control"
            @change="selectedFactoryChange"
          >
            <el-option
              v-for="item in factoryList"
              :key="item.id"
              :label="item.factoryName"
              :value="item.id!"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('workOrderMaterial.storageLocation')" prop="storageLocationId">
          <el-select
            v-model="queryParams.storageLocationId"
            clearable
            filterable
            :placeholder="t('faultForm.choose')"
            class="query-control"
          >
            <el-option
              v-for="item in storageLocationList"
              :key="item.id"
              :label="item.storageLocationName"
              :value="item.id!"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('chooseMaintain.materialCode')" prop="materialCode">
          <el-input
            v-model="queryParams.materialCode"
            :placeholder="t('chooseMaintain.materialCode')"
            clearable
            class="query-control"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item :label="t('chooseMaintain.materialName')" prop="materialName">
          <el-input
            v-model="queryParams.materialName"
            :placeholder="t('chooseMaintain.materialName')"
            clearable
            class="query-control"
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item :label="t('chooseMaintain.createTime')" prop="createTime">
          <el-date-picker
            v-model="queryParams.createTime"
            value-format="YYYY-MM-DD HH:mm:ss"
            type="daterange"
            :start-placeholder="t('info.start')"
            :end-placeholder="t('info.end')"
            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
            class="query-control query-control--date"
          />
        </el-form-item>
        <el-form-item :label="t('route.IsItConfigured')" prop="configFlag" label-width="116px">
          <el-select
            v-model="queryParams.configFlag"
            :placeholder="t('faultForm.choose')"
            clearable
            class="query-control query-control--small"
          >
            <el-option
              v-for="dict in resultOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
      </div>

      <div class="query-side">
        <el-form-item class="query-actions">
          <el-button type="primary" @click="handleQuery">
            <Icon icon="ep:search" class="mr-5px" />{{ t('operationFill.search') }}
          </el-button>
          <el-button @click="resetQuery">
            <Icon icon="ep:refresh" class="mr-5px" />{{ t('operationFill.reset') }}
          </el-button>
          <el-button type="success" plain :loading="exportLoading" @click="handleExport">
            <Icon icon="ep:download" class="mr-5px" />导出
          </el-button>
        </el-form-item>
      </div>
    </el-form>

    <div class="stock-stat-grid">
      <div v-for="item in stockStatCards" :key="item.label" class="stock-stat-card group">
        <div class="relative z-10 flex h-full flex-col justify-center">
          <span class="stat-label">{{ item.label }}</span>
          <div class="flex items-baseline gap-1">
            <span v-if="item.prefix" class="text-[12px] text-gray-400">{{ item.prefix }}</span>
            <count-to
              class="stat-value"
              :start-val="0"
              :end-val="item.value"
              :decimals="item.decimals"
            />
            <span v-if="item.unit" class="stat-unit">{{ item.unit }}</span>
          </div>
        </div>
        <div class="stat-icon">
          <div :class="item.icon" class="text-5xl"></div>
        </div>
      </div>
    </div>

    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 min-w-0 min-h-0">
      <div class="flex-1 relative min-h-0">
        <el-auto-resizer class="absolute">
          <template #default="{ width, height }">
            <ZmTable
              :data="list"
              :loading="loading"
              :width="width"
              :height="height"
              :max-height="height"
              show-border
            >
              <ZmTableColumn
                type="index"
                :label="t('monitor.serial')"
                :width="70"
                fixed="left"
                hide-in-column-settings
              />
              <ZmTableColumn
                prop="factory"
                :label="t('workOrderMaterial.factory')"
                min-width="120"
              />
              <ZmTableColumn
                prop="projectDepartment"
                :label="t('workOrderMaterial.storageLocation')"
                min-width="140"
              />
              <ZmTableColumn
                prop="materialCode"
                :label="t('chooseMaintain.materialCode')"
                min-width="150"
              />
              <ZmTableColumn
                prop="materialName"
                :label="t('chooseMaintain.materialName')"
                min-width="220"
                align="left"
              />
              <ZmTableColumn prop="quantity" :label="t('route.quantity')" min-width="100" />
              <ZmTableColumn
                prop="unitPrice"
                :label="t('workOrderMaterial.unitPrice')"
                min-width="100"
              />
              <ZmTableColumn prop="unit" :label="t('workOrderMaterial.unit')" min-width="90" />
              <ZmTableColumn prop="safetyStock" :label="t('route.safetyStock')" min-width="120" />
              <ZmTableColumn
                prop="createTime"
                :label="t('chooseMaintain.createTime')"
                min-width="180"
                action
              >
                <template #default="{ row }">
                  {{ dateFormatter(row, null, row.createTime) }}
                </template>
              </ZmTableColumn>
            </ZmTable>
          </template>
        </el-auto-resizer>
      </div>

      <div class="h-8 mt-2 flex items-center justify-end">
        <el-pagination
          v-show="total > 0"
          size="default"
          :current-page="queryParams.pageNo"
          :page-size="queryParams.pageSize"
          :background="true"
          :page-sizes="[10, 20, 30, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
.iot-sap-stock-query {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}

.query-row {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 22px;
  min-width: 0;
}

.query-side {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 12px 18px;
}

.stat-label {
  margin-bottom: 2px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--el-text-color-regular);
}

.stat-value {
  font-family: var(--el-font-family);
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  color: var(--el-text-color-primary);
}

.stat-unit {
  font-size: 10px;
  font-weight: 400;
  color: var(--el-text-color-secondary);
}

.stock-stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.stock-stat-card {
  position: relative;
  min-height: 78px;
  padding: 10px 14px;
  overflow: hidden;
  background-color: var(--el-bg-color);
  border: 1px solid var(--el-border-color-extra-light);
  border-radius: 8px;
  box-shadow: var(--el-box-shadow-lighter);
  transition:
    border-color 0.3s,
    box-shadow 0.3s;
}

.stock-stat-card:hover {
  border-color: var(--el-color-primary-light-7);
  box-shadow: var(--el-box-shadow-light);
}

.stat-icon {
  position: absolute;
  right: -8px;
  bottom: -12px;
  opacity: 0.4;
  transform: rotate(-10deg);
  transition:
    transform 0.5s,
    opacity 0.5s;
}

.stock-stat-card:hover .stat-icon {
  opacity: 0.55;
  transform: scale(1.08) rotate(0);
}

.query-actions {
  flex: 0 0 auto;
}

.query-actions :deep(.el-form-item__content) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.query-actions :deep(.el-button) {
  margin-left: 0;
}

.query-control {
  width: 190px;
}

.query-control--small {
  width: 140px;
}

.query-control--date {
  width: 220px;
}

:deep(.el-form-item) {
  margin-bottom: 0;
}

@media (width >= 2400px) {
  .iot-sap-stock-query,
  .query-row,
  .query-side {
    flex-wrap: nowrap;
  }
}

@media (width <= 1500px) {
  .iot-sap-stock-query,
  .query-row {
    gap: 12px 18px;
  }

  .query-control {
    width: 176px;
  }

  .query-control--small {
    width: 132px;
  }

  .query-control--date {
    width: 210px;
  }
}

@media (width <= 1200px) {
  .iot-sap-stock-page {
    grid-template-rows: auto auto minmax(480px, 1fr);
    height: auto;
    min-height: calc(
      100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
    );
  }

  .query-side {
    width: 100%;
    justify-content: space-between;
  }
}

@media (width <= 768px) {
  .iot-sap-stock-query {
    padding: 12px;
  }

  .query-row,
  .query-row :deep(.el-form-item),
  .query-side,
  .query-actions {
    width: 100%;
  }

  .query-control,
  .query-control--small,
  .query-control--date {
    width: 100%;
  }

  .stock-stat-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .query-actions :deep(.el-form-item__content) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    width: 100%;
  }

  .query-actions :deep(.el-button) {
    width: 100%;
    margin-left: 0;
  }
}
</style>
