<script setup lang="ts">
import { ref, computed, watch, shallowRef } from "vue";
import { useQuery } from "@tanstack/vue-query";
import { useI18n } from "vue-i18n";
import { useElementSize } from "@vueuse/core";
import { 
  TeamOutlined, 
  UserAddOutlined, 
  FileDoneOutlined, 
  CloseCircleOutlined,
  ReloadOutlined
} from "@ant-design/icons-vue";
import type { TableColumnsType } from "ant-design-vue";
import type { KolDashboardPackageStat, KolDashboardTrendPoint } from "@geo/shared-types";
import { kolDashboardApi } from "@/lib/api";

const { t } = useI18n();

// Filter for trend chart
const periodDays = ref(7);

// Queries
const overviewQuery = useQuery({
  queryKey: ["kol", "dashboard", "overview"],
  queryFn: () => kolDashboardApi.overview(),
});

const packagesQuery = useQuery({
  queryKey: ["kol", "dashboard", "packages"],
  queryFn: () => kolDashboardApi.packages(),
});

const trendQuery = useQuery({
  queryKey: ["kol", "dashboard", "trend", periodDays],
  queryFn: () => kolDashboardApi.trend(periodDays.value),
});

// Stats formatting
const stats = computed(() => {
  const data = overviewQuery.data.value;
  return [
    {
      title: t("kol.dashboard.totalSubs"),
      value: data?.total_subscriber_tenants ?? 0,
      icon: TeamOutlined,
      color: "#1890ff",
    },
    {
      title: t("kol.dashboard.monthSubs"),
      value: data?.month_new_subscriptions ?? 0,
      icon: UserAddOutlined,
      color: "#52c41a",
    },
    {
      title: t("kol.dashboard.totalUsage"),
      value: data?.total_usage ?? 0,
      icon: FileDoneOutlined,
      color: "#722ed1",
    },
    {
      title: t("kol.dashboard.failRate"),
      value: data ? `${(data.failure_rate * 100).toFixed(2)}%` : "0%",
      icon: CloseCircleOutlined,
      color: "#f5222d",
    },
  ];
});

// Table columns
const packageColumns: TableColumnsType<KolDashboardPackageStat> = [
  {
    title: t("common.name"),
    dataIndex: "package_name",
    key: "package_name",
  },
  {
    title: t("kol.dashboard.totalSubs"),
    dataIndex: "subscriber_tenants",
    key: "subscriber_tenants",
    align: "right",
  },
  {
    title: t("kol.dashboard.totalUsage"),
    dataIndex: "usage_count",
    key: "usage_count",
    align: "right",
  },
  {
    title: t("kol.dashboard.failRate"),
    dataIndex: "failure_rate",
    key: "failure_rate",
    align: "right",
  },
];

// SVG Chart logic
const chartWrapperRef = ref<HTMLElement | null>(null);
const { width: wrapperWidth, height: wrapperHeight } = useElementSize(chartWrapperRef, { width: 1000, height: 300 });

const chartPadding = { top: 20, right: 40, bottom: 40, left: 60 };

const chartViewBox = computed(() => {
  const w = Math.max(wrapperWidth.value, 1);
  const h = Math.max(wrapperHeight.value, 1);
  return `0 0 ${w} ${h}`;
});

const chartPoints = computed(() => {
  const points = trendQuery.data.value || [];
  if (points.length < 2) return [];

  const maxVal = Math.max(
    ...points.map(p => Math.max(p.subscriptions, p.usages)),
    1 // avoid division by zero
  ) * 1.1; // 10% headroom

  const w = Math.max(wrapperWidth.value, 1);
  const h = Math.max(wrapperHeight.value, 1);
  const cWidth = Math.max(w - chartPadding.left - chartPadding.right, 1);
  const cHeight = Math.max(h - chartPadding.top - chartPadding.bottom, 1);

  const getX = (index: number) => chartPadding.left + (index / (points.length - 1)) * cWidth;
  const getY = (val: number) => chartPadding.top + cHeight - (val / maxVal) * cHeight;

  return points.map((p, i) => {
    const x = getX(i);
    let hoverX = 0;
    let hoverWidth = 0;
    
    if (i === 0) {
      hoverX = chartPadding.left;
      hoverWidth = (getX(1) - x) / 2;
    } else if (i === points.length - 1) {
      const prevX = getX(i - 1);
      hoverX = prevX + (x - prevX) / 2;
      hoverWidth = (x - prevX) / 2;
    } else {
      const prevX = getX(i - 1);
      const nextX = getX(i + 1);
      hoverX = prevX + (x - prevX) / 2;
      hoverWidth = (x - prevX) / 2 + (nextX - x) / 2;
    }

    return {
      ...p,
      x,
      subY: getY(p.subscriptions),
      useY: getY(p.usages),
      hoverX,
      hoverWidth,
    };
  });
});

const chartPaths = computed(() => {
  const points = chartPoints.value;
  if (points.length < 2) return { subscriptions: "", usages: "" };

  let subPath = `M ${points[0].x} ${points[0].subY}`;
  let usagePath = `M ${points[0].x} ${points[0].useY}`;

  for (let i = 1; i < points.length; i++) {
    subPath += ` L ${points[i].x} ${points[i].subY}`;
    usagePath += ` L ${points[i].x} ${points[i].useY}`;
  }

  return { subscriptions: subPath, usages: usagePath };
});

const chartAxis = computed(() => {
  const points = chartPoints.value;
  if (points.length === 0) return [];
  
  // Show at most 7 date labels
  const step = Math.max(1, Math.floor(points.length / 6));
  const labels = [];
  for (let i = 0; i < points.length; i += step) {
    labels.push({
      x: points[i].x,
      label: points[i].date.split("-").slice(1).join("/"), // MM/DD
    });
    if (i + step >= points.length && i !== points.length - 1) {
       labels.push({
        x: points[points.length - 1].x,
        label: points[points.length - 1].date.split("-").slice(1).join("/"),
      });
    }
  }
  return labels;
});

const activePoint = ref<any>(null);

function showTooltip(point: any) {
  activePoint.value = point;
}

function hideTooltip() {
  activePoint.value = null;
}

function refresh() {
  void overviewQuery.refetch();
  void packagesQuery.refetch();
  void trendQuery.refetch();
}
</script>

<template>
  <div class="kol-dashboard-view">
    <div class="page-header">
      <div class="header-info">
        <h2 class="page-title">{{ t("kol.dashboard.title") }}</h2>
        <p class="page-desc">实时查看订阅情况与生成数据统计</p>
      </div>
      <a-button @click="refresh">
        <template #icon><ReloadOutlined /></template>
        刷新
      </a-button>
    </div>

    <!-- Stats Row -->
    <div class="stats-row">
      <template v-if="overviewQuery.isPending.value">
        <a-card v-for="i in 4" :key="i" class="stat-card shadow-sm">
          <a-skeleton active :paragraph="{ rows: 1 }" />
        </a-card>
      </template>
      <template v-else>
        <a-card v-for="stat in stats" :key="stat.title" class="stat-card shadow-sm">
          <div class="stat-content">
            <div class="stat-icon" :style="{ background: stat.color + '15', color: stat.color }">
              <component :is="stat.icon" />
            </div>
            <div class="stat-info">
              <span class="stat-label">{{ stat.title }}</span>
              <strong class="stat-value">{{ stat.value }}</strong>
            </div>
          </div>
        </a-card>
      </template>
    </div>

    <div class="dashboard-grid">
      <!-- Package Table -->
      <section class="panel panel-packages">
        <h3 class="panel-title">{{ t("kol.dashboard.byPackage") }}</h3>
        <a-table
          :columns="packageColumns"
          :data-source="packagesQuery.data.value || []"
          :loading="packagesQuery.isPending.value"
          :pagination="false"
          row-key="package_id"
          size="middle"
        >
          <template #emptyText>
            <a-empty :description="t('kol.marketplace.empty')" />
          </template>
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'failure_rate'">
              <span :style="{ color: record.failure_rate > 0.1 ? '#f5222d' : 'inherit' }">
                {{ (record.failure_rate * 100).toFixed(2) }}%
              </span>
            </template>
          </template>
        </a-table>
      </section>

      <!-- Trend Chart -->
      <section class="panel panel-trend">
        <div class="panel-header">
          <h3 class="panel-title">{{ t("kol.dashboard.trend") }}</h3>
          <a-radio-group v-model:value="periodDays" size="small" button-style="solid">
            <a-radio-button :value="7">7天</a-radio-button>
            <a-radio-button :value="30">30天</a-radio-button>
            <a-radio-button :value="90">90天</a-radio-button>
          </a-radio-group>
        </div>

        <div class="chart-container" v-if="!trendQuery.isPending.value">
          <div v-if="chartPoints.length > 0" class="svg-chart-wrapper" ref="chartWrapperRef" @mouseleave="hideTooltip">
            <div class="chart-legend">
              <div class="legend-item"><span class="dot sub"></span> 订阅</div>
              <div class="legend-item"><span class="dot usage"></span> 使用</div>
            </div>
            <svg :viewBox="chartViewBox" class="svg-chart" preserveAspectRatio="none">
              <!-- Grid lines -->
              <line 
                v-for="i in 5" :key="i"
                :x1="chartPadding.left" 
                :y1="chartPadding.top + (Math.max(wrapperHeight - chartPadding.top - chartPadding.bottom, 1) * (i-1) / 4)"
                :x2="chartPadding.left + Math.max(wrapperWidth - chartPadding.left - chartPadding.right, 1)"
                :y2="chartPadding.top + (Math.max(wrapperHeight - chartPadding.top - chartPadding.bottom, 1) * (i-1) / 4)"
                stroke="#f0f0f0"
                stroke-width="1"
              />
              
              <!-- Paths -->
              <path :d="chartPaths.subscriptions" fill="none" stroke="#1890ff" stroke-width="2" stroke-linejoin="round" />
              <path :d="chartPaths.usages" fill="none" stroke="#52c41a" stroke-width="2" stroke-linejoin="round" />
              
              <!-- X Axis Labels -->
              <text 
                v-for="tick in chartAxis" :key="tick.x"
                :x="tick.x" 
                :y="chartPadding.top + Math.max(wrapperHeight - chartPadding.top - chartPadding.bottom, 1) + 20"
                text-anchor="middle"
                font-size="12"
                fill="#8c8c8c"
              >
                {{ tick.label }}
              </text>

              <!-- Hover Interaction Areas -->
              <rect
                v-for="(point, i) in chartPoints"
                :key="'hover-'+i"
                :x="point.hoverX"
                :y="chartPadding.top"
                :width="point.hoverWidth"
                :height="Math.max(wrapperHeight - chartPadding.top - chartPadding.bottom, 1)"
                fill="transparent"
                style="cursor: pointer;"
                @mouseenter="showTooltip(point)"
              />

              <!-- Tooltip Overlay -->
              <g v-if="activePoint">
                <!-- Vertical dashed line -->
                <line 
                  :x1="activePoint.x" :y1="chartPadding.top" 
                  :x2="activePoint.x" :y2="chartPadding.top + Math.max(wrapperHeight - chartPadding.top - chartPadding.bottom, 1)" 
                  stroke="#bfbfbf" stroke-width="1" stroke-dasharray="4 4" 
                />
                
                <!-- Dots on the line -->
                <circle :cx="activePoint.x" :cy="activePoint.subY" r="4" fill="#1890ff" stroke="#fff" stroke-width="2" />
                <circle :cx="activePoint.x" :cy="activePoint.useY" r="4" fill="#52c41a" stroke="#fff" stroke-width="2" />
                
                <!-- Tooltip Panel -->
                <g :transform="`translate(${activePoint.x > (wrapperWidth - 160) ? activePoint.x - 140 : activePoint.x + 15}, ${chartPadding.top + 20})`">
                  <rect x="0" y="0" width="125" height="75" fill="#ffffff" stroke="#e8e8e8" rx="4" style="filter: drop-shadow(0 2px 6px rgba(0,0,0,0.1));" />
                  <text x="12" y="22" font-size="12" font-weight="bold" fill="#8c8c8c">{{ activePoint.date }}</text>
                  <circle cx="16" cy="42" r="4" fill="#1890ff" />
                  <text x="28" y="46" font-size="12" fill="#1a1a1a">订阅: {{ activePoint.subscriptions }}</text>
                  <circle cx="16" cy="62" r="4" fill="#52c41a" />
                  <text x="28" y="66" font-size="12" fill="#1a1a1a">使用: {{ activePoint.usages }}</text>
                </g>
              </g>
            </svg>
          </div>
          <a-empty v-else description="暂无趋势数据" />
        </div>
        <div v-else class="chart-skeleton">
          <a-skeleton active :paragraph="{ rows: 6 }" />
        </div>
      </section>
    </div>
  </div>
</template>

<style scoped>
.kol-dashboard-view {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.page-title {
  font-size: 20px;
  font-weight: 700;
  margin: 0 0 4px 0;
  color: #1a1a1a;
}
.page-desc {
  font-size: 14px;
  color: #8c8c8c;
  margin: 0;
}

/* Stats Row */
.stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.stat-card {
  border-radius: 12px;
  border: none;
}
.stat-content {
  display: flex;
  align-items: center;
  gap: 16px;
}
.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
}
.stat-info {
  display: flex;
  flex-direction: column;
}
.stat-label {
  font-size: 14px;
  color: #8c8c8c;
  margin-bottom: 4px;
}
.stat-value {
  font-size: 24px;
  font-weight: 700;
  color: #1a1a1a;
  line-height: 1;
}

/* Dashboard Grid */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

@media (max-width: 1400px) {
  .dashboard-grid {
    grid-template-columns: 1fr;
  }
}

/* Panel */
.panel {
  background: #ffffff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
  min-width: 0; /* Add to prevent grid/flex blowout */
}
.panel-title {
  margin: 0 0 20px 0;
  font-size: 16px;
  font-weight: 700;
  color: #1a1a1a;
  display: flex;
  align-items: center;
}
.panel-title::before {
  content: "";
  display: inline-block;
  width: 4px;
  height: 14px;
  background: #1f5cff;
  border-radius: 2px;
  margin-right: 8px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
.panel-header .panel-title {
  margin-bottom: 0;
}

/* Chart */
.chart-container {
  height: 320px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.svg-chart-wrapper {
  flex: 1;
  position: relative;
  min-height: 0; /* Fix flex item height blowout */
}
.chart-legend {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  margin-bottom: 12px;
  position: relative;
  z-index: 10;
}
.legend-item {
  font-size: 12px;
  color: #8c8c8c;
  display: flex;
  align-items: center;
  gap: 6px;
}
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.dot.sub { background: #1890ff; }
.dot.usage { background: #52c41a; }

.svg-chart {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  z-index: 1;
}

.chart-skeleton {
  padding: 20px;
}

/* Shadows */
.shadow-sm {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}
</style>
