/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Dropdown, DropdownType, IconButton, IListItemProps, Shadows, Size, Type } from 'browndash-components';
import { action, untracked } from 'mobx';
import { extname } from 'path';
import * as React from 'react';
import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs';
import { FaFilter } from 'react-icons/fa';
import { ClientUtils, DashColor, lightOrDark } from '../../ClientUtils';
import { Doc, Opt, StrListCast } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
import { AudioAnnoState } from '../../server/SharedMediaTypes';
import { emptyPath } from '../../Utils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
import { IsFollowLinkScript } from '../documents/DocUtils';
import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from '../util/UndoManager';
import { TreeSort } from './collections/TreeSort';
import { Colors } from './global/globalEnums';
import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
import { FieldViewProps } from './nodes/FieldView';
import { StyleProp } from './StyleProp';
import './StyleProvider.scss';

function toggleLockedPosition(doc: Doc) {
    UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground');
}
function togglePaintView(e: React.MouseEvent, doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>) {
    const scriptProps = {
        this: doc,
        _readOnly_: false,
        documentView: props?.DocumentView?.(),
        value: undefined,
    };
    e.stopPropagation();
    ScriptCast(doc?.onPaint)?.script.run(scriptProps);
}

export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: number) {
    const style: { [key: string]: any } = {};
    const divKeys = ['width', 'height', 'fontSize', 'transform', 'left', 'backgroundColor', 'left', 'right', 'top', 'bottom', 'pointerEvents', 'position'];
    const replacer = (match: any, expr: string) =>
        // bcz: this executes a script to convert a property expression string:  { script }  into a value
        ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? '';
    divKeys.forEach((prop: string) => {
        const p = (props as any)[prop];
        typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
    });
    return style;
}

export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
    return `M ${pw * 0.5} ${ph * inset}   C ${pw * 0.6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset}   C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * 0.25} ${pw * (1 - inset)} ${ph * 0.3}   C ${
        pw * (1 - inset)
    } ${ph * 0.4} ${pw} ${ph * (1 - 2 * inset)} ${pw * (1 - inset)} ${ph * (1 - inset)}  C ${pw * (1 - 2 * inset)} ${ph} ${pw * 0.6} ${ph * (1 - inset)} ${pw * 0.5} ${ph * (1 - inset)}   C ${pw * 0.3} ${ph * (1 - inset)} ${pw * (2 * inset)} ${ph} ${
        pw * inset
    } ${ph * (1 - inset)}  C 0 ${ph * (1 - 2 * inset)} ${pw * inset} ${ph * 0.8} ${pw * inset} ${ph * 0.75}   C ${pw * inset} ${ph * 0.7} 0 ${ph * (2 * inset)} ${pw * inset} ${ph * inset}   C ${pw * (2 * inset)} 0 ${pw * 0.25} ${ph * inset} ${
        pw * 0.5
    } ${ph * inset}`;
}

let _filterOpener: () => void;
export function SetFilterOpener(func: () => void) {
    _filterOpener = func;
}

// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
//
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) {
    const remoteDocHeader = 'author;author_date;noMargin';
    const isCaption = property.includes(':caption');
    const isAnchor = property.includes(':anchor');
    const isNonTransparent = property.includes(':nonTransparent');
    const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent');
    const isAnnotated = property.includes(':annotated');
    const layoutDoc = doc ? Doc.Layout(doc) : doc;
    const isOpen = property.includes(':treeOpen');
    const boxBackground = property.includes(':docView'); // background color of docView's bounds can be different than the background of contents -- eg FontIconBox
    const {
        DocumentView: docView,
        fieldKey: fieldKeyProp,
        styleProvider,
        pointerEvents,
        isGroupActive,
        isDocumentActive,
        containerViewPath,
        childFilters,
        hideCaptions,
        showTitle,
        childFiltersByRanges,
        renderDepth,
        docViewPath,
        LayoutTemplateString,
        disableBrushing,
        NativeDimScaling,
        PanelWidth,
        PanelHeight,
        isSelected,
        isHovering,
    } = props || {}; // extract props that are not shared between fieldView and documentView props.
    const componentView = docView?.()?.ComponentView;
    const fieldKey = fieldKeyProp ? fieldKeyProp + '_' : isCaption ? 'caption_' : '';
    const isInk = () => layoutDoc?._layout_isSvg && !LayoutTemplateString;
    const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
    const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight);
    const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
    const color = () => styleProvider?.(doc, props, StyleProp.Color) as string;
    const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity);
    const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle) as string;
    // prettier-ignore
    switch (property.split(':')[0]) {
        case StyleProp.TreeViewIcon: {
            const img = ImageCast(doc?.icon ?? doc?.[doc ? Doc.LayoutFieldKey(doc) : ""]);
            if (img) {
                const ext = extname(img.url.href);
                const url = doc?.icon ? img.url.href : img.url.href.replace(ext, '_s' + ext);
                return <img src={url} width={20} height={15} style={{ margin: 'auto', display: 'block', objectFit: 'contain' }} />;
            }
            return Doc.toIcon(doc, isOpen);
        }
        case StyleProp.TreeViewSortings: {
            const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
            allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
            allSorts[TreeSort.AlphaUp] = { color: 'crimson', icon: <BsArrowUp/> };
            if (doc?._type_collection === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: 'green', icon: 'Z' };
            allSorts[TreeSort.WhenAdded] = { color: 'darkgray', icon: <BsArrowDownUp/> };
            return allSorts;
        }
        case StyleProp.Highlighting:
            if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;            
            if (doc && !doc.layout_disableBrushing && !disableBrushing) {
                const selected = DocumentView.getViews(doc).filter(dv => dv.IsSelected).length;
                const highlightIndex = Doc.GetBrushHighlightStatus(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
                const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
                const highlightStyle = ['solid', 'dashed', 'solid', 'solid', 'solid'][highlightIndex];
                if (highlightIndex) {
                    return {
                        highlightStyle: doc.isGroup ? "dotted": highlightStyle,
                        highlightColor,
                        highlightIndex,
                        highlightStroke: layoutDoc?.layout_isSvg,
                    };
                }
            }
            return  undefined;
        case StyleProp.DocContents:  return undefined;
        case StyleProp.WidgetColor:  return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
        case StyleProp.Opacity:      return componentView?.isUnstyledView?.() ? 1 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
        case StyleProp.FontColor:    return StrCast(doc?.[fieldKey + 'fontColor'],  isCaption ? lightOrDark(backgroundCol()) : StrCast(Doc.UserDoc().fontColor, color()));
        case StyleProp.FontSize:     return StrCast(doc?.[fieldKey + 'fontSize'],   StrCast(Doc.UserDoc().fontSize));
        case StyleProp.FontFamily:   return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
        case StyleProp.FontWeight:   return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
        case StyleProp.FillColor:    return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
        case StyleProp.ShowCaption:  return hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
        case StyleProp.TitleHeight:  return Math.min(4,(docView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
        case StyleProp.ShowTitle:    return (
                (doc &&
                    !componentView?.isUnstyledView?.() &&
                    !LayoutTemplateString &&
                    !doc.presentation_targetDoc &&
                    showTitle?.() !== '' &&
                    StrCast(
                        doc._layout_showTitle,
                        showTitle?.() ||
                            (!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as DocumentType)
                                ? doc.author === ClientUtils.CurrentUserEmail()
                                    ? StrCast(Doc.UserDoc().layout_showTitle)
                                    : remoteDocHeader
                                : '')
                    )) ||
                ''
            );
        case StyleProp.Color: {
            if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userBackgroundColor;
            if (Doc.IsSystem(doc!)) return SnappingManager.userColor;
            if (doc?.type === DocumentType.FONTICON) return SnappingManager.userColor;
            const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
            if (docColor) return docColor;
            const backColor = backgroundCol();
            return backColor ? lightOrDark(backColor) : undefined;
        }
        case StyleProp.BorderRounding: {
            const rounding = StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
            return (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc || doc?.isTemplateDoc) ? StrCast(doc._layout_borderRounding,rounding) : rounding;
        }
        case StyleProp.BorderPath: {
            const borderPath = Doc.IsComicStyle(doc) &&
                renderDepth &&
                !doc?.layout_isSvg && { path: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0), fill: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0, 0.08), width: 3 };
                return !borderPath
                    ? null
                    : {
                        clipPath: `path('${borderPath.path}')`,
                        jsx: (
                            <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
                                <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}>
                                    <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
                                </svg>
                            </div>
                        ),
                    };
        }
        case StyleProp.HeaderMargin:
            return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as CollectionViewType) ||
                (doc?.type === DocumentType.RTF && !layoutShowTitle()?.includes('noMargin')) ||
                doc?.type === DocumentType.LABEL) &&
                layoutShowTitle() &&
                !StrCast(doc?.layout_showTitle).includes(':hover')
                ? titleHeight()
                : 0;
        case StyleProp.BackgroundColor: {
            if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userColor; // hack to indicate active menu panel item
            const dataKey = doc ? Doc.LayoutFieldKey(doc) : "";
            const usePath = StrCast(doc?.[dataKey + "_usePath"]);
            const alternate = usePath.includes(":hover") ? ( isHovering?.() ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
            let docColor: Opt<string> = StrCast(doc?.[fieldKey+alternate], StrCast(doc?.['backgroundColor' +alternate], isCaption ? 'rgba(0,0,0,0.4)' : ''));
            if (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor)
            // prettier-ignore
            switch (layoutDoc?.type) {
                case DocumentType.PRESELEMENT: docColor = docColor || ""; break;
                case DocumentType.PRES:        docColor = docColor || 'transparent'; break;
                case DocumentType.FONTICON:    docColor = boxBackground ? undefined : docColor || Colors.DARK_GRAY; break;
                case DocumentType.RTF:         docColor = docColor || Colors.LIGHT_GRAY; break;
                case DocumentType.LINK:        docColor = (isAnchor ? docColor : undefined); break;
                case DocumentType.INK:         docColor = doc?.stroke_isInkMask ? 'rgba(0,0,0,0.7)' : undefined; break;
                case DocumentType.EQUATION:    docColor = docColor || 'transparent'; break;
                case DocumentType.LABEL:       docColor = docColor || Colors.LIGHT_GRAY; break;
                case DocumentType.BUTTON:      docColor = docColor || Colors.LIGHT_GRAY; break;
                case DocumentType.IMG:
                case DocumentType.WEB:
                case DocumentType.PDF:
                case DocumentType.MAP:
                case DocumentType.SCREENSHOT:
                case DocumentType.VID:         docColor = docColor || (Colors.LIGHT_GRAY); break;
                case DocumentType.COL:
                    docColor = docColor || (doc && Doc.IsSystem(doc)
                            ? SnappingManager.userBackgroundColor
                            : doc?.annotationOn
                            ? '#00000010' // faint interior for collections on PDFs, images, etc
                            : doc?.isGroup
                            ? undefined
                            : doc?._type_collection === CollectionViewType.Stacking ?
                            (Colors.DARK_GRAY)
                            : Cast((renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
                    break;
                // if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
                default: docColor = docColor || (Colors.WHITE);
            }
            if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && styleProvider) {
                return styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
            }
            return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor;
        }
        case StyleProp.BoxShadow: {
            if (!doc || opacity() === 0 || doc.noShadow) return undefined; // if it's not visible, then no shadow)
            if (doc.layout_boxShadow === 'standard') return Shadows.STANDARD_SHADOW;
            if (IsFollowLinkScript(doc?.onClick) && Doc.Links(doc).length && !layoutDoc?.layout_isSvg) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
            switch (doc?.type) {
                case DocumentType.COL:
                    return StrCast(
                        doc?.layout_boxShadow,
                        doc?._type_collection === CollectionViewType.Pile
                            ? '4px 4px 10px 2px'
                            : lockedPosition() || doc?.isGroup || LayoutTemplateString
                            ? undefined // groups have no drop shadow -- they're supposed to be "invisible".  LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
                            : `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
                    );

                case DocumentType.LABEL:
                    if (doc?.annotationOn !== undefined) return 'black 2px 2px 1px';
                // eslint-disable-next-line no-fallthrough
                default:
                    return doc.z
                        ? `#9c9396  ${StrCast(doc?.layout_boxShadow, '10px 10px 0.9vw')}` // if it's a floating doc, give it a big shadow
                        : containerViewPath?.().lastElement()?.Document._freeform_useClusters
                        ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
                        : NumCast(doc.group, -1) !== -1
                        ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
                        : lockedPosition()
                        ? undefined // if it's a background & has a cluster color, make the shadow spread really big
                        : fieldKey.includes('_inline')  // if doc is an inline document in a text box
                        ? `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0vw 0vw 0.1vw')}`
                        : DocCast(doc.embedContainer)?.type === DocumentType.RTF && !isInk() // if doc is embedded in a text document (but not an inline)
                        ? `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
                        : StrCast(doc.layout_boxShadow, '');
            }
        }
        case StyleProp.PointerEvents:
            if (componentView?.dontRegisterView?.()) return 'all';
            if (StrCast(doc?.pointerEvents)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
            if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
            if (pointerEvents?.() === 'none') return 'none';
            if (opacity() === 0) return 'none';
            if (isGroupActive?.() ) return isInk()  ? 'visiblePainted':  (doc?.
                isGroup )? undefined: 'all' 
            if (isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
            return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
        case StyleProp.Decorations: {
            const lock = () => doc?.pointerEvents !== 'none' ? null : (
                        <div className="styleProvider-lock" onClick={() => toggleLockedPosition(doc)}>
                            <FontAwesomeIcon icon='lock' size="lg" />
                        </div>
                    );
            const paint = () => !doc?.onPaint ? null : (
                        <div className={`styleProvider-paint${isSelected?.() ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
                            <FontAwesomeIcon icon='pen' size="lg" />
                        </div>
                    );
            const filter = () => {
                const dashView = untracked(() => DocumentView.getDocumentView(Doc.ActiveDashboard));
                const showFilterIcon =
                    StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length
                        ? 'green' // #18c718bd' //'hasFilter'
                        : childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f) && f !== ClientUtils.noDragDocsFilter).length || childFiltersByRanges?.().length
                        ? 'orange' // 'inheritsFilter'
                        : undefined;
                return !showFilterIcon ? null : (
                    <div className="styleProvider-filter">
                        <Dropdown
                            type={Type.TERT}
                            dropdownType={DropdownType.CLICK}
                            fillWidth
                            // eslint-disable-next-line react/no-unstable-nested-components
                            iconProvider={() => <div className='styleProvider-filterShift'><FaFilter/></div>}
                            closeOnSelect
                            setSelectedVal={((dv: DocumentView) => {
                                    dv.select(false);
                                    SnappingManager.SetPropertiesWidth(250);
                                    _filterOpener?.();
                                }) as any // Dropdown assumes values are strings or numbers.. 
                            }
                            size={Size.XSMALL}
                            width={15}
                            height={15}
                            title={showFilterIcon === 'green' ? 
                                "This view is filtered.  Click to view/change filters":
                                "this view inherits filters from one of its parents"}
                            color={SnappingManager.userColor}
                            background={showFilterIcon}
                            items={[ ...(dashView ? [dashView]: []), ...(docViewPath?.()??[])]
                                    .filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
                                    .map(dv => ({
                                text: StrCast(dv?.Document.title),
                                val: dv as any,
                                style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor},
                            } as IListItemProps)) }
                        />
                    </div>
                );
            };
            const audio = () => {
                const audioAnnoState = (audioDoc: Doc) => StrCast(audioDoc.audioAnnoState, AudioAnnoState.stopped);
                const audioAnnosCount = (audioDoc: Doc) => StrListCast(audioDoc[fieldKey + 'audioAnnotations']).length;
                if (!doc || renderDepth === -1 || !audioAnnosCount(doc)) return null;
                const audioIconColors: { [key: string]: string } = { playing: 'green', stopped: 'blue' };
                return (
                    <Tooltip title={<div>{StrListCast(doc[fieldKey + 'audioAnnotations_text']).lastElement()}</div>}>
                        <div className="styleProvider-audio" onPointerDown={() => DocumentView.getFirstDocumentView(doc)?.playAnnotation()}>
                            <FontAwesomeIcon className="documentView-audioFont" style={{ color: audioIconColors[audioAnnoState(doc)] }} icon='file-audio' size="sm" />
                        </div>
                    </Tooltip>
                );
            };
            return (
                <>
                    {paint()}
                    {lock()}
                    {filter()}
                    {audio()}
                </>
            );
        }
        default:
    }
}

export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) {
    const color = SnappingManager.userColor;
    return (
        <IconButton
            size={Size.XSMALL}
            color={color}
            icon={<FontAwesomeIcon icon={(doc[field] ? (onIcon as any) : offIcon) as IconProp} />}
            onClick={undoBatch(
                action((e: React.MouseEvent) => {
                    e.stopPropagation();
                    clickFunc ? clickFunc() : (doc[field] = doc[field] ? undefined : true);
                })
            )}
        />
    );
}
/**
 * add hide button decorations for the "Dashboards" flyout TreeView
 */
export function DashboardStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) {
    if (doc && property.split(':')[0] === StyleProp.Decorations) {
        return doc._type_collection === CollectionViewType.Docking || Doc.IsSystem(doc)
            ? null
            : DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => DocumentView.FocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.embedContainer ?? doc?.annotationOn)));
    }
    return DefaultStyleProvider(doc, props, property);
}

export function returnEmptyDocViewList() {
    return emptyPath;
}
