import type { Page } from "@/lib/store";

type ParsedQuery = {
    textTerms: string[];
    tagTerms: string[];
    typeTerm: "file" | "folder" | null;
    updatedDays: number | null;
};

function stripHtml(input: string): string {
    return (input || "").replace(/<[^>]+>/g, " ");
}

export function parseSearchQuery(rawQuery: string): ParsedQuery {
    const tokens = rawQuery
        .trim()
        .split(/\s+/)
        .filter(Boolean);

    const parsed: ParsedQuery = {
        textTerms: [],
        tagTerms: [],
        typeTerm: null,
        updatedDays: null,
    };

    for (const token of tokens) {
        const lower = token.toLowerCase();
        if (lower.startsWith("tag:")) {
            const value = token.slice(4).trim();
            if (value) parsed.tagTerms.push(value.toLowerCase());
            continue;
        }
        if (lower.startsWith("type:")) {
            const value = token.slice(5).trim().toLowerCase();
            if (value === "file" || value === "folder") parsed.typeTerm = value;
            continue;
        }
        if (lower.startsWith("updated:")) {
            const value = token.slice(8).trim().toLowerCase();
            const match = /^(\d+)d$/.exec(value);
            if (match) {
                parsed.updatedDays = Number.parseInt(match[1], 10);
            }
            continue;
        }
        parsed.textTerms.push(lower);
    }

    return parsed;
}

export function filterPagesByQuery(pages: Page[], rawQuery: string): Page[] {
    const q = parseSearchQuery(rawQuery);
    const now = Date.now();

    return pages.filter((page) => {
        if (q.typeTerm && page.type !== q.typeTerm) return false;

        if (q.tagTerms.length > 0) {
            const tagSet = new Set((page.tags || []).map((t) => t.toLowerCase()));
            const allTagsMatched = q.tagTerms.every((t) => tagSet.has(t));
            if (!allTagsMatched) return false;
        }

        if (q.updatedDays !== null) {
            if (!page.updatedAt) return false;
            const diffMs = now - new Date(page.updatedAt).getTime();
            const maxMs = q.updatedDays * 24 * 60 * 60 * 1000;
            if (Number.isNaN(diffMs) || diffMs > maxMs) return false;
        }

        if (q.textTerms.length > 0) {
            const haystack = [
                page.title || "",
                stripHtml(page.content || ""),
                ...(page.tags || []),
            ]
                .join(" ")
                .toLowerCase();
            const allTermsMatched = q.textTerms.every((term) => haystack.includes(term));
            if (!allTermsMatched) return false;
        }

        return true;
    });
}

