import './discordstatus.css';

import { useEffect, useState } from "react";

interface LanyardResponse {
    success: boolean;
    data: LanyardData;
}

interface LanyardData {
    discord_status: 'online' | 'idle' | 'dnd' | 'offline';
    activities: DiscordActivity[];
    discord_user: DiscordUser;
    active_on_discord_web: boolean;
    active_on_discord_desktop: boolean;
    active_on_discord_mobile: boolean;
    active_on_discord_embedded: boolean;
    active_on_discord_vr: boolean;
    listening_to_spotify: boolean;
    spotify: SpotifyData | null;
    kv: Record<string, string>;
}

interface SpotifyData {
    album: string;
    album_art_url: string;
    artist: string;
    song: string;
    track_id: string;
    timestamps: {
        start: number;
        end: number;
    };
}

interface DiscordUser {
    id: string;
    username: string;
    discriminator: string;
    global_name: string;
    display_name: string;
    avatar: string;
    bot: boolean;
    public_flags: number;
    avatar_decoration_data: null | any;
    collectibles?: {
        nameplate?: {
            asset: string;
            expires_at: string | null;
            label: string;
            palette: string;
            sku_id: string;
        };
    };
    display_name_styles?: {
        colors: any[];
        effect_id: number;
        font_id: number;
    };
    primary_guild?: {
        badge: null | any;
        identity_enabled: boolean;
        identity_guild_id: null | string;
        tag: null | string;
    };
}

interface DiscordActivity {
    id: string;
    name: string;
    type: number;
    session_id?: string;
    created_at: number;
    state?: string;
    details?: string;
    timestamps?: {
        start?: number;
        end?: number;
    };
    assets?: {
        large_image?: string;
        large_text?: string;
        small_image?: string;
        small_text?: string;
    };
    emoji?: {
        name: string;
        id?: string;
        animated?: boolean;
    };
    application_id?: string;
    flags?: number;
    platform?: string;
    sync_id?: string;
    content_classification?: {
        data: null | any;
        loaded: boolean;
    };
}

function resolveDiscordAsset(applicationId: string | undefined, image: string | undefined): string {
    if (!image) return "";

    if (image.startsWith("mp:external/")) {
        const httpsIndex = image.indexOf("/https/");
        if (httpsIndex !== -1) {
            return `https://${image.slice(httpsIndex + "/https/".length)}`;
        }
    }

    if (image.startsWith("spotify:"))
        return "";


    if (applicationId && image)
        return `https://cdn.discordapp.com/app-assets/${applicationId}/${image}.png`;

    return image;
}

export interface DiscordStatusParams {
    userId: string
}

const STATUS_LABELS: Record<LanyardData['discord_status'], string> = {
    online: 'online',
    idle: 'away',
    dnd: 'busy',
    offline: 'offline'
};

export function DiscordStatus({ userId }: DiscordStatusParams) {
    const [presence, setPresence] = useState<LanyardData | null>(null);
    const [loading, setLoading] = useState<boolean>(true);

    useEffect(() => {
        let interval: NodeJS.Timeout | null = null;

        async function fetchRichPresence() {
            try {
                const response = await fetch(`https://api.lanyard.rest/v1/users/${userId}`);
                const json: LanyardResponse = await response.json();
                if (json.success)
                    setPresence(json.data);
            } catch (error) {
                console.error("Failed to fetch Lanyard presence:", error);
            } finally {
                setLoading(false);
            }
        }

        const startPolling = () => {
            if (!interval) {
                fetchRichPresence();
                interval = setInterval(fetchRichPresence, 30000);
            }
        };

        const stopPolling = () => {
            if (interval) {
                clearInterval(interval);
                interval = null;
            }
        };

        const handleVisibilityChange = () => {
            if (document.visibilityState === 'visible')
                startPolling();
            else
                stopPolling();

        };

        if (document.visibilityState === 'visible')
            startPolling();
        else
            setLoading(false);

        document.addEventListener('visibilitychange', handleVisibilityChange);

        return () => {
            document.removeEventListener('visibilitychange', handleVisibilityChange);
            stopPolling();
        };
    }, [userId]);

    if (loading)
        return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>loading status...</p>;

    if (!presence)
        return <p style={{ fontSize: '0.75rem', fontStyle: 'italic', color: 'var(--text-dim)' }}>offline</p>;

    const customActivity = presence.activities.find(act => act.id === "custom");
    const customStatusText = customActivity
        ? `${customActivity.emoji?.name || ''} ${customActivity.state || ''}`.trim()
        : null;

    const gameActivity = presence.activities
        .filter(act => act.type === 0)
        .sort((a, b) => (b.assets ? 1 : 0) - (a.assets ? 1 : 0))[0] as DiscordActivity | undefined;

    const isListeningToSpotify = presence.listening_to_spotify && presence.spotify;

    let primaryActivity = null;
    let activityText = "";
    let activityImage = "";

    if (gameActivity) {
        primaryActivity = gameActivity;
        activityText = `playing: ${gameActivity.name.toLowerCase()}`;

        if (gameActivity.details)
            activityText += ` • ${gameActivity.details}`;

        if (gameActivity.assets) {
            const targetImage = gameActivity.assets.small_image || gameActivity.assets.large_image;
            activityImage = resolveDiscordAsset(gameActivity.application_id, targetImage);
        }
    }
    else if (isListeningToSpotify && presence.spotify) {
        primaryActivity = { name: "Spotify" } as DiscordActivity;
        activityText = `listening to: ${presence.spotify.song} • ${presence.spotify.artist}`;
        activityImage = presence.spotify.album_art_url || "";
    }

    return (
        <div className="discord-status-compact">
            <div className="avatar-container">
                <img
                    src={`https://api.lanyard.rest/${userId}.png`}
                    alt="Discord avatar"
                    className="discord-avatar"
                />
                <span className={`status-dot ${presence.discord_status}`} />
            </div>

            <div className="status-details">
                <span className="status-text">
                    {primaryActivity ? (
                        <>{activityText}</>
                    ) : (
                        <>currently: <em>{STATUS_LABELS[presence.discord_status]}</em></>
                    )}
                </span>

                {customStatusText && (
                    <span className="status-bubble-inline">
                        {customStatusText}
                    </span>
                )}
            </div>

            {activityImage && primaryActivity && (
                <img
                    src={activityImage}
                    alt={primaryActivity.name}
                    className="game-icon"
                />
            )}
        </div>
    );
}
