<template>
  <div
    class="production-dashboard"
    :style="{ width: `${style.width}px`, height: `${style.height}px`, transform: style.transform }"
  >
    <div class="dashboard-shell">
      <header class="dashboard-header">
        <div class="brand">
          <img class="brand-logo" :src="clientLogoUrl" alt="RENLY" />
        </div>
        <h1>生产任务综合看板</h1>
        <div class="current-time">{{ currentTime }}</div>
      </header>

      <main class="dashboard-content">
        <section class="summary-grid first-row">
          <article class="panel kpi-card rate-card">
            <div class="ring-wrap">
              <div class="progress-ring">{{complete.completeset}}%</div>
            </div>
            <div class="rate-info">
              <div class="card-title">按期齐套率</div>
              <div class="mini-row"><span>未齐套数</span><b>{{ complete.untasknum }}</b></div>
              <div class="mini-row"><span>应齐套数</span><b>{{ complete.tasknum }}</b></div>
            </div>
          </article>

          <article v-for="item in topStats" :key="item.title" class="panel kpi-card top-stat-card">
            <div class="icon-slot">
              <img :src="item.icon" :alt="item.title" />
            </div>
            <div class="stat-info">
              <div class="card-title">{{ item.title }}</div>
              <div class="stat-number">{{ item.value }}</div>
            </div>
          </article>
        </section>

        <section class="summary-grid second-row">
          <article class="panel status-card split-number-card">
            <div class="icon-slot wide">
              <img :src="svgIcons.purchaseDelay" alt="采购未及时到货" />
            </div>
            <div class="status-info">
              <div class="card-title">采购未及时到货</div>
              <div class="split-number"><em>8</em><span>/46</span></div>
            </div>
          </article>

          <article class="panel status-card">
            <div class="icon-slot gear">
              <img :src="svgIcons.machineDelay" alt="机加工未及时开工" />
            </div>
            <div class="status-info">
              <div class="card-title">机加未及时开工</div>
              <div class="orange-number">{{ notintimenum }}</div>
            </div>
          </article>

          <article class="panel status-card rate-small-card">
            <div class="small-ring">87.5%</div>
            <div class="status-info">
              <div class="card-title">质检及时率</div>
              <div class="mini-row"><span>已检数</span><b>84</b></div>
              <div class="mini-row"><span>未检数</span><b>12</b></div>
              <div class="mini-row"><span>全部待检数</span><b>96</b></div>
            </div>
          </article>

          <article class="panel status-card">
            <div class="icon-slot house">
              <img :src="svgIcons.stockDelay" alt="未及时入库" />
            </div>
            <div class="status-info">
              <div class="card-title">未及时入库</div>
              <div class="orange-number">11</div>
            </div>
          </article>

          <article class="panel status-card urgent-status-card">
            <div class="icon-slot alarm">
              <img :src="svgIcons.urgent" alt="加急件" />
            </div>
            <div class="status-info">
              <div class="card-title">加急件</div>
              <div class="red-number">{{ Urgentnum }}</div>
            </div>
          </article>
        </section>

        <section class="table-area">
          <article class="panel table-panel">
            <div class="panel-caption">未按期齐套任务</div>
            <div class="table-wrap">
              <table>
                <thead>
                  <tr>
                    <th v-for="column in leftColumns" :key="column.key">{{ column.label }}</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(row, index) in kitRows" :key="`${row.salesOrder}-${index}`">
                    <td v-for="column in leftColumns" :key="column.key">{{ row[column.key] }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </article>

          <article class="panel table-panel">
            <div class="panel-caption">加急件</div>
            <div class="table-wrap">
              <table>
                <thead>
                  <tr>
                    <th v-for="column in urgentColumns" :key="column.key">{{ column.label }}</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="(row, index) in urgentRows" :key="`${row.salesOrder}-${index}`">
                    <td v-for="column in urgentColumns" :key="column.key">{{ row[column.key] }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </article>
        </section>
      </main>
    </div>
  </div>
</template>

<script setup>
import { computed, inject, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
const CreateData = inject('CreateData')
const ExecDatabase = inject('ExecDatabase')
const tableData = ref([])
const now = ref(new Date('2026-05-06 10:10:10'))
let timer = null
let resizeHandler = null
let Urgentnum = null
let notintimenum = null
let complete = reactive({
  completeset:100,
  tasknum:0,
  untasknum:0
})
const style = reactive({
  width: 1920,
  height: 1080,
  transform: 'scaleY(1) scaleX(1) translate(-50%, -50%)'
})
const setScale = () => {
  const scale = getScale()
  style.transform = 'scaleY(' + scale.y + ') scaleX(' + scale.x + ') translate(-50%, -50%)'
}
const getScale = () => {
  const w = window.innerWidth / style.width
  const h = window.innerHeight / style.height
  return { x: w, y: h }
}
const pad = (value) => String(value).padStart(2, '0')

const currentTime = computed(() => {
  const date = now.value
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
})

const clientLogoUrl = './public/ClientLogo.png'
const svgIcons = {
  pendingSchedule: './public/svg/待排产任务.svg',
  salesOrder: './public/svg/待处理销售订单.svg',
  bom: './public/svg/工艺BOM待完成.svg',
  purchaseDelay: './public/svg/采购未及时到货.svg',
  machineDelay: './public/svg/机加未及时开工.svg',
  stockDelay: './public/svg/未及时入库.svg',
  urgent: './public/svg/加急件.svg',
}

onMounted(() => {
  startClock()
  setScale()
  resizeHandler = () => {
    setScale()
  }
  window.addEventListener('resize', resizeHandler)
  searchDashboardData()
})

onUnmounted(() => {
  destroyDashboard()
})

const searchDashboardData = () => {
  searchCompleteSetData()
  searchNoProcessData()
  searchUrgentData()
  searchUnCompleteData()
  searchNotInTimeData()

}
const searchCompleteSetData = () => {
  queryDashboardData('生产任务综合看板_按期齐套率', applyCompleteSetData)
}
const searchNoProcessData = () => {
  queryDashboardData('生产任务综合看板_未排产无工艺查询', applyNoProcessData)
}
const searchUrgentData = () => {
  queryDashboardData('生产任务综合看板_加急任务查询', applyUrgentData)
}
const searchNotInTimeData = () => {
  queryDashboardData('生产任务综合看板_未及时开工查询', applyNotInTimeData)
}
const searchUnCompleteData = () => {
  queryDashboardData('生产任务综合看板_未按期齐套任务', applyUnCompleteData)
}
const applyCompleteSetData = rows => {
  complete.completeset = rows[0].齐套率
  complete.untasknum = rows[0].未齐套任务数
  complete.tasknum = rows[0].总任务数
}
const applyNoProcessData = rows => {
  topStats[0].value = rows[0].未排产任务数
  topStats[2].value = rows[0].无生产工艺计划数
}
const applyNotInTimeData = rows => {
  notintimenum = rows[0].未及时开工总数
}
const applyUrgentData = rows => {
    urgentRows = rows.map( item => ({
      salesOrder: item.合同号,
      productionOrder: item.订单编号,
      productName: item.物料描述,
      productCode: item.物料编号,
      property: item.自制件属性,
      planQty: item.计划数量,
      releaseDate: item.下达日期,
      startDate: item.计划开始,
      finishDate: item.计划完成,
    }))
    Urgentnum = rows[0].加急订单总数
}
const applyUnCompleteData = rows => {
    kitRows = rows.map( item => ({
      productionOrder: item.订单编号,
      productName: item.物料描述,
      productCode: item.物料编号,
      property: item.自制件属性,
      planQty: item.计划数量,
      releaseDate: item.下达日期,
      startDate: item.计划开始,
      finishDate: item.计划完成,
      planNo: item.合同号,
      stockQty: '0',
      kitDate: item.计划开始,
      pickStatus: item.拣配状态 == 1 ?'已拣配':'未拣配',
      issueStatus: item.发料状态 == 2 ?'发料缺件':'未发料',
    }))
}
const queryDashboardData = (procedureName, applyData) => {
  let data
  data = CreateData('11', procedureName, [])
  ExecDatabase(data).then(response => {
    const rows = getResponseRows(response)
    tableData.value = rows
    applyData(rows)
  })
}
const getResponseRows = response => {
  if (response && Array.isArray(response.data)) {
    return response.data
  }
  if (response && response.data && Array.isArray(response.data.result)) {
    return response.data.result
  }
  return []
}

const startClock = () => {
  timer = window.setInterval(() => {
    now.value = new Date(now.value.getTime() + 1000)
  }, 1000)
}

const destroyDashboard = () => {
  if (timer) {
    window.clearInterval(timer)
    timer = null
  }
  if (resizeHandler) {
    window.removeEventListener('resize', resizeHandler)
    resizeHandler = null
  }
}

const topStats = [
  { title: '待排产任务', value: 18, icon: svgIcons.pendingSchedule },
  { title: '待处理销售订单', value: 12, icon: svgIcons.salesOrder },
  { title: '工艺BOM待完成', value: 9, icon: svgIcons.bom },
]

const leftColumns = [
  { label: '销售订单', key: 'salesOrder' },
  { label: '计划号', key: 'planNo' },
  { label: '生产订单', key: 'productionOrder' },
  { label: '产品名称', key: 'productName' },
  { label: '产品编码', key: 'productCode' },
  { label: '计划数', key: 'planQty' },
  { label: '入库数', key: 'stockQty' },
  { label: '预计齐套', key: 'kitDate' },
  { label: '拣配状态', key: 'pickStatus' },
  { label: '发料状态', key: 'issueStatus' },
]

const urgentColumns = [
  { label: '销售订单', key: 'salesOrder' },
  { label: '生产订单', key: 'productionOrder' },
  { label: '产品名称', key: 'productName' },
  { label: '产品编码', key: 'productCode' },
  { label: '属性', key: 'property' },
  { label: '计划数', key: 'planQty' },
  { label: '下达日期', key: 'releaseDate' },
  { label: '计划开始', key: 'startDate' },
  { label: '计划完成', key: 'finishDate' },
]

let kitRows = Array.from({ length: 9 }, () => ({
  salesOrder: 'SH260014',
  planNo: '54023',
  productionOrder: '1075',
  productName: '垫铁+行程开关部装',
  productCode: '213-YGLQ-DF150V1.2.18',
  planQty: '1',
  stockQty: '0',
  kitDate: '2026-01-21',
  pickStatus: '已拣配',
  issueStatus: '未发料',
}))

let urgentRows = Array.from({ length: 10 }, () => ({
  salesOrder: 'SH260014',
  productionOrder: '1075',
  productName: '垫铁+行程开关部装',
  productCode: '213-YGLQ-DF150V1.2.18',
  property: '机加',
  planQty: '1',
  releaseDate: '2026-01-21',
  startDate: '2026-01-21',
  finishDate: '2026-01-21',
}))
</script>

<style scoped lang="scss">
* {
  box-sizing: border-box;
}

.production-dashboard {
  position: fixed;
  left: 50%;
  top: 50%;
  width: 1920px;
  height: 1080px;
  transform-origin: 0 0;
  transition: 0.3s;
  overflow: hidden;
  color: #f3f9ff;
  font-family: 'Microsoft YaHei', Arial, sans-serif;
  background-color: #07001f;
}

.dashboard-shell {
  width: 100%;
  height: 100%;
  padding: 0px 15px 15px 15px;
}

.dashboard-header {
  position: relative;
  display: grid;
  grid-template-columns: 336px 1fr 442px;
  align-items: center;
  height: 84px;
  border-bottom: 1px solid rgba(21, 162, 240, 0.62);
}

.logo-slot {
  width: 230px;
  height: 45px;
  margin-left: 8px;
  border: 1px solid rgba(100, 196, 255, 0.48);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 14px rgba(83, 181, 255, 0.25);
}

.dashboard-header h1 {
  margin: 0;
  text-align: center;
  font-size: 55px;
  font-weight: 900;
  letter-spacing: 0.08em;
}

.current-time {
  padding-right: 38px;
  text-align: right;
  font-size: 22px;
  color: #eef7ff;
}

.dashboard-content {
  display: grid;
  grid-template-rows: 145px 145px 1fr;
  gap: 17px;
  height: calc(100% - 84px);
  padding-top: 12px;
}

.summary-grid {
  display: grid;
  gap: 17px;
}

.first-row {
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

.second-row {
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}

.panel {
  position: relative;
  border: 1px solid rgba(29, 153, 229, 0.78);
  box-shadow:
    inset 0 0 18px rgba(27, 130, 214, 0.24),
    0 0 10px rgba(1, 132, 220, 0.18);
}

.panel::before {
  position: absolute;
  inset: -1px;
  content: '';
  pointer-events: none;
  background:
    linear-gradient(90deg, #2bd8ff 0 14px, transparent 14px) left top / 14px 2px no-repeat,
    linear-gradient(180deg, #2bd8ff 0 14px, transparent 14px) left top / 2px 14px no-repeat,
    linear-gradient(270deg, #2bd8ff 0 14px, transparent 14px) right top / 14px 2px no-repeat,
    linear-gradient(180deg, #2bd8ff 0 14px, transparent 14px) right top / 2px 14px no-repeat,
    linear-gradient(90deg, #2bd8ff 0 14px, transparent 14px) left bottom / 14px 2px no-repeat,
    linear-gradient(0deg, #2bd8ff 0 14px, transparent 14px) left bottom / 2px 14px no-repeat,
    linear-gradient(270deg, #2bd8ff 0 14px, transparent 14px) right bottom / 14px 2px no-repeat,
    linear-gradient(0deg, #2bd8ff 0 14px, transparent 14px) right bottom / 2px 14px no-repeat;
}

.panel::after {
  position: absolute;
  inset: 0;
  content: '';
  pointer-events: none;
  box-shadow: inset 0 0 12px rgba(43, 216, 255, 0.12);
}

.kpi-card,
.status-card {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 70px;
  min-width: 0;
}

.card-title,
.panel-caption {
  color: #8cd3ff;
  font-size: 20px;
  font-weight: 600;
  text-align: center;
  letter-spacing: 0.03em;
}

.rate-card {
  justify-content: flex-start;
  padding-left: 42px;
  box-sizing: border-box;
}

.ring-wrap,
.progress-ring,
.small-ring {
  display: flex;
  align-items: center;
  justify-content: center;
}

.progress-ring {
  width: 110px;
  height: 110px;
  min-width: 58px;
  min-height: 58px;
  border-radius: 50%;
  font-size: 22px;
  font-weight: 900;
  background:
    radial-gradient(circle, #08234f 53%, transparent 55%),
    conic-gradient(#1ce6ff 0deg 333deg, rgba(47, 84, 131, 0.8) 333deg 360deg);
  box-shadow: 0 0 15px rgba(0, 208, 255, 0.65);
}

.rate-info {
  width: 154px;
}

.mini-row {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  color: #e7f6ff;
  font-size: 15px;
  line-height: 1;
}

.mini-row b {
  color: #ffffff;
}

.icon-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 110px;
  height: 110px;
  min-width: 60px;
  min-height: 60px;
}

.icon-slot img {
  width: 76%;
  height: 76%;
  object-fit: contain;
  display: block;
}

.icon-slot.wide {
  width: 108px;
}

.icon-slot.gear,
.icon-slot.house,
.icon-slot.alarm {
  border-radius: 50%;
}



.stat-info,
.status-info {
  min-width: 0;
  text-align: center;
}

.stat-number {
  margin-top: 5px;
  font-size: 58px;
  line-height: 1;
  font-weight: 900;
  color: #ffffff;
  text-shadow: 0 0 8px rgba(255, 255, 255, 0.36);
}

.split-number,
.orange-number,
.red-number {
  margin-top: 2px;
  font-size: 52px;
  line-height: 1;
  font-weight: 900;
}

.split-number em {
  color: #ff2026;
  font-style: normal;
}

.split-number span {
  color: #ffffff;
}

.orange-number {
  color: #ff9e14;
}

.red-number {
  color: #ff242a;
}

.small-ring {
  width: 110px;
  height: 110px;
  min-width: 56px;
  min-height: 56px;
  border-radius: 50%;
  font-size: 17px;
  font-weight: 900;
  background:
    radial-gradient(circle, #08234f 52%, transparent 54%),
    conic-gradient(#19d4ff 0deg 315deg, rgba(47, 84, 131, 0.85) 315deg 360deg);
  box-shadow: 0 0 13px rgba(0, 208, 255, 0.54);
}

.table-area {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 17px;
  min-height: 0;
}

.table-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.panel-caption {
  height: 38px;
  line-height: 38px;
}

.table-wrap {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 0 9px 10px;
}

table {
  width: 100%;
  height: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

th,
td {
  border: 1px solid rgba(53, 149, 217, 0.48);
  text-align: center;
  vertical-align: middle;
  color: #f1f8ff;
  font-size: 12px;
  line-height: 1.18;
  word-break: break-all;
}

th {
  height: 38px;
  font-size: 14px;
  font-weight: 200;
  background: rgba(12, 68, 119, 0.28);
}

td {
  height: 50px;
}

.brand {
  width: 300px;
  height: 72px;
  display: flex;
  align-items: center;
  overflow: visible;
  position: relative;
  z-index: 2;
}

.brand-logo {
  width: 224px;
  height: 58px;
  padding: 5px 10px;
  background: #ffffff;
  border-radius: 6px;
  object-fit: contain;
  object-position: left center;
  filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.28));
}
</style>
