import {
    getWrongQuestionFilterPage,
    getWrongQuestionSummary,
    type PageResult,
    type QuestionTitle,
    type WrongQuestionItem,
    type WrongQuestionSummaryResult,
} from '@/api/parent';
import { formatWrongQuestionHtml } from '@/utils/questionHtml';
import { useParentStore } from '@/state/modules/parent';
import { useUserStore } from '@/state/modules/user';

export type { QuestionTitle, WrongQuestionItem };

export interface WrongOption {
    index: string;
    html: string;
}

export interface WrongQuestion extends WrongQuestionItem {
    expanded: boolean;
    previewHtml: string;
    firstErrorTimeText: string;
    lastErrorTimeText: string;
    expandContent?: WrongExpandContent;
}

export interface WrongExpandContent {
    parsedOptions: WrongOption[] | null;
    stemHtml: string;
    optionHtmlFallback: string;
    answerHtml: string;
    explanationHtml: string;
}

export const SUBJECT_TONES = ['blue', 'green', 'orange', 'rose', 'violet'];

export const TIME_RANGE_OPTIONS = [
    { value: '', label: '全部时间' },
    { value: 'today', label: '今天' },
    { value: '7days', label: '近7天' },
    { value: '30days', label: '近30天' },
];

export const normalizeHtml = (html?: string, options?: { stripImages?: boolean }) =>
    formatWrongQuestionHtml(html, options);

export const getPreviewHtml = (item: WrongQuestionItem): string => {
    if (!item.questionTitle) return '--';
    const html = item.questionTitle.stemHtml || item.questionTitle.stem || '';
    if (!html) return '--';
    return formatWrongQuestionHtml(html, { stripImages: true }) || '--';
};

export const parseOptions = (optionHtml?: string): WrongOption[] | null => {
    if (!optionHtml) return null;
    try {
        const parsed = typeof optionHtml === 'string' ? JSON.parse(optionHtml) : optionHtml;
        if (Array.isArray(parsed)) {
            return parsed.map((item: any) => ({
                index: item.index || '',
                html: formatWrongQuestionHtml(item.html || ''),
            }));
        }
    } catch {
        /* not JSON, fallback to HTML string */
    }
    return null;
};

export const getTimeRange = (rangeKey: string): { startTime?: string; endTime?: string } => {
    if (!rangeKey) return {};
    const now = new Date();
    const endTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} 23:59:59`;
    let start: Date;
    if (rangeKey === 'today') {
        start = now;
    } else if (rangeKey === '7days') {
        start = new Date(now.getTime() - 6 * 86400000);
    } else {
        start = new Date(now.getTime() - 29 * 86400000);
    }
    const startTime = `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, '0')}-${String(start.getDate()).padStart(2, '0')} 00:00:00`;
    return { startTime, endTime };
};

export const formatWrongTime = (time?: string) => {
    if (!time) return '--';
    return time.replace('T', ' ').slice(0, 16);
};

export const getPreviewText = (item: WrongQuestionItem): string => {
    const html = item.questionTitle?.stemHtml || item.questionTitle?.stem || '';
    if (!html) return '--';
    return html.replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim().slice(0, 120) || '--';
};

export const createWrongQuestionShell = (item: WrongQuestionItem): WrongQuestion => ({
    ...item,
    expanded: false,
    previewHtml: getPreviewText(item),
    firstErrorTimeText: formatWrongTime(item.firstErrorTime),
    lastErrorTimeText: formatWrongTime(item.lastErrorTime),
});

export const hydrateWrongQuestionPreview = (item: WrongQuestion) => {
    try {
        item.previewHtml = getPreviewHtml(item);
    } catch (err) {
        console.error('[wrong] preview hydrate failed', err);
        item.previewHtml = getPreviewText(item);
    }
};

export const mapWrongQuestionItem = (item: WrongQuestionItem): WrongQuestion => ({
    ...createWrongQuestionShell(item),
    previewHtml: getPreviewHtml(item),
});

export const ensureExpandContent = (item: WrongQuestion) => {
    if (item.expandContent || !item.questionTitle) return;
    const qt = item.questionTitle;
    try {
        item.expandContent = {
            parsedOptions: parseOptions(qt.optionHtml),
            stemHtml: normalizeHtml(qt.stemHtml || qt.stem),
            optionHtmlFallback: normalizeHtml(qt.optionHtml),
            answerHtml: normalizeHtml(qt.answerHtml || qt.answer),
            explanationHtml: normalizeHtml(qt.explanation),
        };
    } catch (err) {
        console.error('[wrong] expand content failed', err);
        item.expandContent = {
            parsedOptions: null,
            stemHtml: getPreviewText(item),
            optionHtmlFallback: '',
            answerHtml: String(qt.answer || qt.answerHtml || ''),
            explanationHtml: String(qt.explanation || ''),
        };
    }
};

export const normalizeWrongQuestionPage = (
    data: WrongQuestionItem[] | PageResult<WrongQuestionItem> | null | undefined,
    page = 1,
) => {
    if (!data) {
        return { rows: [] as WrongQuestionItem[], totalRows: 0, current: page };
    }
    if (Array.isArray(data)) {
        return { rows: data, totalRows: data.length, current: page };
    }
    const rows = data.rows || data.records || [];
    return {
        rows,
        totalRows: data.totalRows ?? rows.length,
        current: data.current ?? page,
    };
};

export const WRONG_LIST_PAGE_SIZE = 10;

export const resolveWrongUserId = async () => {
    const userStore = useUserStore();
    const parentStore = useParentStore();

    if (parentStore.activeChild.id) {
        return parentStore.activeChild.id;
    }
    if (parentStore.activeChildId) {
        return parentStore.activeChildId;
    }

    try {
        if (!userStore.userInfo.id) {
            await userStore.fetchParentUserInfo();
        }
        if (userStore.userInfo.id) {
            await parentStore.fetchBindChildren(userStore.userInfo.id);
        }
    } catch {
        /* ignore */
    }

    if (parentStore.activeChild.id) {
        return parentStore.activeChild.id;
    }

    try {
        if (!userStore.userInfo.id) {
            await userStore.fetchUserInfo();
        }
    } catch {
        /* ignore */
    }

    return userStore.userInfo.id || '';
};

export const fetchWrongSummary = async (): Promise<WrongQuestionSummaryResult | null> => {
    const userId = await resolveWrongUserId();
    if (!userId) return null;

    try {
        const res = await getWrongQuestionSummary({ userId });
        return res.data || null;
    } catch (err) {
        console.error('[wrong] summary err', err);
        return null;
    }
};

export const fetchWrongQuestionPage = async (params: {
    userId?: string | number;
    subjectId?: string | number;
    current?: number;
    size?: number;
    startTime?: string;
    endTime?: string;
}) => {
    const current = params.current ?? 1;
    const res = await getWrongQuestionFilterPage({
        userId: params.userId,
        subjectId: params.subjectId,
        current,
        size: params.size ?? WRONG_LIST_PAGE_SIZE,
        startTime: params.startTime,
        endTime: params.endTime,
    });
    const { rows, totalRows } = normalizeWrongQuestionPage(res.data, current);
    return {
        rows: rows.map((item: WrongQuestionItem) => mapWrongQuestionItem(item)),
        totalRows,
        current,
    };
};

export const buildSubjectStatRow = (
    name: string,
    stats: { total: number; newCount: number; reviewCount: number; masteredCount: number },
    index: number,
) => ({
    name,
    shortName: name === '全部' ? '全' : name.slice(0, 1),
    tone: SUBJECT_TONES[index % SUBJECT_TONES.length],
    total: stats.total,
    newCount: stats.newCount,
    reviewCount: stats.reviewCount,
    masteredCount: stats.masteredCount,
});
