<template>
    <ParentPage active="reports" @scrolltolower="loadMore">
        <ParentFilterRow
            :items="filterItems"
            @change="onFilterChange"
        />

        <view v-if="reportList.length" class="report-list">
            <ParentCard
                v-for="item in reportList"
                :key="item.id"
                class="report-card"
                clickable
                @click="openReport(item)"
            >
                <view class="report-body">
                    <view class="subject-badge" :class="subjectClass(item.subject)">{{ subjectShort(item.subject) }}</view>
                    <view class="report-main">
                        <view v-if="item.category" class="category">[{{ item.category }}]</view>
                        <text class="report-title ellipsis-2">{{ item.title }}</text>
                    </view>
                    <view class="score-wrap">
                        <text class="score">{{ formatScore(item.score) }}</text>
                        <text class="date">{{ item.date }}</text>
                    </view>
                </view>
            </ParentCard>
            <view v-if="loadingMore" class="list-tip">加载中...</view>
            <view v-else-if="!hasMore" class="list-tip">没有更多了</view>
        </view>

        <view v-else-if="!listLoading" class="empty-card">
            <xy-Empty type="task" content="暂无符合条件的考试报告" />
        </view>

        <view v-if="listLoading" class="loading-wrap">
            <xy-Empty type="loading" content="加载中..." />
        </view>
    </ParentPage>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import {
    getListCompleteRecord,
    getPaperTestTypeLabel,
    normalizeListCompleteRecord,
    PAPER_TEST_TYPE_OPTIONS,
    type ListCompleteRecordParams,
    type PaperRecord,
} from '@/api/homework';
import { useParentStore } from '@/state/modules/parent';
import { formatTime } from '@/utils/format';
import { SUBJECT_FILTER_OPTIONS, type SubjectFilterOption } from '@/utils/subject';
import { storeToRefs } from 'pinia';
import ParentCard from '../components/ParentCard.vue';
import ParentFilterRow from '../components/ParentFilterRow.vue';
import ParentPage from '../components/ParentPage.vue';

interface ReportCard {
    id: string;
    subject: string;
    category: string;
    title: string;
    score: number;
    date: string;
}

const parentStore = useParentStore();
const { activeChild } = storeToRefs(parentStore);

const typeOptionLabels = PAPER_TEST_TYPE_OPTIONS.map((item) => item.label);

const subjectOptions = ref<SubjectFilterOption[]>([...SUBJECT_FILTER_OPTIONS]);
const subjectIndex = ref(0);
const typeIndex = ref(0);

const reportList = ref<ReportCard[]>([]);
const listLoading = ref(false);
const loadingMore = ref(false);
const hasMore = ref(true);
const currentPage = ref(1);

const subjectOptionLabels = computed(() => subjectOptions.value.map((item) => item.label));

const filterItems = computed(() => [
    { key: 'subject', range: subjectOptionLabels.value, value: subjectIndex.value },
    { key: 'type', range: typeOptionLabels, value: typeIndex.value },
]);

const getScoreRate = (item: PaperRecord) => {
    const total = Number(item.totalScore);
    const score = Number(item.score);
    if (total > 0) {
        return Math.round((score / total) * 1000) / 10;
    }
    return score || 0;
};

const mapRecord = (item: PaperRecord): ReportCard => ({
    id: String(item.id),
    subject: item.subjectName || '多科',
    category: getPaperTestTypeLabel(item.type),
    title: item.paperName || '',
    score: getScoreRate(item),
    date: formatTime(item.markTime || item.submitTime || item.endTime, 'YYYY-MM-DD'),
});

const buildRequestParams = (): ListCompleteRecordParams => {
    const params: ListCompleteRecordParams = {
        current: currentPage.value,
        resourceType: 0,
    };

    if (activeChild.value.id) {
        params.userId = activeChild.value.id;
    }

    const subject = subjectOptions.value[subjectIndex.value];
    if (subject?.subjectId) {
        params.subjectId = subject.subjectId;
    }

    const typeOption = PAPER_TEST_TYPE_OPTIONS[typeIndex.value];
    if (typeOption?.value) {
        params.type = typeOption.value;
    }

    return params;
};

const fetchReports = async (append = false) => {
    if (!activeChild.value.id) {
        reportList.value = [];
        hasMore.value = false;
        return;
    }

    const res = await getListCompleteRecord(buildRequestParams());
    const { rows, totalRows } = normalizeListCompleteRecord(res.data);
    const mapped = rows.map(mapRecord);

    if (append) {
        const exists = new Set(reportList.value.map((item) => item.id));
        reportList.value = reportList.value.concat(mapped.filter((item) => !exists.has(item.id)));
    } else {
        reportList.value = mapped;
    }

    hasMore.value = reportList.value.length < totalRows;
};

const refreshReports = async () => {
    listLoading.value = true;
    currentPage.value = 1;
    hasMore.value = true;
    try {
        await fetchReports(false);
    } catch (err) {
        console.error('[parent-reports] fetch err', err);
        reportList.value = [];
        hasMore.value = false;
    } finally {
        listLoading.value = false;
    }
};

const loadMore = async () => {
    if (listLoading.value || loadingMore.value || !hasMore.value) return;
    loadingMore.value = true;
    currentPage.value += 1;
    try {
        await fetchReports(true);
    } catch (err) {
        console.error('[parent-reports] load more err', err);
        currentPage.value -= 1;
    } finally {
        loadingMore.value = false;
    }
};

const onSubjectChange = (e: { detail: { value: string } }) => {
    subjectIndex.value = Number(e.detail.value);
    refreshReports();
};

const onTypeChange = (e: { detail: { value: string } }) => {
    typeIndex.value = Number(e.detail.value);
    refreshReports();
};

const onFilterChange = (payload: { key: string; value: number }) => {
    if (payload.key === 'subject') {
        subjectIndex.value = payload.value;
        refreshReports();
        return;
    }
    if (payload.key === 'type') {
        typeIndex.value = payload.value;
        refreshReports();
    }
};

const formatScore = (score: number) => `${score.toFixed(1).replace(/\.0$/, '')}%`;

const subjectShort = (subject: string) => {
    if (!subject) return '多科';
    return subject.length > 2 ? subject.slice(0, 2) : subject;
};

const subjectClass = (subject: string) => {
    if (subject.includes('数学')) return 'math';
    if (subject.includes('语文')) return 'chinese';
    if (subject.includes('英语')) return 'english';
    return 'multi';
};

const openReport = (item: ReportCard) => {
    const userId = activeChild.value.id ? `&userId=${activeChild.value.id}` : '';
    uni.navigateTo({
        url: `/pages/parent/reports/detail?id=${item.id}&name=${encodeURIComponent(item.title)}&subject=${encodeURIComponent(item.subject)}&category=${encodeURIComponent(item.category)}&date=${item.date}&score=${item.score}${userId}`,
    });
};

onShow(() => {
    refreshReports();
});
</script>

<style lang="scss" scoped>
.report-list {
    margin-top: 22rpx;
}

.report-card {
    margin-bottom: 18rpx;
    padding: 24rpx;
}

.report-body {
    display: flex;
    align-items: center;
    gap: 20rpx;
}

.subject-badge {
    width: 86rpx;
    height: 86rpx;
    border-radius: 32rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffffff;
    font-size: 24rpx;
    font-weight: 900;
    flex-shrink: 0;

    &.math { background: #14b8a6; }
    &.chinese { background: #f97316; }
    &.english { background: #ec4899; }
    &.multi { background: #3b82f6; }
}

.report-main {
    flex: 1;
    min-width: 0;
}

.category {
    color: #64748b;
    font-size: 22rpx;
    font-weight: 700;
}

.report-title {
    display: block;
    margin-top: 4rpx;
    color: #164e63;
    font-size: 28rpx;
    font-weight: 800;
    line-height: 1.35;
}

.score-wrap {
    width: 112rpx;
    text-align: right;
    flex-shrink: 0;
}

.score {
    display: block;
    color: #ea580c;
    font-size: 30rpx;
    font-weight: 900;
}

.date {
    display: block;
    margin-top: 8rpx;
    color: #94a3b8;
    font-size: 22rpx;
}

.empty-card {
    height: 520rpx;
    margin-top: 24rpx;
}

.loading-wrap {
    height: 520rpx;
    margin-top: 24rpx;
}

.list-tip {
    text-align: center;
    color: #94a3b8;
    font-size: 24rpx;
    padding: 12rpx 0 24rpx;
}
</style>
