<template>
  <div class="workbench admin-page-card">
    <!-- 时间筛选 -->
    <div class="filter-bar">
      <div class="period-bar">
        <div class="period-tabs">
          <el-button v-for="t in periodTabs" :key="t.value"
            :class="['period-tab', { active: period === t.value && !isCustom }]" plain @click="onPickPeriod(t.value)">
            {{ t.label }}
          </el-button>
          <el-button :class="['period-tab', { active: isCustom }]" plain @click="onPickCustom">{{
            $t('common.customDate')
          }}</el-button>
        </div>
        <div v-if="isCustom" class="custom-range">
          <el-date-picker v-model="dateRange" type="daterange" range-separator="-"
            :start-placeholder="$t('common.startDate')" :end-placeholder="$t('common.endDate')"
            value-format="YYYY-MM-DD" style="width: 240px" />
          <el-button type="primary" class="search-btn" plain @click="onSearch">查询</el-button>
        </div>
      </div>
    </div>

    <!-- 统计卡片 -->
    <div class="stat-cards">
      <div class="stat-card" v-for="card in cards" :key="card.key" @click="goToOrders(card)">
        <div class="stat-icon">
          <img :src="card.icon" alt="" />
        </div>
        <div class="right">
          <div class="stat-value">{{ card.value }}</div>
          <div class="stat-label">{{ card.label }}</div>
        </div>
      </div>
    </div>

    <!-- 趋势图 -->
    <div class="trend-card">
      <div class="card-header">
        <span class="border-title">{{ $t('chart.title') }}</span>
        <div class="chart-switch" :class="{ 'is-line': chartType === 'line' }">
          <span class="switch-item" :class="{ active: chartType === 'bar' }" @click="chartType = 'bar'">
            {{ $t('chart.bar') }}
          </span>
          <span class="switch-item" :class="{ active: chartType === 'line' }" @click="chartType = 'line'">
            {{ $t('chart.line') }}
          </span>
        </div>
      </div>
      <v-chart ref="chartRef" class="chart" :option="chartOption" autoresize />
      <div class="chart-legend">
        <div class="legend-item">
          <span class="legend-dot legend-dot--submit" />
          <span class="legend-text">{{ $t('chart.submit') }}</span>
        </div>
        <div class="legend-item">
          <span class="legend-dot legend-dot--complete" />
          <span class="legend-text">{{ $t('chart.complete') }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import dayjs from "dayjs";
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { dateRangeShortcuts } from "@/utils/dateShortcuts";
import { useRouter } from "vue-router";
import iconAll from "@/assets/image/admin/orders/all.svg";
import iconPending from "@/assets/image/admin/orders/pending.svg";
import iconComplete from "@/assets/image/admin/orders/complete.svg";
import iconHigh from "@/assets/image/admin/orders/high.svg";
import VChart from "vue-echarts";
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { LineChart, BarChart } from "echarts/charts";
import {
  GridComponent,
  TooltipComponent,
  LegendComponent,
  TitleComponent,
  DataZoomComponent,
} from "echarts/components";
import { useI18n } from "vue-i18n";
import { getWorkbench } from "@/service/modular/hospital";

use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent, LegendComponent, TitleComponent, DataZoomComponent]);

const { t: $t } = useI18n();

// 时间筛选 tab（不包含"本周"，自定义点查询才触发）
const periodTabs = [
  { label: $t('common.thisMonth'), value: "month" },
  { label: $t('common.thisQuarter'), value: "quarter" },
  { label: $t('common.thisYear'), value: "year" },
];

const period = ref("month");
const isCustom = ref(false);
const dateRange = ref([]);
const chartType = ref("line");

const onPickPeriod = (val) => {
  isCustom.value = false;
  dateRange.value = [];
  period.value = val;
  loadStats();
};

const onPickCustom = () => {
  isCustom.value = true;
};

const onSearch = () => {
  loadStats();
};

const stats = ref({
  totalOrders: 0,
  completedOrders: 0,
  pendingOrders: 0,
  highPriorityOrders: 0,
  trendData: [],
});

const router = useRouter();

const chartRef = ref(null);
const overlaySize = ref({ w: 0, h: 0 });
const stripeTargets = ref([]);

// 顺序、文案与 src/views/admin/orders/list.vue 的 .order-stats 保持一致
const cards = computed(() => [
  { key: "total", label: $t('stat.totalOrders'), value: stats.value.totalOrders, icon: iconAll },
  { key: "pending", label: $t('stat.pendingOrders'), value: stats.value.pendingOrders, icon: iconPending },
  { key: "completed", label: $t('stat.completedOrders'), value: stats.value.completedOrders, icon: iconComplete },
  { key: "highPriority", label: $t('stat.highPriorityOrders'), value: stats.value.highPriorityOrders, icon: iconHigh },
]);

const allStripeLines = computed(() => {
  const result = [];
  stripeTargets.value.forEach((t) => {
    buildStripeLines(t).forEach((ln) => result.push(ln));
  });
  return result;
});

const resolveDateRange = () => {
  if (period.value === "custom" && dateRange.value?.length === 2) {
    return { startDate: dateRange.value[0], endDate: dateRange.value[1] };
  }
  const now = dayjs();
  if (period.value === "month") return { startDate: now.startOf("month").format("YYYY-MM-DD"), endDate: now.endOf("month").format("YYYY-MM-DD") };
  if (period.value === "quarter") return { startDate: now.startOf("quarter").format("YYYY-MM-DD"), endDate: now.endOf("quarter").format("YYYY-MM-DD") };
  if (period.value === "year") return { startDate: now.startOf("year").format("YYYY-MM-DD"), endDate: now.endOf("year").format("YYYY-MM-DD") };
  return {};
};

const goToOrders = (card) => {
  const query = { ...resolveDateRange() };
  if (card.key === "completed") query.status = "已完成";
  else if (card.key === "pending") query.status = "待处理";
  else if (card.key === "highPriority") query.priority = "高";
  router.push({ path: "/hospital/orders", query });
};

// ==================== ECharts 配置 ====================
const BAR_W = 59;
const CORNER_R = 8;
const WRAP_THICK = 8;
const WRAP_BORDER = "#EFF2FE";

const buildLinearGradient = (top, bottom) => ({
  type: "linear",
  x: 0, y: 0, x2: 0, y2: 1,
  colorStops: [
    { offset: 0, color: top },
    { offset: 1, color: bottom },
  ],
});

const chartOption = computed(() => {
  const data = stats.value.trendData || [];
  const dates = data.map((d) => d.date);
  const submit = data.map((d) => d.submitCount);
  const complete = data.map((d) => d.completeCount);
  const isLine = chartType.value === "line";
  const isBar = chartType.value === "bar";
  // > 7 组才显示滚动条；用 startValue/endValue 锁定最后 7 组，避免百分比误差
  const showSlider = dates.length > 7;
  const sliderStartValue = showSlider ? dates[dates.length - 7] : undefined;
  const sliderEndValue = showSlider ? dates[dates.length - 1] : undefined;

  const maxValue = Math.max(0, ...submit, ...complete);
  const yMax = maxValue > 0 ? Math.ceil(maxValue / 2) * 2 : 4;

  const submitTopColor = "#3289FB";
  const completeTopColor = "#34C759";
  const submitWrapColor = "#B4CAE6";
  const completeWrapColor = "#B0D2B9";

  const lineSeries = [
    {
      name: $t('chart.submit'),
      type: "line",
      smooth: true,
      symbol: "circle",
      symbolSize: 8,
      data: submit,
      lineStyle: { color: submitTopColor, width: 2 },
      itemStyle: { color: submitTopColor },
      areaStyle: { color: "rgba(50,137,251,0.08)" },
      label: {
        show: true,
        position: "top",
        distance: 8,
        color: submitTopColor,
        fontWeight: 400,
        fontSize: 14,
        formatter: (p) => p.value,
      },
    },
    {
      name: $t('chart.complete'),
      type: "line",
      smooth: true,
      symbol: "circle",
      symbolSize: 8,
      data: complete,
      lineStyle: { color: completeTopColor, width: 2 },
      itemStyle: { color: completeTopColor },
      areaStyle: { color: "rgba(52,199,89,0.08)" },
      label: {
        show: true,
        position: "top",
        distance: 8,
        color: completeTopColor,
        fontWeight: 400,
        fontSize: 14,
        formatter: (p) => p.value,
      },
    },
  ];

  const makeBarSeries = (dataArr, topColor, bottomColor) => ({
    type: chartType.value,
    barWidth: BAR_W,
    barGap: isBar ? "0%" : "20%",
    data: dataArr,
    label: isBar ? {
      show: true,
      position: "top",
      distance: 4,
      color: topColor,
      fontWeight: 400,
      fontSize: 14,
      formatter: (p) => p.value,
    } : { show: false },
    itemStyle: isBar ? {
      borderRadius: CORNER_R,
      borderColor: WRAP_BORDER,
      borderWidth: WRAP_THICK,
      color: buildLinearGradient(topColor, bottomColor),
    } : { color: topColor, borderRadius: 0 },
    showBackground: false,
  });

  return {
    grid: { left: 30, right: 30, top: 50, bottom: showSlider ? 60 : 30 },
    tooltip: { trigger: "axis" },
    xAxis: {
      type: "category",
      data: dates,
      // 折线/柱状图统一带 boundaryGap，让首末坐标点/柱距边留出与柱状图一致的间距
      boundaryGap: true,
      ...(isBar ? { barCategoryGap: "7%" } : {}),
      axisLine: { lineStyle: { color: "#e4e7ed" } },
    },
    yAxis: {
      type: "value",
      min: 0,
      max: yMax,
      interval: 2,
      axisLine: { show: false },
      splitLine: { lineStyle: { color: "#f0f2f5" } },
    },
    dataZoom: showSlider
      ? [
          {
            type: "slider",
            xAxisIndex: 0,
            bottom: 0,
            height: 14,
            startValue: sliderStartValue,
            endValue: sliderEndValue,
            zoomLock: true,
            showDetail: false,
            showDataShadow: false,
            fillerColor: "rgba(50,137,251,0.12)",
            borderColor: "transparent",
            backgroundColor: "#F2F3F5",
          },
        ]
      : [],
    series: isLine ? lineSeries : [
      { ...makeBarSeries(submit, submitTopColor, submitWrapColor), name: $t('chart.submit') },
      { ...makeBarSeries(complete, completeTopColor, completeWrapColor), name: $t('chart.complete') },
    ],
  };
});

// ==================== 计算斜线位置 ====================
const computeStripeTargets = () => {
  if (chartType.value !== "bar") {
    stripeTargets.value = [];
    return;
  }
  const inst = chartRef.value?.getInstance ? chartRef.value.getInstance() : chartRef.value?.chart;
  if (!inst) return;
  const data = stats.value.trendData || [];
  if (!data.length) return;
  const dom = inst.getDom();
  const rect = dom.getBoundingClientRect();
  overlaySize.value = { w: rect.width, h: rect.height };

  const targets = [];
  [0, 1].forEach((sIdx) => {
    data.forEach((d, i) => {
      const v = sIdx === 0 ? d.submitCount : d.completeCount;
      if (!v || v <= 0) return;
      const top = inst.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0, seriesIndex: sIdx }, [i, v]);
      const base = inst.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0, seriesIndex: sIdx }, [i, 0]);
      if (!top || !base) return;
      const x = top[0] - BAR_W / 2;
      const y = top[1];
      const h = base[1] - top[1];
      targets.push({ x, y, w: BAR_W, h: Math.max(h, 1), r: CORNER_R });
    });
  });
  stripeTargets.value = targets;
};

// 在目标矩形内生成 45° 斜线列表（端点坐标物理上不会溢出）
const buildStripeLines = (t) => {
  const lines = [];
  const gap = 4;
  const x0 = t.x + WRAP_THICK;
  const y0 = t.y + WRAP_THICK;
  const w = t.w - WRAP_THICK * 2;
  const h = t.h - WRAP_THICK * 2;
  if (w <= 0 || h <= 0) return lines;
  // 45° 斜线 y = -x + c，c 范围是 [x0+y0+h, x0+w+y0]
  // 步长 gap*sqrt(2) 保证视觉间距 = gap
  const stepC = gap * Math.SQRT2;
  for (let c = x0 + y0 + h; c <= x0 + w + y0 + 0.001; c += stepC) {
    // 端点：左边 x=x0 → y = -x0 + c；右边 x=x0+w → y = -(x0+w) + c
    lines.push({
      x1: x0,
      y1: c - x0,
      x2: x0 + w,
      y2: c - x0 - w,
    });
  }
  return lines;
};

watch([() => stats.value.trendData, chartType], () => {
  nextTick(() => setTimeout(computeStripeTargets, 50));
}, { deep: true });

const onResize = () => setTimeout(computeStripeTargets, 50);
window.addEventListener("resize", onResize);
onBeforeUnmount(() => window.removeEventListener("resize", onResize));

const loadStats = async () => {
  // 自定义模式以 isCustom 为准（自定义需点查询才进这里，与 score.vue 一致）
  const params = {};
  if (isCustom.value && dateRange.value?.length === 2) {
    params.start = dateRange.value[0];
    params.end = dateRange.value[1];
  } else if (!isCustom.value) {
    params.period = period.value;
  }
  try {
    const data = await getWorkbench(params);
    if (data && Array.isArray(data.trendData) && data.trendData.length) {
      stats.value = data;
    } else {
    }
  } catch (_) {
  }
};

onMounted(loadStats);
</script>

<style scoped lang="scss">
.workbench {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

// 统计卡片：与 src/views/admin/orders/list.vue .order-stats 同款（workbench 无 active 态，省略相关样式）
.stat-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-top: 5px;
}

.stat-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 24px;
  background: #fff;
  border-radius: 16px 16px 16px 16px;
  border: 1px solid #e0e0e0;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    background 0.2s ease;
  cursor: pointer;
  user-select: none;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}

.stat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.stat-icon img {
  width: 48px;
  height: 48px;
  object-fit: contain;
}

// 右侧文字区（value + label 垂直堆叠，column-reverse 让 value 在 label 上方）
.stat-card .right {
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
  min-width: 0;
}

.stat-value {
  font-size: 26px;
  font-weight: 700;
  color: #333;
  line-height: 1.1;
}

.stat-label {
  font-size: 13px;
  color: #999;
  margin-top: 4px;
}

.trend-card {
  border-radius: 16px 16px 16px 16px;
  border: 1px solid #E0E0E0;
  padding: 21px 16px;
}

.trend-card .card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}


// 类 el-switch 分段控件：外层浅紫底，内项平分，激活态由 ::before 滑动白块承载（带过渡动画）
.trend-card .card-header .chart-switch {
  position: relative;
  display: inline-flex;
  width: 220px;
  height: 31px;
  padding: 4px;
  background: #F9FAFF;
  border-radius: 8px;
  overflow: hidden;
}

.trend-card .card-header .chart-switch::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: calc(50% - 4px);
  height: calc(100% - 8px);
  background: #FFFFFF;
  border-radius: 6px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 0;
}

.trend-card .card-header .chart-switch.is-line::before {
  transform: translateX(100%);
}

.trend-card .card-header .chart-switch .switch-item {
  flex: 1;
  height: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 400;
  color: #666666;
  cursor: pointer;
  user-select: none;
  position: relative;
  z-index: 1;
  transition: color 0.3s ease;
}

.trend-card .card-header .chart-switch .switch-item:hover {
  color: #3289FB;
}

.trend-card .card-header .chart-switch .switch-item.active {
  color: #3289FB;
}

.trend-card .chart-wrap {
  position: relative;
}

.trend-card .chart {
  height: 340px;
}

// 自定义图例：水平居中，色块 + 文字两部分，提交/完成配色与图表系列保持一致
.trend-card .chart-legend {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 30px;
  padding-top: 12px;
}

.trend-card .chart-legend .legend-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.trend-card .chart-legend .legend-dot {
  display: inline-block;
  width: 28px;
  height: 16px;
  border-radius: 4px;
}

.trend-card .chart-legend .legend-dot--submit {
  background: #3289FB;
}

.trend-card .chart-legend .legend-dot--complete {
  background: #34C759;
}

.trend-card .chart-legend .legend-text {
  font-size: 14px;
  font-weight: 400;
  color: #171F2A;
  line-height: 1;
}

.trend-card .stripe-overlay {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
</style>

<style lang="scss">
@use "@/assets/style/admin-common.scss" as *;

.workbench {
  .filter-bar {
    background: #fff;

    .period-bar {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 16px;

      .period-tabs {
        display: flex;
        gap: 10px;
      }

      .period-tab {
        background: #FFFFFF !important;
        border-radius: 8px 8px 8px 8px !important;
        border: 1px solid #E0E0E0 !important;
        font-weight: normal !important;
        font-size: 16px !important;
        color: #1D2129 !important;
        line-height: 22px !important;
        width: auto !important;
        height: auto !important;
        padding: 10px 24px !important;

        &:hover,
        &.active {
          background: #3289FB !important;
          border-color: #3289FB !important;
          color: #fff !important;
        }
      }

      .search-btn {
        font-size: 16px !important;
        line-height: 22px !important;
        width: auto !important;
        height: auto !important;
        padding: 10px 24px !important;

        &:hover,
        &.active {
          background: #3289FB !important;
          border-color: #3289FB !important;
          color: #fff !important;
        }
      }

      .custom-range {
        display: flex;
        align-items: center;
        gap: 10px;

        .el-date-editor {
          background: #FFFFFF !important;
          border-radius: 8px 8px 8px 8px !important;
          border: 1px solid #E0E0E0 !important;
          overflow: hidden;
          height: 44px !important;
        }
      }
    }
  }
}
</style>