import { apiClient } from '../infrastructure/api/client';
import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import { Layers, Sparkles } from 'lucide-react';
import * as Icons from 'lucide-react';
import { metadataAPI } from '../infrastructure/api/metadata';
import { Logger } from '../core/services/Logger';
import type { AppConfig } from '../types';
import { getColorClasses } from '../core/utils/colorClasses';
import { registerHostSessionLifecycleListener, formatApiError } from '@nexuscrm/host-sdk';
import { useApp } from '@nexuscrm/host-sdk';
import { tryBuildAppNavigationPath } from '../core/navigation/appNavigationCapabilities';

export function buildAppManagerStudioRoute(app: Pick<AppConfig, 'id' | 'frontendAppId'>): string | null {
    return app.frontendAppId ? tryBuildAppNavigationPath(app.frontendAppId, 'studio', { appId: app.id }) ?? null : null;
}

export const AppManager: React.FC = () => {
    const { currentFrontendAppId } = useApp();
    const externalSalesforce = apiClient.getSessionConnectionKind() === 'external';
    const [apps, setApps] = useState<AppConfig[]>([]);
    const [loading, setLoading] = useState(true);
    const [loadError, setLoadError] = useState<string | null>(null);
    const generation = useRef(0);
    const sessionActive = useRef(true);
    const [sessionRevision, setSessionRevision] = useState(0);
    const loadApps = async () => {
        const current = ++generation.current;
        try {
            setLoadError(null);
            const response = await metadataAPI.getApplicationDefinitions();
            if (generation.current === current) setApps(response.apps || []);
        } catch (err: unknown) {
            if (generation.current !== current) return;
            Logger.error('[AppManager] Failed to load apps', {}, err);
            setLoadError(formatApiError(err).message);
        } finally {
            if (generation.current === current) setLoading(false);
        }
    };

    useEffect(() => {
        const clear = () => {
            sessionActive.current = false;
            ++generation.current;
            setApps([]);
            setLoadError(null);
            setLoading(false);
        };
        const unregister = registerHostSessionLifecycleListener({
            onCleared: clear,
            onAuthenticated: () => { clear(); sessionActive.current = true; setLoading(true); setSessionRevision(value => value + 1); },
        });
        return unregister;
    }, []);

    useEffect(() => {
        // Start after host notification finishes; newly registered requests
        // must not consume the authentication event that created this session.
        if (sessionActive.current) void loadApps();
        return () => { ++generation.current; };
    }, [sessionRevision]);

    const getIconComponent = (iconName: string) => {
        const IconComponent = Icons[iconName as keyof typeof Icons] as React.ComponentType<{ size?: number | string; className?: string }>;
        return IconComponent || Icons.Layers;
    };

    if (loading) {
        return (
            <div className="p-6 space-y-6">
                <div className="animate-pulse flex justify-between items-center">
                    <div>
                        <div className="h-8 w-48 bg-slate-200 rounded mb-2" />
                        <div className="h-4 w-72 bg-slate-100 rounded" />
                    </div>
                    <div className="h-10 w-28 bg-slate-200 rounded-lg" />
                </div>
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                    {[1, 2, 3].map(i => (
                        <div key={i} className="bg-white border border-slate-200 rounded-2xl p-6 animate-pulse">
                            <div className="w-12 h-12 bg-slate-200 rounded-lg mb-4" />
                            <div className="h-5 w-32 bg-slate-200 rounded mb-2" />
                            <div className="h-4 w-48 bg-slate-100 rounded" />
                        </div>
                    ))}
                </div>
            </div>
        );
    }

    return (
        <div className="p-6">
            <div className="flex justify-between items-center mb-6">
                <div>
                    <h1 className="text-2xl font-bold text-slate-800">App Manager</h1>
                    <p className="text-slate-600 mt-1">{externalSalesforce ? 'View Salesforce applications. Manage their settings and navigation in Salesforce Setup.' : 'View installed applications and edit their navigation'}</p>
                </div>

            </div>

            {loadError && <div role="alert" className="mb-4 text-red-700">Unable to load applications: {loadError}. <button onClick={loadApps} className="underline">Retry</button></div>}
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {apps.map(app => {
                    const IconComponent = getIconComponent(app.icon || '');
                    const colors = getColorClasses(app.color);
                    const studioRoute = buildAppManagerStudioRoute(apiClient.getSessionConnectionKind() === 'external' ? { ...app, frontendAppId: currentFrontendAppId ?? undefined } : app);
                    return (
                        <div
                            key={app.id}
                            className="bg-white border border-slate-200 rounded-2xl p-6 hover:shadow-xl hover:border-blue-200 hover:-translate-y-1 transition-all duration-200 cursor-pointer group"
                        >
                            <div className="flex items-start justify-between mb-4">
                                <div className={`w-12 h-12 ${colors.bg} rounded-lg flex items-center justify-center ${colors.text}`}>
                                    <IconComponent size={24} />
                                </div>

                            </div>

                            <h3 className="text-lg font-semibold text-slate-800 mb-1">{app.label}</h3>
                            <p className="text-sm text-slate-500 mb-3">{app.description}</p>

                            <div className="flex items-center justify-between">
                                <div className="text-xs text-slate-400">
                                    {externalSalesforce ? 'Salesforce application' : 'Installed application'}
                                </div>
                                {studioRoute ? (
                                    <Link
                                        to={studioRoute}
                                        className="flex items-center gap-1 text-xs text-blue-600 hover:text-blue-700 font-medium"
                                    >
                                        <Sparkles size={12} />
                                        Open in Studio
                                    </Link>
                                ) : (
                                    <span className="flex items-center gap-1 text-xs text-slate-400 font-medium">
                                        <Sparkles size={12} />
                                        Open in Studio
                                    </span>
                                )}
                            </div>
                        </div>
                    );
                })}
            </div>

            {!loadError && apps.length === 0 && (
                <div className="flex flex-col items-center justify-center py-16 px-4">
                    <div className="w-24 h-24 bg-gradient-to-br from-blue-100 to-indigo-100 rounded-full flex items-center justify-center mb-6 shadow-inner">
                        <Layers className="text-blue-500" size={40} />
                    </div>
                    <h3 className="text-xl font-semibold text-slate-700 mb-2">No apps yet</h3>
                    <p className="text-slate-500 text-center max-w-md mb-6">
                        {externalSalesforce ? 'Manage applications in Salesforce Setup.' : 'Applications are supplied by the installed application release.'}
                    </p>

                </div>
            )}


        </div>
    );
};
