/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
import DOMPurify from 'dompurify';
import { getAppOrigin } from '../utils/capacitor';
import React, { useState, useEffect, useRef, lazy, Suspense } from 'react';
import { Helmet } from 'react-helmet-async';
import { useParams, useNavigate, useLocation, Link } from 'react-router-dom';
import { Button } from '../components/ui/Button';
import { RecipeHero } from '../components/recipe/RecipeHero';
import { StarRating } from '../components/community/StarRating';
import { RecipeIngredients } from '../components/recipe/RecipeIngredients';

const RecipeComments = lazy(() => import('../components/recipe/RecipeComments').then(m => ({ default: m.RecipeComments })));
const RecipeCarousel = lazy(() => import('../components/recipe/RecipeCarousel').then(m => ({ default: m.RecipeCarousel })));
const RecipeKnowledge = lazy(() => import('../components/recipe/RecipeKnowledge').then(m => ({ default: m.RecipeKnowledge })));
const RecipeGuideBento = lazy(() => import('../components/recipe/RecipeGuide/RecipeGuideBento').then(m => ({ default: m.RecipeGuideBento })));
import { Skeleton } from '../components/ui/Skeleton';
import { RecipeDeleteModal, RecipePlannerModal, RecipeTrackerModal, RecipeReportModal, RecipeShareModal } from '../components/recipe/modals/RecipeDetailModals';
import { useRecipeFetch } from '../hooks/useRecipeFetch';
import { useAppContext } from '../context/AppContext';
import { Leaf, Clock, Flame, Plus, Heart, MessageCircle, Trash2, Pencil, Check, Flag, Share2, Star, Droplets, Egg, Activity, Candy, Package, Loader2, ChevronDown, MoreHorizontal, ArrowRight } from 'lucide-react';
import { ShieldCheck, Sparkles, Wand2 } from 'lucide-react';
import { Modal } from '../components/ui/Modal';
import { SEOHead } from '../components/seo/SEOHead';
import contentService from '../services/contentService';
import api from '../api';
import { optimizedImg } from '../utils/optimizedImg';
import { AnimatePresence } from 'framer-motion';
import { NotFound } from './NotFound';
import { Breadcrumbs } from '../components/seo/Breadcrumbs';
import { pluralizeUnit } from '../utils/pluralizeUnit';
import { scaleIngredientString, parseIngredientString, formatIngredientAmount, cleanIngredientForShopping } from '../utils/ingredientParser';
import { safeStorage } from '../utils/safeStorage';
import { capitalizeFirstLetter, linkifyGlossaryTerms } from '../utils/textFormatting';
// Lazy-loaded: RecipeCoachDashboard pulls recharts (~440 KB) which is below-the-fold
// on first paint. Deferring this saves ~100 KB brotli on the initial RecipeDetail render
// and improves mobile LCP measurably.
const RecipeCoachDashboard = lazy(() => import('../components/recipe/RecipeCoachDashboard'));
import { trackEvent } from '../utils/pageMetrics';
import { getSynergies, getBrainFoodStatus, getEcoAndPRAL } from '../utils/healthAdvanced';
import { generateRecipeImage } from '../components/recipe/RecipeImageExport';
import { getCategorySeoData, SEO_TAG_SLUG_MAP } from '../utils/seoTagMap';
import { generateRecipeSchemas } from '../components/recipe/RecipeSchema';
import { getMatchingExclusions } from '../utils/allergenUtils';
import './RecipeDetail.css';
import './RecipeDetail.polish.css';
import '../pages/MealPlannerPremium.css';
import { PullToRefresh } from '../components/ui/PullToRefresh';

// --- Lazy-loaded heavy components (only load when needed) ---
const CookingMode = lazy(() => import('../components/recipe/CookingMode').then(m => ({ default: m.CookingMode })));

// Helper to detect ingredient group headers in both "## Dressing" and "---Dressing---" formats
const isIngredientGroupHeader = (rawText) => {
    if (typeof rawText !== 'string') return false;
    const trimmed = rawText.trim();
    if (trimmed.startsWith('## ')) return true;
    if (/^-{2,}[^-].*-{2,}$/.test(trimmed)) return true;
    // Plain text ending with colon, no leading digit (not an ingredient)
    if (/^[^\d][^:]{1,40}:$/.test(trimmed)) return true;
    return false;
};

export function RecipeDetail() {
    const { id } = useParams();
    const navigate = useNavigate();
    const location = useLocation();
    const {
        user,
        savedRecipeIds,
        toggleSaveRecipe,
        addIngredientsToShoppingList,
        pantryItems,
        logMealAndDeduct,
        showToast,
        setCollectionModalRecipe,
        weeklyPlan,
        setWeeklyPlan,
        isEditMode,
        deleteRecipe
    } = useAppContext();

    const commentFormRef = useRef(null);

    const [isCookingModeOpen, setIsCookingModeOpen] = useState(false);
    const [commentRating, setCommentRating] = useState(0);
    const [isDownloading, setIsDownloading] = useState(false);
    const [isDeleting, setIsDeleting] = useState(false);
    const [isAddingToList, setIsAddingToList] = useState(false);
    const [isAddingToPlan, setIsAddingToPlan] = useState(false);
    const [recipeToDelete, setRecipeToDelete] = useState(false);

    // Meal Planner Modal
    const [showPlannerModal, setShowPlannerModal] = useState(false);
    const [plannerDay, setPlannerDay] = useState('Montag');
    const [plannerMeal, setPlannerMeal] = useState('lunch');
    const PLANNER_DAYS = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'];
    const PLANNER_MEALS = [{ id: 'breakfast', label: 'Frühstück' }, { id: 'lunch', label: 'Mittagessen' }, { id: 'dinner', label: 'Abendessen' }, { id: 'snack', label: 'Snack' }];

    const [isReportModalOpen, setIsReportModalOpen] = useState(false);
    const [reportReason, setReportReason] = useState('Typo/Fehler im Text');
    const [reportComment, setReportComment] = useState('');
    const [isReporting, setIsReporting] = useState(false);

    // Tracker Log Modal
    const [showTrackerModal, setShowTrackerModal] = useState(false);
    const [trackerMealType, setTrackerMealType] = useState('lunch');
    const [isLoggingToTracker, setIsLoggingToTracker] = useState(false);
    const [deductFromPantry, setDeductFromPantry] = useState(false);
    const TRACKER_MEALS = [{ id: 'breakfast', label: 'Frühstück' }, { id: 'lunch', label: 'Mittagessen' }, { id: 'dinner', label: 'Abendessen' }, { id: 'snack', label: 'Snack' }];


    // Share Modal state
    const [showShareModal, setShowShareModal] = useState(false);
    const [networkUsers, setNetworkUsers] = useState([]);
    const [loadingNetwork, setLoadingNetwork] = useState(false);
    const [isSharingToUser, setIsSharingToUser] = useState(null);

    // Follow state
    const [isFollowing, setIsFollowing] = useState(false);
    const [isFollowLoading, setIsFollowLoading] = useState(false);

    // Verification state
    const [isVerifying, setIsVerifying] = useState(false);

    // Desktop Tags Limitation State
    const [isDesktop, setIsDesktop] = useState(window.innerWidth > 768);
    const [showAllTagsDesktop, setShowAllTagsDesktop] = useState(false);
    const [showAllTagsMobile, setShowAllTagsMobile] = useState(false);

    // Description expand state
    // Description is expanded by default; toggle only appears for truly long (>5 lines) descriptions.
    const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(true);
    const [showDescriptionToggle, setShowDescriptionToggle] = useState(false);
    const descriptionRef = useRef(null);

    // Action overflow menu
    const [isActionMenuOpen, setIsActionMenuOpen] = useState(false);
    const actionMenuRef = useRef(null);


    useEffect(() => {
        const handleResize = () => setIsDesktop(window.innerWidth > 768);
        window.addEventListener('resize', handleResize);
        return () => window.removeEventListener('resize', handleResize);
    }, []);

    useEffect(() => {
        const handleClickOutside = (e) => {
            if (actionMenuRef.current && !actionMenuRef.current.contains(e.target)) {
                setIsActionMenuOpen(false);
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);

    // Note: Pre-filling comment name/email is handled inside RecipeComments component

    const { recipe, setRecipe, relatedRecipes, loading, loadingRelated, knowledgeArticles, checkedIngredients, setCheckedIngredients, portions, setPortions } = useRecipeFetch(id, savedRecipeIds);



    useEffect(() => {
        if (!descriptionRef.current) return;
        const timer = setTimeout(() => {
            const el = descriptionRef.current;
            if (!el) return;
            // Measure true content height irrespective of clamp state, compare against
            // 5 lines using computed line-height. Toggle is only needed for long copy.
            const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 20;
            const threshold = lineHeight * 5;
            // When unclamped, scrollHeight equals content. When clamped, scrollHeight
            // still equals content while clientHeight is smaller. Either way scrollHeight
            // reflects the real measured length.
            setShowDescriptionToggle(el.scrollHeight > threshold + 2);
        }, 50);
        return () => clearTimeout(timer);
    }, [recipe?.seoArticleData?.hook, recipe?.seoDescription, isDesktop, isDescriptionExpanded]);

    useEffect(() => {
        const checkFollowStatus = async () => {
            if (user && recipe && recipe.authorId && user.id !== recipe.authorId) {
                try {
                    const res = await api.get(`/user/check-follow/${recipe.authorId}`);
                    setIsFollowing(res.data.isFollowing);
                } catch (error) {
                    console.error("Error checking follow status:", error);
                }
            }
        };
        checkFollowStatus();
    }, [user, recipe]);



    const synergies = React.useMemo(() => getSynergies(recipe || {}), [recipe]);
    const brainFood = React.useMemo(() => getBrainFoodStatus(recipe || {}), [recipe]);
    const { ecoScore, ecoReason, pralScore, pralDesc } = React.useMemo(() => getEcoAndPRAL(recipe || {}), [recipe]);

    const identifier = recipe?.id || recipe?.title;
    const isSaved = savedRecipeIds.some(item =>
        (typeof item === 'string' && item === identifier) ||
        (typeof item === 'object' && (item.id === identifier || item.title === identifier))
    );
    const initialIsSavedRef = useRef(false);

    useEffect(() => {
        initialIsSavedRef.current = isSaved;
        // Run once on load to capture the initial state.
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [recipe?.id]);

    // Push recipe into "Kürzlich angesehen"-Liste (für Home-Feed Section).
    // Max 10 Einträge, neueste zuerst, keine Duplikate.
    useEffect(() => {
        if (!recipe?.id) return;
        const existing = safeStorage.local.getJSON('recentlyViewedRecipeIds') ?? [];
        const filtered = (Array.isArray(existing) ? existing : []).filter(id => id !== recipe.id);
        const next = [recipe.id, ...filtered].slice(0, 10);
        safeStorage.local.setJSON('recentlyViewedRecipeIds', next);
    }, [recipe?.id]);

    const handleVerify = async () => {
        if (!user || user.role !== 'ADMIN') return;
        setIsVerifying(true);
        try {
            const newStatus = !recipe.isManuallyVerified;
            await api.put(`/admin/recipes/${recipe.id}/verify`, { isManuallyVerified: newStatus });
            setRecipe({ ...recipe, isManuallyVerified: newStatus });
            showToast('Aktualisiert!', 'success');
        } catch (error) {
            console.error(error);
            showToast("Fehler beim Ändern des Verifizierungs-Status.", "error");
        } finally {
            setIsVerifying(false);
        }
    };

    // Pantry matching for ingredient list
    const pantryMatchMap = React.useMemo(() => {
        if (!pantryItems || pantryItems.length === 0 || !recipe?.ingredients) return { map: new Map(), matchCount: 0, totalCount: 0 };
        const pantryNameSet = new Map();
        pantryItems.forEach(p => {
            const name = (p.item || '').toLowerCase().trim();
            if (name) pantryNameSet.set(name, p);
        });
        const map = new Map();
        let matchCount = 0;
        let totalCount = 0;
        const allIngs = recipe.recipeIngredients && recipe.recipeIngredients.length > 0
            ? recipe.recipeIngredients
            : (recipe.ingredients || []).map(rawText => ({ rawText }));
        allIngs.forEach((ingObj, idx) => {
            const raw = ingObj.rawText || ingObj;
            if (typeof raw === 'string' && isIngredientGroupHeader(raw)) return;
            totalCount++;
            const parsed = ingObj.parsedName ? { name: ingObj.parsedName } : parseIngredientString(typeof raw === 'string' ? raw : '');
            const name = (parsed.name || (typeof raw === 'string' ? raw : '')).toLowerCase().trim();
            let found = pantryNameSet.has(name);
            if (!found) {
                const firstWord = name.split(/\s+/)[0];
                for (const [pName] of pantryNameSet) {
                    if (pName === firstWord || (name.length >= 3 && pName.length >= 3 && (name.includes(pName) || pName.includes(name)))) {
                        found = true;
                        break;
                    }
                }
            }
            if (found) {
                matchCount++;
                map.set(idx, true);
            }
        });
        return { map, matchCount, totalCount };
    }, [pantryItems, recipe]);

    // Allergen/Exclusion matching
    const matchingExclusions = React.useMemo(() => {
        if (!user || !user.exclusions || user.exclusions.length === 0 || !recipe) return [];
        const allIngs = recipe.recipeIngredients && recipe.recipeIngredients.length > 0
            ? recipe.recipeIngredients
            : (recipe.ingredients || []).map(rawText => ({ rawText }));
        return getMatchingExclusions(allIngs, user.exclusions);
    }, [user, recipe]);

    if (loading) {
        return (
            <div className="recipe-detail-page">
                <Skeleton className="detail-skeleton-hero" />
                <article className="recipe-detail-container recipe-detail-wrapper">
                    <div className="detail-breadcrumbs-wrapper detail-skeleton-breadcrumbs-wrap">
                        <Skeleton className="detail-skeleton-breadcrumbs" />
                    </div>
                    <header className="detail-header">
                        <div className="detail-title-row">
                            <Skeleton className="detail-skeleton-title" />
                        </div>
                        <div className="detail-skeleton-tags-wrap">
                            <Skeleton className="detail-skeleton-tag-1" />
                            <Skeleton className="detail-skeleton-tag-2" />
                            <Skeleton className="detail-skeleton-tag-3" />
                        </div>
                    </header>
                    <div className="detail-skeleton-content-wrap">
                        <div className="detail-skeleton-column">
                            <Skeleton className="detail-skeleton-subtitle" />
                            {[...Array(6)].map((_, i) => (
                                <Skeleton key={i} className="detail-skeleton-line" />
                            ))}
                        </div>
                        <div className="detail-skeleton-column">
                            <Skeleton className="detail-skeleton-subtitle" />
                            {[...Array(5)].map((_, i) => (
                                <Skeleton key={i} className={i === 4 ? "detail-skeleton-line-sm-short" : "detail-skeleton-line-sm"} />
                            ))}
                        </div>
                    </div>
                </article>
            </div>
        );
    }

    let saveCount = recipe?._count?.savedBy || 0;
    if (isSaved && !initialIsSavedRef.current) saveCount += 1;
    if (!isSaved && initialIsSavedRef.current) saveCount = Math.max(0, saveCount - 1);

    if (!recipe) {
        const isFromCoach = id?.startsWith('temp_ai_') || location.state?.fromCoach;

        if (isFromCoach) {
            return (
                <div className="recipe-detail-page recipe-detail-empty-state">
                    <Sparkles size={48} color="var(--brand-primary)" className="recipe-detail-empty-icon" />
                    <h1 className="recipe-detail-empty-title">Rezept nicht gefunden</h1>
                    <p className="recipe-detail-empty-text">
                        Möglicherweise hat dein Coach dieses Rezept <b>gerade erst für dich konzipiert</b> und es existiert noch nicht in der Datenbank.
                    </p>
                    <div className="recipe-detail-empty-actions">
                        <Button onClick={() => navigate('/rezept-generator')} className="hover-lift">
                            <Wand2 size={16} /> Jetzt von KI generieren lassen
                        </Button>
                        <Button variant="outline" onClick={() => navigate(-1)}>
                            Zurück zum Chat
                        </Button>
                    </div>
                </div>
            );
        }

        return (
            <div className="recipe-detail-page recipe-detail-empty-state">
                <NotFound />
            </div>
        );
    }


    const handlePrint = () => {
        trackEvent('print', recipe.id, window.location.pathname, user?.id);
        window.print();
    };

    const handleAddToList = async () => {
        setIsAddingToList(true);
        try {
            let itemsToAdd = recipe.recipeIngredients || [];

            // Fallback for old recipes that haven't been migrated yet
            if (itemsToAdd.length === 0 && recipe.ingredients && recipe.ingredients.length > 0) {
                itemsToAdd = recipe.ingredients.map(ing => ({ rawText: ing }));
            }

            if (checkedIngredients.size > 0) {
                itemsToAdd = itemsToAdd.filter((_, idx) => checkedIngredients.has(idx));
            }

            const multiplier = portions / (recipe.portions || 2);
            const recipeTitle = recipe.title || '';

            const scaledIngredients = itemsToAdd
                .filter(item => {
                    const raw = item.rawText || item;
                    return !isIngredientGroupHeader(raw);
                })
                .map(item => {
                    const raw = item.rawText || item;
                    // Always re-check if the raw string is completely unparsable junk (e.g. "oder grob gemahlen")
                    const testParsed = parseIngredientString(cleanIngredientForShopping(raw));
                    if (!testParsed.name) return null; // Drop junk fragments entirely

                    let scaled;
                    if (item.parsedName) {
                        const scaledQty = item.parsedQuantity ? (item.parsedQuantity * multiplier) : '';
                        scaled = `${scaledQty ? formatIngredientAmount(scaledQty) : ''} ${pluralizeUnit(item.parsedUnit, scaledQty)} ${item.parsedName} ${item.descriptors || ''}`.replace(/\\s+/g, ' ').trim();
                    } else {
                        scaled = scaleIngredientString(raw, multiplier);
                    }
                    // Pre-clean and add recipe annotation
                    const cleaned = cleanIngredientForShopping(scaled);
                    if (!cleaned) return null;
                    return recipeTitle ? `${cleaned} ||Für: ${recipeTitle}||` : cleaned;
                })
                .filter(Boolean);

            await addIngredientsToShoppingList(scaledIngredients);
        } finally {
            setIsAddingToList(false);
        }
    };




    const handleRatingClick = (selectedRating) => {
        setCommentRating(selectedRating);
        if (commentFormRef.current) {
            commentFormRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    };

    const handleSave = () => {
        toggleSaveRecipe(recipe);
    };

    const handleAddToMealPlan = async () => {
        if (!user) {
            showToast('Bitte einloggen, um den Wochenplaner zu nutzen.', 'info');
            navigate(`/auth?redirect=${encodeURIComponent(location.pathname)}`);
            return;
        }

        setIsAddingToPlan(true);
        const currentPlan = weeklyPlan ? JSON.parse(JSON.stringify(weeklyPlan)) : {};
        if (!currentPlan[plannerDay]) currentPlan[plannerDay] = {};

        const pRecipe = {
            id: recipe.id,
            title: recipe.title,
            image: recipe.image,
            prepTime: recipe.prepTime,
            cookTime: recipe.cookTime,
            macros: recipe.macros,
            category: recipe.category,
            taxonomySlugs: recipe.taxonomySlugs
        };

        currentPlan[plannerDay][plannerMeal] = pRecipe;

        try {
            await api.put('/mealplan', { planData: currentPlan });
            if (setWeeklyPlan) setWeeklyPlan(currentPlan);
            showToast('Erfolgreich!', 'success');
            setShowPlannerModal(false);
        } catch (err) {
            console.error(err);
            const errMsg = err.response?.data?.error || 'Fehler beim Speichern in den Wochenplan.';
            const isUpgrade = err.response?.data?.upgrade;
            
            showToast(errMsg, 'error', isUpgrade ? {
                label: 'Zu Premium',
                onClick: () => navigate('/premium')
            } : null, isUpgrade ? 8000 : 3000);
        } finally {
            setIsAddingToPlan(false);
        }
    };

    const handleFollowToggle = async () => {
        if (!user) {
            showToast("Bitte logge dich ein, um diesem Profil zu folgen.", "error");
            return;
        }
        setIsFollowLoading(true);
        try {
            const res = await api.post(`/user/follow/${recipe.authorId}`);
            setIsFollowing(res.data.following);
            showToast('Erfolgreich!', 'success');
        } catch (error) {
            console.error(error);
            showToast("Fehler beim Ändern des Follow-Status.", "error");
        } finally {
            setIsFollowLoading(false);
        }
    };

    const handleShare = async () => {
        // Track share event in background immediately to not block UI
        if (recipe?.id) {
            api.post(`/recipes/${recipe.id}/share`).catch(err => console.warn('Share track err', err));
        }

        // Prefer native Share Sheet immediately on mobile devices
        if (navigator.share && /iPad|iPhone|iPod|Android/.test(navigator.userAgent)) {
            try {
                await navigator.share({
                    title: recipe.title,
                    text: `Schau dir dieses Rezept an: ${recipe.title}`,
                    url: `${getAppOrigin()}${location.pathname}`,
                });
                return; // Successfully shared natively, don't open modal
            } catch (err) {
                // If the user cancelled (AbortError), do nothing. Otherwise, fallback to modal.
                if (err.name === 'AbortError') return;
            }
        }

        // Fallback for Desktop: Show the custom share modal with Network options
        setShowShareModal(true);
        if (user && networkUsers.length === 0) {
            setLoadingNetwork(true);
            try {
                const res = await api.get('/user/following?limit=50');
                setNetworkUsers(res.data.users || []);
            } catch (error) {
                console.error("Failed to load network for sharing", error);
            } finally {
                setLoadingNetwork(false);
            }
        }
    };

    const handleShareLink = async () => {
        if (navigator.share) {
            try {
                await navigator.share({
                    title: recipe.title,
                    url: `${getAppOrigin()}${location.pathname}`,
                });
            } catch (err) {
                console.error("error sharing", err);
            }
        } else {
            navigator.clipboard.writeText(`${getAppOrigin()}${location.pathname}`);
            showToast('Kopiert!', 'success');
        }
        setShowShareModal(false);
    };

    const handleShareToNetwork = async (targetUserId) => {
        if (!user) {
            showToast('Bitte einloggen, um Rezepte zu teilen.', 'info');
            return;
        }
        setIsSharingToUser(targetUserId);
        try {
            await api.post('/user/share/recipe', { targetUserId, recipeId: recipe.id });
            showToast('Rezept erfolgreich geteilt!', 'success');
            setShowShareModal(false);
        } catch (error) {
            showToast('Fehler beim Teilen', 'error');
        } finally {
            setIsSharingToUser(null);
        }
    };

    const handleDownloadImage = async () => {
        await generateRecipeImage({
            recipe,
            portions,
            setIsDownloading,
            showToast,
            formatIngredientAmount,
            pluralizeUnit,
            scaleIngredientString
        });
    };

    const handleDelete = async () => {
        setIsDeleting(true);
        try {
            await deleteRecipe(recipe.id);
            // deleteRecipe already shows a toast, so we don't need another success toast
            setRecipeToDelete(false);
            navigate('/');
        } catch (error) {
            console.error(error);
            showToast("Fehler beim Löschen des Rezepts", "error");
        } finally {
            setIsDeleting(false);
        }
    };


    const handleReportSubmit = async (e) => {
        e.preventDefault();
        setIsReporting(true);
        try {
            await api.post(`/recipes/${recipe.id}/report`, {
                reason: reportReason,
                comment: reportComment,
            });
            showToast('Gesendet!', 'success');
            setIsReportModalOpen(false);
            setReportReason('Typo/Fehler im Text');
            setReportComment('');
        } catch (error) {
            console.error('Error submitting report:', error);
            showToast('Fehler beim Senden der Meldung.', 'error');
        } finally {
            setIsReporting(false);
        }
    };

    const handleToggleFeature = async () => {
        try {
            await api.put(`/admin/recipes/${recipe.id}/featured`, { isFeatured: !recipe.isFeatured });
            setRecipe(prev => ({ ...prev, isFeatured: !prev.isFeatured }));
            showToast('Erfolgreich!', 'success');
        } catch (error) {
            console.error(error);
            showToast("Fehler beim Ändern des Featured-Status", "error");
        }
    };

    const calculateRating = (r) => {
        if (r.comments && r.comments.length > 0) {
            const ratingComments = r.comments.filter(c => c.rating && c.rating > 0);
            if (ratingComments.length > 0) {
                const sum = ratingComments.reduce((acc, c) => acc + c.rating, 0);
                return Math.round(sum / ratingComments.length);
            }
        }
        return Math.round(r.rating || 0);
    };

    const toggleIngredientCheck = (idx) => {
        setCheckedIngredients(prev => {
            const next = new Set(prev);
            if (next.has(idx)) {
                next.delete(idx);
            } else {
                next.add(idx);
            }
            return next;
        });
    };

    const handleRefresh = async () => {
        await new Promise(r => setTimeout(r, 500));
        window.location.reload();
    };

    return (
        <>
            {/* ── PREMIUM AURORA BACKGROUND ── */}
            

            <PullToRefresh onRefresh={handleRefresh}>
            <div className="recipe-detail-page recipe-detail-page--ready">
                <SEOHead
                title={`${recipe.title} ${recipe.category ? '– ' + recipe.category : ''} | SmarTasty`}
                exactTitle={true}
                description={recipe.seoDescription || `${recipe.title} – gesundes Rezept${recipe.category ? ' (' + recipe.category + ')' : ''}. ${(recipe.prepTime || 0) + (recipe.cookTime || 0)} Min. | ${recipe.macros?.calories ? recipe.macros.calories + ' kcal' : ''}${recipe.macros?.protein ? ', ' + recipe.macros.protein + 'g Eiweiß' : ''}${recipe.servings ? ' | ' + recipe.servings + ' Portionen' : ''}. Jetzt nachkochen auf SmarTasty!`}
                path={`/rezept/${recipe.slug || recipe.id}`}
                image={recipe.image}
                type="article"
            />
            {/* Keeping Schema.org structured data in separate Helmet */}
            <Helmet>
                {recipe.image && (
                    <link rel="preload" as="image" href={optimizedImg(recipe.image, { w: 800, q: 80 })} fetchPriority="high" />
                )}
                <script type="application/ld+json">
                    {JSON.stringify(generateRecipeSchemas(recipe, portions, calculateRating))}
                </script>
            </Helmet>

            {/* Edge-to-Edge Hero Image Layer */}
            <RecipeHero
                recipe={recipe}
                isSaved={isSaved}
                isDownloading={isDownloading}
                onSave={handleSave}
                onPrint={handlePrint}
                onShare={handleShare}
                onDownload={handleDownloadImage}
            />

            <article className="recipe-detail-container recipe-detail-wrapper">
                {/* Print Only Logo Header */}
                <div className="print-only-header">
                    <div className="print-only-logo">
                        <Leaf size={32} fill="currentColor" />
                        <span>SmarTasty</span>
                    </div>
                </div>

                {getCategorySeoData(recipe)?.name && (
                    <div className="no-print detail-breadcrumbs-wrapper">
                        <Breadcrumbs items={[
                            { name: 'Kategorien', path: '/rezepte' },
                            { name: getCategorySeoData(recipe).name, path: `/${getCategorySeoData(recipe).path}` },
                            { name: recipe.title }
                        ]} />
                    </div>
                )}
                <header className="detail-header">
                    {new URLSearchParams(location.search).get('imported') === 'true' && (
                        <div className="import-success-banner">
                            <div className="import-success-header">
                                <div className="import-success-check">
                                    <Check size={14} strokeWidth={2.5} />
                                </div>
                                <div>
                                    <strong className="import-success-title">Erfolgreich importiert!</strong>
                                    <span className="import-success-text">
                                        Gespeichert in{' '}
                                        <button
                                            onClick={() => navigate('/meine-rezepte')}
                                            className="import-success-link"
                                        >
                                            Meine Rezepte
                                        </button>.
                                    </span>
                                </div>
                            </div>
                            <div className="import-success-actions">
                                <button
                                    className="import-success-btn import-success-btn--collection"
                                    onClick={() => setCollectionModalRecipe(recipe)}
                                >
                                    <Plus size={15} />
                                    Sammlung
                                </button>
                                <button
                                    className="import-success-btn import-success-btn--edit"
                                    onClick={() => navigate(`/edit-recipe/${recipe.id}`)}
                                >
                                    <Pencil size={15} />
                                    Bearbeiten
                                </button>
                                <button
                                    className="import-success-btn import-success-btn--more"
                                    onClick={() => navigate('/create-recipe')}
                                >
                                    <ArrowRight size={15} />
                                    Weiteres importieren
                                </button>
                            </div>
                        </div>
                    )}
                    {/* Title is rendered as H1 overlay on the Hero image above.
                        The admin overflow menu (if applicable) lives inline at the end of
                        the author/social row below. */}

                    {/* Author + social row */}
                    <div className="detail-author-social-row no-print">
                        <div className="detail-author-group">
                            <span className="detail-subtitle-author" onClick={() => navigate(`/user/${recipe.author?.username || 'Unbekannt'}`)}>
                                {recipe.author?.username || 'Unbekannt'}
                            </span>
                            {(!user || user.id !== recipe.authorId) && recipe.authorId && (
                                <button className="btn btn-primary detail-follow-btn" onClick={handleFollowToggle} disabled={isFollowLoading}>
                                    {isFollowLoading ? '...' : (isFollowing ? 'Folgst du' : 'Folgen')}
                                </button>
                            )}
                            {calculateRating(recipe) > 0 && (
                                <StarRating
                                    initialRating={calculateRating(recipe)}
                                    onReadOnlyClick={(star) => handleRatingClick(star)}
                                    size={14}
                                />
                            )}

                        </div>
                        <div className="detail-social-icons">
                            {calculateRating(recipe) === 0 && (
                                <button
                                    className="detail-rating-cta"
                                    onClick={() => handleRatingClick(0)}
                                    aria-label="Rezept bewerten"
                                >
                                    <Star size={14} />
                                    <span>Bewerten</span>
                                </button>
                            )}
                            <button
                                className="detail-social-item"
                                onClick={() => {
                                    const el = document.getElementById('comments');
                                    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
                                }}
                                aria-label={`Kommentare (${recipe.comments ? recipe.comments.length : 0})`}
                            >
                                <MessageCircle size={14} />
                                <span>{recipe.comments ? recipe.comments.length : 0}</span>
                            </button>
                            <button
                                className="detail-social-item"
                                onClick={(e) => { e.preventDefault(); e.stopPropagation(); handleSave(); }}
                                aria-label={isSaved ? 'Aus Merkliste entfernen' : 'Zur Merkliste'}
                            >
                                <Heart size={14} fill={isSaved ? 'var(--brand-primary)' : 'none'} color="var(--brand-primary)" />
                                <span>{saveCount}</span>
                            </button>
                            {user && (user.id === recipe.authorId || user.role === 'ADMIN') && (
                                <div className="detail-overflow-wrap no-print" ref={actionMenuRef}>
                                    <button
                                        className="detail-overflow-btn"
                                        onClick={() => setIsActionMenuOpen(prev => !prev)}
                                        title="Aktionen"
                                    >
                                        <MoreHorizontal size={18} />
                                    </button>
                                    {isActionMenuOpen && (
                                        <div className="detail-overflow-menu">
                                            <button className="detail-overflow-item" onClick={() => { setIsActionMenuOpen(false); navigate(`/edit-recipe/${recipe.id}`); }}>
                                                <Pencil size={14} /> Bearbeiten
                                            </button>
                                            {user?.role === 'ADMIN' && (
                                                <>
                                                    <button className={`detail-overflow-item${recipe.isFeatured ? ' detail-overflow-item--active-gold' : ''}`} onClick={() => { setIsActionMenuOpen(false); handleToggleFeature(); }}>
                                                        <Star size={14} fill={recipe.isFeatured ? 'currentColor' : 'none'} /> {recipe.isFeatured ? 'Empfehlung entfernen' : 'Empfehlen'}
                                                    </button>
                                                    <button className={`detail-overflow-item${recipe.isManuallyVerified ? ' detail-overflow-item--active-green' : ''}`} onClick={() => { setIsActionMenuOpen(false); handleVerify(); }} disabled={isVerifying}>
                                                        <ShieldCheck size={14} className={isVerifying ? 'spin' : ''} /> {recipe.isManuallyVerified ? 'Geprüft (entsperren)' : 'Als geprüft markieren'}
                                                    </button>
                                                </>
                                            )}
                                            <div className="detail-overflow-divider" />
                                            <button className="detail-overflow-item detail-overflow-item--danger" onClick={() => { setIsActionMenuOpen(false); setRecipeToDelete(true); }} disabled={isDeleting}>
                                                <Trash2 size={14} /> {isDeleting ? 'Löschen…' : 'Löschen'}
                                            </button>
                                        </div>
                                    )}
                                </div>
                            )}
                        </div>
                    </div>

                    {/* Description (collapsed, toggle below) */}
                    {(recipe.seoArticleData?.hook || recipe.seoDescription) && (
                        <div className="detail-description-wrap">
                            <div
                                ref={descriptionRef}
                                className={`detail-description${!isDescriptionExpanded ? ' detail-description--clamped' : ''}`}
                            >
                                {recipe.seoArticleData?.hook ? (
                                    <span>{recipe.seoArticleData.hook}</span>
                                ) : (
                                    <span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(linkifyGlossaryTerms(recipe.seoDescription), { ADD_ATTR: ['target'] }) }} />
                                )}
                            </div>
                            {showDescriptionToggle && (
                                <button className="detail-description-toggle" onClick={() => setIsDescriptionExpanded(prev => !prev)}>
                                    {isDescriptionExpanded ? 'Weniger' : 'Mehr lesen'}
                                    <ChevronDown size={12} className={`detail-description-toggle-icon${isDescriptionExpanded ? ' is-open' : ''}`} />
                                </button>
                            )}
                        </div>
                    )}

                    {/* Macro bar */}
                    {recipe.macros && (recipe.macros.protein || recipe.macros.fat || recipe.macros.carbs) && (() => {
                        const p = Math.round(recipe.macros.protein || 0);
                        const f = Math.round(recipe.macros.fat || 0);
                        const c = Math.round(recipe.macros.carbs || 0);
                        const fi = Math.round(recipe.macros.fiber || 0);
                        const total = p + f + c + fi || 1;
                        return (
                            <div className="detail-macro-bar-wrap no-print">
                                <div className="detail-macro-legend">
                                    {p > 0 && <span className="detail-macro-legend__item detail-macro-legend__item--protein"><strong>{p}g</strong> Protein</span>}
                                    {f > 0 && <span className="detail-macro-legend__item detail-macro-legend__item--fat"><strong>{f}g</strong> Fett</span>}
                                    {c > 0 && <span className="detail-macro-legend__item detail-macro-legend__item--carbs"><strong>{c}g</strong> Carbs</span>}
                                    {fi > 0 && <span className="detail-macro-legend__item detail-macro-legend__item--fiber"><strong>{fi}g</strong> Fiber</span>}
                                </div>
                            </div>
                        );
                    })()}

                    {/* Tag Chips */}
                    {recipe.tags && recipe.tags.length > 0 && (
                        <div className="detail-tag-chips no-print">
                            {(() => {
                                const seoMap = {
                                    "Mediterran": "mediterrane-rezepte",
                                    "Ballaststoffreich": "ballaststoffreiche-rezepte",
                                    "FODMAP": "fodmap-rezepte",
                                    "Probiotisch": "probiotische-rezepte",
                                    "Basisch": "basische-rezepte",
                                    "Clean Eating": "clean-eating-rezepte",
                                    "High-Protein": "high-protein-rezepte",
                                    "Low-Carb": "low-carb-rezepte",
                                    "Meal-Prep": "meal-prep-rezepte",
                                    "Vegan": "vegane-rezepte",
                                    "Vegetarisch": "vegetarische-rezepte",
                                    "Keto": "keto-rezepte",
                                    "Zuckerfrei": "zuckerfreie-rezepte",
                                    "Kuhmilchfrei": "kuhmilchfreie-rezepte",
                                    "Leber & Stoffwechsel": "leber-detox-rezepte",
                                    "Glutenfrei": "glutenfreie-rezepte",
                                    "Darmfreundlich": "darmfreundliche-rezepte",
                                    "Abnehmen": "abnehmen-rezepte",
                                    "Saft": "saft-rezepte",
                                    "Smoothie": "smoothie-rezepte",
                                    "Getränke": "getraenke-rezepte",
                                    "Longevity": "longevity-rezepte"
                                };
                                const mainTags = recipe.tags.filter(t => seoMap[t]);
                                const secondaryTags = recipe.tags.filter(t => !seoMap[t]);

                                const allDisplayTags = [];
                                if (recipe.macros?.goodForSleep) allDisplayTags.push({ id: 'sleep', type: 'chrono', label: 'Sleep-Boost', tooltip: "Ideal für abends: Enthält schlaffreundliche Nährstoffe" });
                                if (recipe.macros?.energyBooster) allDisplayTags.push({ id: 'energy', type: 'chrono', label: 'Energie-Boost', tooltip: "Ideal für den Tag: Liefert langanhaltende Energie und Fokus" });
                                if (recipe.macros?.goodForBreakfast) allDisplayTags.push({ id: 'breakfast', type: 'chrono', label: 'Frühstücks-Boost', tooltip: "Perfekt für den Start in den Tag" });
                                if (recipe.macros?.preWorkout) allDisplayTags.push({ id: 'preworkout', type: 'chrono', label: 'Pre-Workout', tooltip: "Liefert schnelle Energie für dein Training" });
                                if (recipe.macros?.postWorkoutRecovery) allDisplayTags.push({ id: 'recovery', type: 'chrono', label: 'Recovery', tooltip: "Ideal zur Muskel-Regeneration nach dem Sport" });
                                mainTags.forEach(tag => allDisplayTags.push({ id: tag, type: 'main', tag, path: seoMap[tag] }));
                                secondaryTags.forEach(tag => allDisplayTags.push({ id: tag, type: 'secondary', tag }));

                                const displayLimit = (isDesktop && !showAllTagsDesktop) ? 6 : allDisplayTags.length;
                                const visibleTags = allDisplayTags.slice(0, displayLimit);
                                const hiddenCount = allDisplayTags.length - visibleTags.length;

                                return (
                                    <>
                                        {visibleTags.map(item => {
                                            if (item.type === 'chrono') {
                                                return <span key={item.id} className="detail-tag-chip detail-tag-chip-static" title={item.tooltip}>{item.label}</span>;
                                            } else if (item.type === 'main') {
                                                return <button key={item.id} className="detail-tag-chip detail-tag-chip-link" onClick={() => navigate(`/${item.path}`)}>{item.tag}</button>;
                                            } else {
                                                return <span key={item.id} className="detail-tag-chip detail-tag-chip-static">{item.tag}</span>;
                                            }
                                        })}
                                        {(hiddenCount > 0 && isDesktop && !showAllTagsDesktop) && (
                                            <button className="detail-tag-chip detail-tag-chip-more" onClick={() => setShowAllTagsDesktop(true)}>+ {hiddenCount}</button>
                                        )}
                                    </>
                                );
                            })()}
                        </div>
                    )}
                </header>

                <div className="detail-content-grid">
                    {/* Ingredients Section — sticky on desktop */}
                    <div className="detail-ingredients-sticky-wrap">
                    <RecipeIngredients
                        recipe={recipe}
                        setRecipe={setRecipe}
                        portions={portions}
                        user={user}
                        pantryMatchMap={pantryMatchMap}
                        checkedIngredients={checkedIngredients}
                        isCookingModeOpen={isCookingModeOpen}
                        isAddingToList={isAddingToList}
                        matchingExclusions={matchingExclusions}
                        onPortionChange={(e) => { const val = parseFloat(e.target.value); if (!isNaN(val) && val > 0) setPortions(val); }}
                        onPortionStep={(dir) => setPortions(prev => {
                            const step = prev < 1 ? 0.25 : 0.5;
                            const next = dir === "up" ? prev + step : prev - step;
                            return Math.max(0.25, parseFloat(next.toFixed(2)));
                        })}
                        onSetCookingMode={setIsCookingModeOpen}
                        onToggleIngredientCheck={toggleIngredientCheck}
                        onAddToList={() => handleAddToList()}
                        onAddMissing={() => handleAddToList("missing")}
                        onShowPlannerModal={(val) => {
                            if (!user) {
                                showToast('Bitte einloggen, um den Wochenplaner zu nutzen.', 'info');
                                navigate(`/auth?redirect=${encodeURIComponent(location.pathname)}`);
                                return;
                            }
                            setShowPlannerModal(val);
                        }}
                        onPrint={handlePrint}
                        onShare={handleShare}
                        onLogToTracker={() => {
                            setDeductFromPantry(pantryMatchMap.matchCount > 0);
                            setShowTrackerModal(true);
                        }}
                    />
                    </div>

                    <section className="detail-instructions-section">
                        <h2>{contentService.get('recipe.detail.instructions', 'Zubereitung')}</h2>
                        <ol className="detail-instructions-list">
                            {recipe.instructions.map((step, idx) => (
                                <li key={idx}>
                                    <div className="detail-step-content">
                                        <p>{capitalizeFirstLetter(step)}</p>
                                    </div>
                                </li>
                            ))}
                        </ol>

                    </section>
                </div>

                <Suspense fallback={<div style={{ minHeight: 320 }} aria-hidden="true" />}>
                    <RecipeCoachDashboard
                        recipe={recipe}
                        setRecipe={setRecipe}
                        user={user}
                    />
                </Suspense>

                {recipe.seoArticleData && (
                    <section className="recipe-guide-section">
                        <Suspense fallback={null}>
                            <RecipeGuideBento data={recipe.seoArticleData} />
                        </Suspense>
                    </section>
                )}

                {/* Bottom card — Knowledge, Comments unified */}
                <div className="detail-bottom-card">
                    <Suspense fallback={null}>
                        <RecipeKnowledge
                            recipe={recipe}
                            setRecipe={setRecipe}
                            isEditMode={isEditMode}
                            knowledgeArticles={knowledgeArticles}
                            showToast={showToast}
                        />
                    </Suspense>

                    {/* Related Recipes Carousel */}
                    <Suspense fallback={<div className="suspense-loader"><Loader2 size={24} /></div>}>
                        <RecipeCarousel recipes={relatedRecipes} loading={loadingRelated} />
                    </Suspense>

                    <div id="comments" className="detail-bottom-comments">
                        <Suspense fallback={null}>
                            <RecipeComments
                                recipe={recipe}
                                setRecipe={setRecipe}
                                user={user}
                                commentFormRef={commentFormRef}
                                commentRating={commentRating}
                                setCommentRating={setCommentRating}
                                showToast={showToast}
                                contentService={contentService}
                            />
                        </Suspense>
                    </div>

                    <div className="detail-report-row no-print">
                        <button className="detail-report-link" onClick={() => setIsReportModalOpen(true)}>
                            <Flag size={12} />
                            Rezept melden
                        </button>
                    </div>
                </div>
                
            </article>

            {
                isCookingModeOpen && (
                    <Suspense fallback={null}>
                        <CookingMode
                            recipe={recipe}
                            currentPortions={portions}
                            onClose={() => setIsCookingModeOpen(false)}
                        />
                    </Suspense>
                )
            }

            <RecipeDeleteModal
                isOpen={recipeToDelete}
                onClose={() => setRecipeToDelete(false)}
                onDelete={handleDelete}
                isDeleting={isDeleting}
            />
            <RecipePlannerModal
                isOpen={showPlannerModal}
                onClose={() => setShowPlannerModal(false)}
                plannerDay={plannerDay}
                setPlannerDay={setPlannerDay}
                plannerMeal={plannerMeal}
                setPlannerMeal={setPlannerMeal}
                onAdd={handleAddToMealPlan}
                isAdding={isAddingToPlan}
            />
            <RecipeTrackerModal
                isOpen={showTrackerModal}
                onClose={() => setShowTrackerModal(false)}
                trackerMealType={trackerMealType}
                setTrackerMealType={setTrackerMealType}
                deductFromPantry={deductFromPantry}
                setDeductFromPantry={setDeductFromPantry}
                matchCount={pantryMatchMap.matchCount}
                onLog={async () => {
                    setIsLoggingToTracker(true);
                    try {
                        let itemsToDeduct = [];
                        if (deductFromPantry) {
                            const multiplier = portions / (recipe.portions || 2);
                            let raw = recipe.recipeIngredients || [];
                            if (raw.length === 0 && recipe.ingredients && recipe.ingredients.length > 0) {
                                raw = recipe.ingredients.map(ing => ({ rawText: ing }));
                            }
                            itemsToDeduct = raw
                                .filter(ing => !isIngredientGroupHeader(ing.rawText || ing))
                                .map(ing => {
                                    if (ing.parsedName) {
                                        const scaledQty = ing.parsedQuantity ? (ing.parsedQuantity * multiplier) : '';
                                        return `${scaledQty ? formatIngredientAmount(scaledQty) : ''} ${pluralizeUnit(ing.parsedUnit, scaledQty)} ${ing.parsedName} ${ing.descriptors || ''}`.replace(/\\s+/g, ' ').trim();
                                    } else {
                                        return scaleIngredientString(ing.rawText || ing, multiplier);
                                    }
                                });
                        }
                        
                        await logMealAndDeduct(
                            { recipeId: recipe.id, meal: trackerMealType },
                            itemsToDeduct
                        );
                        setShowTrackerModal(false);
                    } catch (err) {
                        console.error('Tracker log error:', err);
                    } finally {
                        setIsLoggingToTracker(false);
                    }
                }}
                isLogging={isLoggingToTracker}
            />
            <RecipeReportModal
                isOpen={isReportModalOpen}
                onClose={() => setIsReportModalOpen(false)}
                reportReason={reportReason}
                setReportReason={setReportReason}
                reportComment={reportComment}
                setReportComment={setReportComment}
                onSubmit={handleReportSubmit}
                isReporting={isReporting}
            />
            <RecipeShareModal
                isOpen={showShareModal}
                onClose={() => setShowShareModal(false)}
                onShareToNetwork={handleShareToNetwork}
                onShareLink={handleShareLink}
                networkUsers={networkUsers}
                isSharing={isSharingToUser}
                loadingNetwork={loadingNetwork}
            />
        </div>
            </PullToRefresh>
        </>
    );
}

