<script lang="ts">
export default { name: "DashboardDailyUserStat" };
</script>

<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, reactive, watch } from "vue";
import { init, EChartsOption } from "echarts";
import resize from "@/utils/resize";
import { dailyUserStat } from "@/api/system/dashboard";

interface DayRow {
    stat_date:      string;
    register_count: number;
    login_count:    number;
}

const props = defineProps<{ includeInternal?: number }>();

const state = reactive({
    loading:    false,
    days:       7 as 7 | 30,
    activeTab:  "register" as "register" | "login",
    rows:       [] as DayRow[],
});

const { mounted: resizeMounted, chart, beforeDestroy } = resize();

watch(() => props.includeInternal, () => load());

async function load(days: 7 | 30 = state.days) {
    state.loading = true;
    try {
        const res: any = await dailyUserStat(days, (props.includeInternal ?? 0) as 0 | 1);
        state.rows = (res?.data ?? []).map((r: any) => ({
            stat_date:      r.stat_date,
            register_count: Number(r.register_count) || 0,
            login_count:    Number(r.login_count)    || 0,
        }));
        await nextTick();
        renderChart();
    } catch (e) {
        console.error("[DailyUserStat]", e);
    } finally {
        state.loading = false;
    }
}

function setDays(days: 7 | 30) {
    state.days = days;
    load(days);
}

function switchTab(tab: "register" | "login") {
    state.activeTab = tab;
    renderChart();
}

function fmtDate(d: string) {
    const parts = d.split("-");
    if (parts.length < 3) return d;
    return parseInt(parts[1]) + "月" + parseInt(parts[2]) + "日";
}

function renderChart() {
    const el = document.getElementById("dailyUserStatChart");
    if (!el) return;
    if (!chart.value) chart.value = init(el);

    const isRegister = state.activeTab === "register";
    const dates  = state.rows.map(r => fmtDate(r.stat_date));
    const values = state.rows.map(r => isRegister ? r.register_count : r.login_count);
    const label  = isRegister ? "注册" : "登录";
    const color  = isRegister ? "#409eff" : "#67c23a";

    const opts: EChartsOption = {
        color: [color],
        tooltip: {
            trigger: "axis",
            axisPointer: { type: "shadow" },
            formatter(params: any) {
                const p = params[0];
                return p.name + "<br/>" + p.marker + label + ": " + p.value;
            },
        },
        legend: {
            data: [label],
            top: 4,
            textStyle: { fontSize: 12 },
            selectedMode: false,
        },
        grid: {
            top: 36,
            bottom: 24,
            left: 12,
            right: 12,
            containLabel: true,
        },
        xAxis: {
            type: "category",
            data: dates,
            axisLabel: { fontSize: 11 },
            axisTick: { show: false },
            axisLine: { lineStyle: { color: "#ddd" } },
        },
        yAxis: {
            type: "value",
            minInterval: 1,
            axisLabel: { fontSize: 11 },
            splitLine: { lineStyle: { color: "#f5f5f5" } },
        },
        series: [
            {
                name: label,
                type: "bar",
                data: values,
                barMaxWidth: 24,
                itemStyle: { borderRadius: [3, 3, 0, 0] },
            },
        ],
    };
    chart.value.setOption(opts, true);
}

onBeforeUnmount(() => { beforeDestroy(); });

onMounted(() => {
    resizeMounted();
    load();
});
</script>

<template>
    <el-col :span="24" class="card-panel__col">
        <el-card class="daily-user-card" shadow="never">
            <template #header>
                <div class="us-header">
                    <div class="tab-group">
                        <span
                            class="us-tab"
                            :class="{ active: state.activeTab === 'register' }"
                            @click="switchTab('register')"
                        >注册统计</span>
                        <span
                            class="us-tab"
                            :class="{ active: state.activeTab === 'login' }"
                            @click="switchTab('login')"
                        >登录统计</span>
                    </div>
                    <div class="header-actions">
                        <el-button
                            size="small"
                            :type="state.days === 7 ? 'primary' : ''"
                            @click="setDays(7)"
                        >最近7日</el-button>
                        <el-button
                            size="small"
                            :type="state.days === 30 ? 'primary' : ''"
                            @click="setDays(30)"
                        >最近30日</el-button>
                    </div>
                </div>
            </template>

            <div v-loading="state.loading" element-loading-text="加载中...">
                <div id="dailyUserStatChart" style="height: 300px; width: 100%" />

                <div class="table-scroll" v-if="state.rows.length > 0">
                    <table class="data-table">
                        <thead>
                            <tr>
                                <th class="label-th"></th>
                                <th v-for="row in state.rows" :key="row.stat_date">
                                    {{ fmtDate(row.stat_date) }}
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-if="state.activeTab === 'register'">
                                <td class="label-td">
                                    <span class="dot" style="background:#409eff" />注册
                                </td>
                                <td v-for="row in state.rows" :key="row.stat_date">
                                    {{ row.register_count }}
                                </td>
                            </tr>
                            <tr v-else>
                                <td class="label-td">
                                    <span class="dot" style="background:#67c23a" />登录
                                </td>
                                <td v-for="row in state.rows" :key="row.stat_date">
                                    {{ row.login_count }}
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <el-empty v-else-if="!state.loading" description="暂无数据" :image-size="60" style="padding: 20px 0" />
            </div>
        </el-card>
    </el-col>
</template>

<style lang="scss" scoped>
.daily-user-card {
    border-radius: 4px;
    margin-top: 12px;

    :deep(.el-card__header) {
        padding: 14px 20px;
        border-bottom: 1px solid #ebeef5;
    }
}

.us-header {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .header-actions {
        display: flex;
        gap: 8px;
    }
}

.tab-group {
    display: flex;
    gap: 0;
}

.us-tab {
    font-size: 16px;
    font-weight: 600;
    color: #909399;
    cursor: pointer;
    padding-bottom: 2px;
    margin-right: 20px;
    border-bottom: 2px solid transparent;
    transition: color 0.2s, border-color 0.2s;

    &.active {
        color: #303133;
        border-bottom-color: #409eff;
    }

    &:hover {
        color: #606266;
    }
}

.table-scroll {
    margin-top: 12px;
    overflow-x: auto;
}

.data-table {
    border-collapse: collapse;
    width: 100%;
    min-width: max-content;
    font-size: 12px;

    th, td {
        padding: 6px 10px;
        text-align: center;
        border: 1px solid #ebeef5;
        white-space: nowrap;
    }

    th {
        background: #f5f7fa;
        color: #606266;
        font-weight: 600;
    }

    .label-th, .label-td {
        text-align: left;
        min-width: 64px;
        background: #fafafa;
        font-weight: 600;
        color: #303133;
    }
}

.dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    margin-right: 5px;
    vertical-align: middle;
}
</style>
