import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
// packages/ui/src/components/cookie-consent/CookieConsent.tsx
import { Cookie, Settings, Shield, BarChart3, Target } from 'lucide-react';
import { useState, useEffect, useRef } from 'react';
import { Accordion, Button, BUTTON_VARIANT, Card, Switch, Text, cn, Stack, } from '@donotdev/components';
import { handleError, useConsent, getCookieExamples, hasOptionalCookies as checkHasOptionalCookies, } from '@donotdev/core';
import { CONSENT_CATEGORY, } from '@donotdev/core';
import { useTranslation } from '@donotdev/core';
import { isClient } from '@donotdev/core';
function CookieConsent({ position = 'bottom', showBranding = true, brandingText = 'Powered by DoNotDev Framework', className = '', }) {
    const hasConsented = useConsent('hasConsented');
    const categories = useConsent('categories');
    const acceptAll = useConsent('acceptAll');
    const declineAll = useConsent('declineAll');
    const updateCategory = useConsent('updateCategory');
    const storeShowBanner = useConsent('showBanner');
    const { t } = useTranslation('cookies');
    const [showPreferences, setShowPreferences] = useState(false);
    const [showBanner, setShowBanner] = useState(!hasConsented || storeShowBanner);
    const [preferenceCategories, setPreferenceCategories] = useState(categories);
    const bannerRef = useRef(null);
    useEffect(() => {
        if (storeShowBanner) {
            setShowBanner(true);
        }
    }, [storeShowBanner]);
    // Get categories that are actually required by the app's features
    // Store only includes categories that are needed (from featureMatrix or requiredCookies config)
    const requiredCategories = Object.keys(categories);
    const categoryDefs = [
        {
            id: CONSENT_CATEGORY.NECESSARY,
            icon: Shield,
            title: t('essentialCookies'),
            description: t('essentialDescription'),
            examples: getCookieExamples('necessary') || t('essentialExamples'),
            locked: true,
        },
        {
            id: CONSENT_CATEGORY.FUNCTIONAL,
            icon: Cookie,
            title: t('functionalCookies'),
            description: t('functionalDescription'),
            examples: getCookieExamples('functional') || t('functionalExamples'),
            legalNotice: t('functionalLegalNotice'),
            locked: false,
        },
        {
            id: CONSENT_CATEGORY.ANALYTICS,
            icon: BarChart3,
            title: t('analyticsCookies'),
            description: t('analyticsDescription'),
            examples: getCookieExamples('analytics') || t('analyticsExamples'),
            locked: false,
        },
        {
            id: CONSENT_CATEGORY.MARKETING,
            icon: Target,
            title: t('marketingCookies'),
            description: t('marketingDescription'),
            examples: getCookieExamples('marketing') || t('marketingExamples'),
            locked: false,
        },
    ].filter((cat) => requiredCategories.includes(cat.id));
    // Check if app has optional categories based on detected features
    const hasOptionalCategories = checkHasOptionalCookies();
    // Auto-accept if only necessary cookies (GDPR/CCPA compliant - necessary cookies don't need consent)
    useEffect(() => {
        if (!hasConsented && !hasOptionalCategories) {
            acceptAll(); // Accepts only necessary cookies, show notice instead of banner
        }
    }, [hasConsented, hasOptionalCategories, acceptAll]);
    // Sync local draft state with store when categories change
    // Default all optional categories to ON for better UX (easier to uncheck than check all)
    useEffect(() => {
        const defaultedCategories = { ...categories };
        // Default all optional categories to true if accordion is open and they're undefined
        if (showPreferences) {
            // Use Record type assertion for mutable access to union type
            const mutableCategories = defaultedCategories;
            Object.keys(mutableCategories).forEach((cat) => {
                if (cat !== CONSENT_CATEGORY.NECESSARY &&
                    mutableCategories[cat] === false) {
                    mutableCategories[cat] = true;
                }
            });
        }
        setPreferenceCategories(defaultedCategories);
    }, [categories, showPreferences]);
    // Track if banner was dismissed without consent
    useEffect(() => {
        if (!isClient() || hasConsented || !showBanner)
            return;
        const handleClickOutside = (event) => {
            if (bannerRef.current &&
                !bannerRef.current.contains(event.target)) {
                setShowBanner(false);
            }
        };
        const timeoutId = setTimeout(() => {
            document.addEventListener('mousedown', handleClickOutside);
        }, 100);
        return () => {
            clearTimeout(timeoutId);
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, [hasConsented, showBanner]);
    if (hasConsented && !storeShowBanner)
        return null;
    const handleSave = () => {
        try {
            Object.entries(preferenceCategories).forEach(([cat, val]) => {
                if (cat !== CONSENT_CATEGORY.NECESSARY && val !== undefined) {
                    const categoryKey = cat;
                    // Check if category value exists in CONSENT_CATEGORY values (not keys)
                    if (Object.values(CONSENT_CATEGORY).includes(categoryKey)) {
                        updateCategory(categoryKey, Boolean(val));
                    }
                }
            });
            setShowPreferences(false);
            setShowBanner(false);
        }
        catch (error) {
            handleError(error, {
                userMessage: 'Error saving preferences',
                context: { operation: 'save_preferences' },
                severity: 'warning',
                log: true,
                reportToSentry: false,
                showNotification: false,
            });
        }
    };
    const handleAcceptAll = () => {
        acceptAll();
        setShowBanner(false);
    };
    const handleDeclineAll = () => {
        declineAll();
        setShowBanner(false);
    };
    const bannerContent = (_jsxs(Stack, { children: [_jsx(Text, { as: "p", variant: "muted", level: "small", children: t('cookieBannerDescription') }), hasOptionalCategories && (_jsx(Accordion, { type: "single", collapsible: true, value: showPreferences ? 'preferences' : '', onValueChange: (value) => setShowPreferences(value === 'preferences'), items: [
                    {
                        value: 'preferences',
                        trigger: (_jsxs(Stack, { direction: "row", align: "center", gap: "tight", children: [_jsx(Settings, { className: "dndev-size-md" }), t('customize')] })),
                        content: (_jsx(Stack, { children: categoryDefs.map((cat) => {
                                const Icon = cat.icon;
                                const enabled = preferenceCategories[cat.id] ?? false;
                                return (_jsx(Card, { content: _jsxs(Stack, { direction: "row", align: "center", justify: "between", children: [_jsxs(Stack, { direction: "row", align: "start", gap: "tight", style: { flex: 1 }, children: [_jsx(Icon, { className: "dndev-size-md", style: {
                                                            color: 'var(--primary)',
                                                            marginTop: '0.125rem',
                                                        } }), _jsxs(Stack, { gap: "tight", children: [_jsx(Text, { as: "span", level: "body", style: { fontWeight: 600 }, children: cat.title }), _jsx(Text, { as: "span", variant: "muted", level: "small", children: cat.description }), cat.examples && (_jsx(Text, { as: "span", variant: "muted", level: "small", style: { fontStyle: 'italic' }, children: cat.examples }))] })] }), cat.locked ? (_jsx(Text, { as: "span", variant: "muted", level: "small", children: t('alwaysOn') })) : (_jsx(Switch, { checked: enabled, onCheckedChange: (val) => setPreferenceCategories((prev) => ({
                                                    ...prev,
                                                    [cat.id]: val,
                                                })) }))] }) }, cat.id));
                            }) })),
                    },
                ] }))] }));
    const bannerFooter = showPreferences ? (_jsxs(Stack, { direction: "row", gap: "tight", style: { width: '100%' }, children: [_jsx(Button, { onClick: handleSave, variant: BUTTON_VARIANT.DEFAULT, style: { flex: 1 }, children: t('savePreferences', 'Save Preferences') }), _jsx(Button, { onClick: () => setShowPreferences(false), variant: BUTTON_VARIANT.OUTLINE, style: { flex: 1 }, children: t('form.cancel', 'Cancel') })] })) : (_jsxs(Stack, { direction: "row", gap: "tight", style: { width: '100%' }, children: [_jsx(Button, { onClick: handleAcceptAll, variant: BUTTON_VARIANT.DEFAULT, style: { flex: 1 }, children: t('acceptAll') }), hasOptionalCategories && (_jsx(Button, { onClick: handleDeclineAll, variant: BUTTON_VARIANT.OUTLINE, style: { flex: 1 }, children: t('declineOptional') }))] }));
    return (_jsxs(_Fragment, { children: [showBanner && (_jsx(Card, { ref: bannerRef, className: cn('dndev-fixed dndev-z-modal', className), icon: Cookie, title: t('cookiePreferences'), content: bannerContent, footer: bannerFooter, style: {
                    [position === 'top' ? 'top' : 'bottom']: 'var(--gap-md)',
                    insetInlineStart: 'var(--gap-md)',
                    insetInlineEnd: 'var(--gap-md)',
                    maxWidth: '100%',
                    width: 'calc(100% - var(--gap-md) * 2)',
                } })), !showBanner && !hasConsented && (_jsx(Button, { onClick: () => setShowBanner(true), className: "dndev-fixed dndev-z-toast", style: { bottom: 'var(--gap-md)', insetInlineStart: 'var(--gap-md)' }, icon: Cookie, title: t('cookiePreferences') }))] }));
}
export default CookieConsent;
