import {
    defaultOrionPanelContent,
    defaultPublicPanelContent,
    defaultCompetitionTabsContent,
    emptyCompetitionItem,
} from "./defaults";
import type {
    CompetitionItem,
    CompetitionPanelContent,
    CompetitionTab,
    CompetitionTabsContent,
    ContentMap,
} from "./types";

function str(value: unknown): string {
    return typeof value === "string" ? value : "";
}

function parseCompetition(raw: Record<string, unknown>): CompetitionItem {
    return {
        title: str(raw.title ?? raw.name).trim(),
        icon: str(raw.icon ?? raw.emoji).trim(),
        iconImage: str(raw.iconImage).trim(),
        category: str(raw.category ?? raw.committee).trim(),
        color: str(raw.color).trim() || "deep-sea",
        month: str(raw.month ?? raw.orionMonth).trim(),
        description: str(raw.description).trim(),
        publicCompetition: str(raw.publicCompetition).trim(),
        publicTiming: str(raw.publicTiming).trim(),
        orionMonth: str(raw.orionMonth).trim(),
        dateTime: str(raw.dateTime).trim(),
        method: str(raw.method).trim(),
        badge: str(raw.badge).trim(),
        buttonText: str(raw.buttonText).trim(),
        buttonUrl: str(raw.buttonUrl).trim(),
    };
}

export function parseCompetitions(raw: unknown, fallback: CompetitionItem[]): CompetitionItem[] {
    if (!Array.isArray(raw) || raw.length === 0) {
        return fallback.map((item) => ({ ...item }));
    }

    return raw
        .filter((item): item is Record<string, unknown> => item != null && typeof item === "object")
        .map(parseCompetition)
        .filter((item) => item.title || item.description || item.category || item.month);
}

export function parseCompetitionPanelContent(
    content: ContentMap | undefined,
    fallback: CompetitionPanelContent = defaultOrionPanelContent(),
): CompetitionPanelContent {
    const base = fallback;
    return {
        emoji: str(content?.emoji).trim() || base.emoji,
        title: str(content?.title).trim() || base.title,
        subtitle: str(content?.subtitle).trim(),
        description: str(content?.description).trim(),
        accentColor: str(content?.accentColor).trim() || base.accentColor,
        flexibleEmoji: str(content?.flexibleEmoji).trim(),
        flexibleTitle: str(content?.flexibleTitle).trim() || base.flexibleTitle,
        competitions: parseCompetitions(content?.competitions, base.competitions),
    };
}

export function parseCompetitionTab(raw: unknown, index: number): CompetitionTab {
    const source = raw != null && typeof raw === "object" ? (raw as Record<string, unknown>) : {};
    const fallbackPanel = index === 1 ? defaultPublicPanelContent() : defaultOrionPanelContent();
    const panelRaw =
        source.panel != null && typeof source.panel === "object"
            ? (source.panel as ContentMap)
            : (source as ContentMap);

    const id = str(source.id).trim() || (index === 0 ? "orion" : index === 1 ? "public" : `tab-${index + 1}`);
    const label =
        str(source.label).trim() ||
        str(panelRaw.title).trim() ||
        (index === 0 ? "Orion Competitions" : index === 1 ? "Public Competitions" : `Tab ${index + 1}`);
    const icon = str(source.icon).trim() || str(panelRaw.emoji).trim() || (index === 0 ? "🏫" : "🌍");

    return {
        id,
        label,
        icon,
        panel: parseCompetitionPanelContent(panelRaw, fallbackPanel),
    };
}

export function parseCompetitionTabsContent(content: ContentMap | undefined): CompetitionTabsContent {
    const fallback = defaultCompetitionTabsContent();
    const rawTabs = content?.tabs;

    const tabs =
        Array.isArray(rawTabs) && rawTabs.length > 0
            ? rawTabs.map((tab, index) => parseCompetitionTab(tab, index))
            : fallback.tabs.map((tab) => ({
                  ...tab,
                  panel: {
                      ...tab.panel,
                      competitions: tab.panel.competitions.map((item) => ({ ...item })),
                  },
              }));

    const defaultTabId = str(content?.defaultTabId).trim() || tabs[0]?.id || fallback.defaultTabId;

    return {
        defaultTabId: tabs.some((tab) => tab.id === defaultTabId) ? defaultTabId : tabs[0]?.id || "orion",
        showCounts: content?.showCounts !== false,
        tabs,
    };
}

export function serializeCompetitionPanel(panel: CompetitionPanelContent): ContentMap {
    return {
        emoji: panel.emoji,
        title: panel.title,
        subtitle: panel.subtitle,
        description: panel.description,
        accentColor: panel.accentColor,
        flexibleEmoji: panel.flexibleEmoji,
        flexibleTitle: panel.flexibleTitle,
        competitions: panel.competitions,
    };
}

export function newCompetitionTab(index: number): CompetitionTab {
    return {
        id: `tab-${Date.now()}-${index}`,
        label: `Tab ${index + 1}`,
        icon: "🏆",
        panel: {
            ...defaultOrionPanelContent(),
            title: `Tab ${index + 1}`,
            emoji: "🏆",
            competitions: [emptyCompetitionItem()],
        },
    };
}

export { defaultOrionPanelContent, defaultPublicPanelContent, emptyCompetitionItem };
