<template>
  <div class="stocking-order-page card h-100 flex overflow-hidden">
    <div class="order-status">
      <ElTree
        ref="treeRef"
        default-expand-all
        :expand-on-click-node="false"
        :default-expanded-keys="[]"
        :highlight-current="true"
        node-key="code"
        :data="treeData"
        :props="{ children: 'children', label: 'name' }"
        @node-click="nodeClick"
      >
        <template #default="{ data }">
          <div class="tree-node">
            <div class="tree-node-label">{{ data.name }}</div>
            <div
              v-if="data.countQuantity || data.countQuantity === 0"
              class="tree-node-count"
            >
              {{ `(${data.countQuantity})` }}
            </div>
          </div>
        </template>
      </ElTree>
    </div>
    <div class="order-content flex-1 flex-column overflow-hidden">
      <div class="header">
        <div class="header-search-form">
          <ElForm
            ref="searchFormRef"
            :model="searchForm"
            inline
            label-width="70px"
            class="search-form"
          >
            <ElFormItem label="备货仓库" prop="warehouseId">
              <ElSelect
                v-model="searchForm.warehouseId"
                placeholder="请选择"
                filterable
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
              >
                <ElOption
                  v-for="item in warehouseList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="订单时间" prop="orderTime">
              <ElDatePicker
                v-model="rangeTime"
                type="datetimerange"
                value-format="YYYY-MM-DD HH:mm:ss"
                clearable
                start-placeholder="开始时间"
                end-placeholder="结束时间"
              />
            </ElFormItem>
            <ElFormItem label="备货单号" prop="stockingUpManageNo">
              <ElInput
                v-model="searchForm.stockingUpManageNo"
                clearable
                placeholder="备货单号"
              />
            </ElFormItem>
            <ElFormItem label="供应商" prop="supplierId">
              <ElSelect
                v-model="searchForm.supplierId"
                placeholder="请选择"
                filterable
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
              >
                <ElOption
                  v-for="item in supplierList"
                  :key="item.id"
                  :label="item.supplierName"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="发货状态" prop="shippingStatusList">
              <ElSelect
                v-model="searchForm.shippingStatusList"
                placeholder="请选择"
                filterable
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
              >
                <ElOption
                  v-for="item in deliveryStatusList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="库存SKU" prop="warehouseSku">
              <ElInput
                v-model="searchForm.warehouseSku"
                clearable
                placeholder="库存SKU"
              />
            </ElFormItem>

            <ElFormItem label="备货员" prop="stockingUpUserId">
              <ElSelect
                v-model="searchForm.stockingUpUserId"
                placeholder="请选择"
                filterable
                multiple
                collapse-tags
                collapse-tags-tooltip
                clearable
              >
                <ElOption
                  v-for="item in stockKeeperList"
                  :key="item.id"
                  :label="item.account"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="商品名称" prop="warehouseSkuName">
              <ElInput
                v-model="searchForm.warehouseSkuName"
                clearable
                placeholder="商品名称"
              />
            </ElFormItem>
            <ElFormItem label="备注" prop="remark">
              <ElInput
                v-model="searchForm.remark"
                clearable
                placeholder="备注或内部便签"
              />
            </ElFormItem>

            <ElFormItem class="form-item-buttons">
              <ElButton type="primary" @click="() => search()">查询</ElButton>
              <ElButton @click="() => resetSearchForm()">重置</ElButton>
            </ElFormItem>
          </ElForm>
        </div>
        <div class="header-operation">
          <span v-if="status === 'PENDING_SUBMIT'" class="item">
            <ElButton type="success" @click="handleAddOrder">新增</ElButton>
          </span>
          <span v-if="status === 'PENDING_SUBMIT'" class="item">
            <ElButton type="primary" @click="handleSubmitAudit"
              >提交审核</ElButton
            >
          </span>

          <span v-if="status !== 'COMPLETED' && status !== 'CANCELLED'" class="item">
            <ElButton type="success" @click="addInternalTag"
              >添加内部便签</ElButton
            >
          </span>
          <span
            v-if="['PENDING_SUBMIT', 'STOCKING_UP'].includes(status)"
            class="item"
          >
            <ElButton type="warning" @click="handleCancelOrder">取消</ElButton>
          </span>
          <span v-if="status === 'PENDING_SUBMIT'" class="item">
            <ElButton type="danger" @click="handleDeleteOrder">删除</ElButton>
          </span>
        </div>
      </div>
      <div class="table-content">
        <SplitDiv size="60">
          <template #top>
            <div class="table-list flex-1 overflow-hidden">
              <TableView
                ref="tableRef"
                highlight-current-row
                :selectionable="true"
                :serial-numberable="true"
                :columns="tableColumns"
                :paginated-data="tableData"
                @row-click="handleRowClick"
                @selection-change="handleSelectionChange"
              />
            </div>
            <ElPagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[50, 100, 200, 300, 500]"
              background
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              style="margin: 10px auto 0; text-align: right"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            ></ElPagination>
          </template>
          <template #bottom>
            <StockingOrderDetailTabs :selected-row="selectedRow" />
          </template>
        </SplitDiv>
      </div>
    </div>
    <AddStockingOrderDialog
      ref="addStockingOrderDialogRef"
      :supplier-list="supplierList"
      :stock-keeper-list="stockKeeperList"
      :warehouse-list="warehouseList"
      :currency-list="currencyList"
      @refresh="onRefresh"
    />
    <SupplierDispatchOrderDialog
      ref="supplierDispatchOrderDialogRef"
      :warehouse-list="warehouseList"
      @refresh="onRefresh"
    />
  </div>
</template>
<script setup lang="tsx">
import { computed, ref } from 'vue'
import dayjs from 'dayjs'
import {
  getStockingOrderListApi,
  stockingCompleteApi,
  submitStockingOrderAuditApi,
  deleteStockingOrderApi,
  cancelStockingOrderApi,
  addStockingOrderInternalTagApi,
} from '@/api/supplier/stockingOrder'
import TableView from '@/components/TableView.vue'
import StockingOrderDetailTabs from './StockingOrderDetailTabs.vue'
import AddStockingOrderDialog from './AddStockingOrderDialog.vue'
import SupplierDispatchOrderDialog from './SupplierDispatchOrderDialog.vue'
import {
  TreeData,
  SearchForm,
  TableData,
} from '@/types/api/supply/stockingOrder'
import usePageList from '@/utils/hooks/usePageList'
import { useValue } from '@/utils/hooks/useValue'
import { CurrencyCodeData, SupplierItem, WarehouseListData } from '@/types'
import {
  getBaseCurrencyInfoApi,
  getEmployeeListApi,
  getSupplierListApi,
  loadWarehouseListApi,
} from '@/api/common'
import { getStockingOrderStatusTreeApi } from '@/api/supplier/stockingOrder'
import { userData } from '@/types/api/user'
import { ElButton, ElTag } from 'element-plus'
const deliveryStatusList = ref([
  { label: '待发货', value: '0' },
  { label: '部分发货', value: '1' },
  { label: '全部发货', value: '2' },
])
const tableColumns = computed(() => {
  return [
    {
      label: '备货单号',
      prop: 'stockingUpManageNo',
      minWidth: 200,
      align: 'center',
      render: (row: TableData) => {
        const isDelayed =
          row.expectDeliveryTime &&
          dayjs()
            .startOf('day')
            .diff(dayjs(row.expectDeliveryTime).startOf('day'), 'day') > 0
        return (
          <div style="position: relative; width: 100%;">
            {isDelayed && (
              <ElTag
                type="danger"
                size="small"
                style="position: absolute; left: -10px; top: 2px; transform: scale(0.8);"
              >
                延期
              </ElTag>
            )}
            <span>{row.stockingUpManageNo}</span>
          </div>
        )
      },
    },
    {
      label: '备货仓库',
      prop: 'warehouseName',
      width: 120,
      align: 'center',
    },
    {
      label: '供应商',
      prop: 'supplierName',
      width: 120,
      align: 'center',
    },
    {
      label: '订单状态',
      prop: 'status',
      width: 100,
      align: 'center',
      render: (row: TableData) => {
        if (row.status === 'PENDING_SUBMIT') {
          return <ElTag type="primary">待提交</ElTag>
        }
        if (row.status === 'PENDING_AUDIT') {
          return <ElTag type="warning">待审核</ElTag>
        }
        if (row.status === 'STOCKING_UP') {
          return <ElTag type="success">备货中</ElTag>
        }
        if (row.status === 'COMPLETED') {
          return <ElTag type="success">备货完成</ElTag>
        }
        if (row.status === 'CANCELLED') {
          return <ElTag type="danger">已取消</ElTag>
        }
      },
    },
    {
      label: '期望交货日期',
      prop: 'expectDeliveryTime',
      width: 160,
      align: 'center',
    },
    {
      label: 'SKU个数',
      prop: 'skuTotal',
      width: 100,
      align: 'right',
    },
    {
      label: '备货总数',
      prop: 'total',
      width: 100,
      align: 'right',
    },
    {
      label: '备货总额',
      prop: 'totalPrice',
      width: 120,
      align: 'right',
    },
    {
      label: '币种',
      prop: 'currencyCode',
      width: 80,
      align: 'center',
    },
    {
      label: '发货状态',
      prop: 'shippingStatus',
      width: 100,
      align: 'center',
      render: (row: TableData) => {
        return (
          <span>
            {row.shippingStatus && (
              <ElTag type="primary">
                {getDeliveryStatusName(row.shippingStatus)}
              </ElTag>
            )}
          </span>
        )
      },
    },
    {
      label: '备货员',
      prop: 'stockingUpUserName',
      width: 100,
      align: 'center',
    },
    {
      label: '最后交货日期',
      prop: 'lastDeliveryTime',
      width: 160,
      align: 'center',
    },
    {
      label: '订单完成日期',
      prop: 'completeTime',
      width: 160,
      align: 'center',
    },
    {
      label: '延误天数',
      prop: 'delayDays',
      width: 100,
      align: 'center',
      render: (row: TableData) => {
        if (!row.expectDeliveryTime) return <span>-</span>
        let delayDays: number
        if (row.completeTime) {
          delayDays = dayjs(row.completeTime)
            .startOf('day')
            .diff(dayjs(row.expectDeliveryTime).startOf('day'), 'day')
        } else {
          delayDays = dayjs()
            .startOf('day')
            .diff(dayjs(row.expectDeliveryTime).startOf('day'), 'day')
        }
        if (delayDays > 0 && row.status !== 'CANCELLED') {
          return (
            <span style="color: #f56c6c; font-weight: bold;">{delayDays}</span>
          )
        }
        return <span>-</span>
      },
    },
    {
      label: '制单人',
      prop: 'createUserName',
      width: 100,
      align: 'center',
    },
    {
      label: '审核人',
      prop: 'auditName',
      width: 100,
      align: 'center',
    },
    {
      label: '制单时间',
      prop: 'createTime',
      width: 160,
      align: 'center',
      sortable: true,
    },
    {
      label: '审核时间',
      prop: 'auditTime',
      width: 160,
      align: 'center',
      sortable: true,
    },
    {
      label: '备注',
      prop: 'remark',
      minWidth: 150,
      align: 'left',
      showOverflowTooltip: true,
    },
    {
      label: '操作',
      prop: 'operation',
      width: 180,
      align: 'center',
      fixed: 'right',
      render: (row: TableData) => {
        return (
          <span>
            {row.status === 'PENDING_SUBMIT' && (
              <ElButton
                link
                type="warning"
                onClick={() => handleOrder(row, 'edit')}
              >
                编辑
              </ElButton>
            )}
            {row.status === 'PENDING_AUDIT' && (
              <ElButton
                link
                type="success"
                onClick={() => handleOrder(row, 'audit')}
              >
                审核
              </ElButton>
            )}
            {row.status === 'STOCKING_UP' && (
              <ElButton
                link
                type="primary"
                onClick={() => handleSupplierDispatchOrder(row)}
              >
                供应商发货
              </ElButton>
            )}
            {row.status === 'STOCKING_UP' && (
              <ElButton
                link
                type="warning"
                onClick={() => stockingComplete(row)}
              >
                备货完成
              </ElButton>
            )}
          </span>
        )
      },
    },
  ]
})

const treeData = ref<TreeData[]>([])
const status = ref<string>('PENDING_SUBMIT')
const selectedRow = ref<TableData | null>(null)

const warehouseList = ref<WarehouseListData[]>([])
const supplierList = ref<SupplierItem[]>([])
const stockKeeperList = ref<userData[]>([])
const currencyList = ref<CurrencyCodeData[]>([])

const selection = ref<TableData[]>([])
const rangeTime = ref<string[]>([])
const [searchForm, resetSearchForm] = useValue<SearchForm>({} as SearchForm)
const treeRef = ref()
const tableRef = ref()
const supplierDispatchOrderDialogRef = ref()
const addStockingOrderDialogRef = ref()
const loadWarehouseList = async () => {
  try {
    const res = await loadWarehouseListApi()
    if (res.code !== 200) return
    warehouseList.value = res.data || []
  } catch (e) {
    console.error(e)
  }
}
const loadEmployeeList = async () => {
  try {
    const res = await getEmployeeListApi()
    if (res.code !== 200) return
    stockKeeperList.value = res.data || []
  } catch (e) {
    console.error(e)
  }
}
const loadSupplierList = async () => {
  try {
    const res = await getSupplierListApi()
    if (res.code !== 200) return
    supplierList.value = res.data || []
  } catch (e) {
    console.error(e)
  }
}
const loadCurrencyList = async () => {
  try {
    const res = await getBaseCurrencyInfoApi()
    if (res.code !== 200) return
    currencyList.value = res.data || []
  } catch (e) {
    console.error(e)
  }
}
const loadTreeData = async () => {
  try {
    const res = await getStockingOrderStatusTreeApi()
    if (res.code !== 200) return
    treeData.value = [{ code: '-1', name: '全部', children: res.data }]
    await nextTick(() => {
      treeRef.value!.setCurrentKey(status.value, true)
    })
  } catch (e) {
    console.error(e)
  }
}
const nodeClick = (data: TreeData) => {
  status.value = data.code
  search()
}
const getDeliveryStatusName = (shippingStatus: number) => {
  if (!shippingStatus) return ''
  return deliveryStatusList.value.find(
    (item) => item.value === shippingStatus.toString(),
  )?.label
}

const {
  currentPage,
  pageSize,
  total,
  data: tableData,
  refresh: search,
  onCurrentPageChange: handleCurrentChange,
  onPageSizeChange: handleSizeChange,
} = usePageList<TableData>({
  query: (page, pageSize) =>
    getStockingOrderListApi(
      {
        ...searchForm.value,
        startDate: rangeTime.value?.[0],
        endDate: rangeTime.value?.[1],
        status: status.value === '-1' ? undefined : status.value,
      },
      page,
      pageSize,
    ).then(async (res) => {
      const { records } = res.data
      await nextTick(() => {
        tableRef.value.setCurrentRow(records[0])
        selectedRow.value = (records as never)[0]
      })
      return res.data
    }),
  initLoad: true,
})
const handleSelectionChange = (val: TableData[]) => {
  selection.value = val
}
const handleRowClick = (row: TableData) => {
  if (row) {
    selectedRow.value = row
  } else {
    selectedRow.value = null
  }
}

const handleOrder = (row: TableData, type: string) => {
  addStockingOrderDialogRef.value.open(row, type)
}
const handleSupplierDispatchOrder = (row: TableData) => {
  supplierDispatchOrderDialogRef.value.open(row)
}
const stockingComplete = async (row: TableData) => {
  try {
    await ElMessageBox.confirm(
      '备货完成将把未完成入库申请单自动取消，是否继续对选中的订单操作备货完成？',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
  } catch {
    return
  }
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await stockingCompleteApi(row.id)
    if (res.code !== 200) return
    ElMessage.success('备货完成成功')
    search()
    loadTreeData()
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleAddOrder = () => {
  addStockingOrderDialogRef.value.open(null, 'add')
}

const handleSubmitAudit = async () => {
  if (selection.value.length === 0) {
    return ElMessage.warning('请选择要操作的数据')
  }
  try {
    await ElMessageBox.confirm('确定将选中的订单提交至审核？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }
  try {
    const res = await submitStockingOrderAuditApi(
      selection.value.map((el) => el.id).join(','),
    )
    if (res.code !== 200) return
    ElMessage.success('提交审核成功')
    search()
    loadTreeData()
  } catch (e) {
    console.error(e)
  }
}
const handleDeleteOrder = async () => {
  if (selection.value.length === 0) {
    return ElMessage.warning('请选择一条数据')
  }
  if (selection.value.length !== 1) {
    return ElMessage.warning('不支持批量删除！')
  }
  try {
    await ElMessageBox.confirm('确定删除选中的订单?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }
  try {
    const res = await deleteStockingOrderApi(selection.value[0].id)
    if (res.code !== 200) return
    ElMessage.success('删除成功')
    onRefresh()
  } catch (e) {
    console.error(e)
  }
}
const handleCancelOrder = async () => {
  if (selection.value.length === 0) {
    return ElMessage.warning('请选择一条数据')
  }
  if (selection.value.length !== 1) {
    return ElMessage.warning('不支持批量取消！')
  }
  ElMessageBox.prompt('', '取消原因', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    inputType: 'textarea',
    inputPlaceholder: '请输入取消原因',
    inputPattern: /.+/,
    inputErrorMessage: '取消原因不能为空',
  }).then(async ({ value }: { value: string }) => {
    const loading = ElLoading.service({
      fullscreen: true,
      text: '操作中...',
      background: 'rgba(0, 0, 0, 0.3)',
    })
    try {
      const res = await cancelStockingOrderApi(selection.value[0].id, value)
      if (res.code !== 200) return
      ElMessage.success('取消成功')
      onRefresh()
    } catch (e) {
      console.error(e)
    } finally {
      loading.close()
    } 
  })
}
const addInternalTag = async () => {
  if (selection.value.length === 0) {
    return ElMessage({
      message: '请选择订单',
      type: 'warning',
      offset: window.innerHeight / 2,
    })
  }
  ElMessageBox.prompt('', '添加内部便签', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    inputType: 'textarea',
    inputPlaceholder: '请输入内部便签',
    inputPattern: /.+/,
    inputErrorMessage: '内部便签不能为空',
  }).then(async ({ value }: { value: string }) => {
    try {
      const res = await addStockingOrderInternalTagApi(
        value,
        selection.value.map((item) => item.id),
      )
      ElMessage.success(res.message)
      search()
    } catch (e) {
      // showError(e)
    }
  })
}
const onRefresh = () => {
  search()
  loadTreeData()
}

onMounted(() => {
  loadWarehouseList()
  loadEmployeeList()
  loadSupplierList()
  loadTreeData()
  loadCurrencyList()
})
</script>
<style lang="scss" scoped>
.order-status {
  width: 160px;
  :deep(.el-tree-node__content) {
    height: 30px;
    line-height: 30px;
  }
  :deep(.el-tree-node__label) {
    font-size: 13px;
    cursor: pointer;
    display: inline-block;
    width: 100%;
    color: black !important;

    padding: 3px 7px;
  }

  :deep(.el-tree-node__expand-icon) {
    display: none;
  }

  :deep(.is-current) {
    .tree-node-label,
    .tree-node-count {
      background-color: #ecf5ff;
      color: #409eff !important;
    }

    .el-tree-node__children {
      .tree-node-label,
      .tree-node-count {
        background-color: transparent !important;
        color: black !important;
      }
    }
  }
  :deep(.el-tree-node__label) {
    font-size: 13px;
    color: rgb(96, 98, 102);
    cursor: pointer;
  }

  :deep(.el-tree-node__expand-icon) {
    display: none;
  }

  :deep(.el-tree-node__label) {
    display: inline-block;
    width: 100%;
    color: black !important;

    padding: 3px 7px;
  }

  :deep(.is-current) {
    .el-tree-node__label {
      background-color: #ecf5ff;
      color: #409eff !important;
    }

    .el-tree-node__children {
      .el-tree-node__label {
        background-color: transparent !important;
        color: black !important;
      }
    }
  }
}
.tree-node {
  display: flex;
  color: #333;
  font-weight: 500;
}
.table-content {
  flex: 1;
  margin-top: 10px;
  overflow: hidden;
  :deep(#top) {
    height: 100%;
  }
}

.search-form {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  align-items: flex-start;
  :deep(.el-form-item) {
    margin-right: 10px;
    margin-bottom: 10px;
  }
}
</style>
