window.dashExtensions = Object.assign({}, window.dashExtensions, {
    default: {
        function0: function(feature, latlng, context) {
                return L.marker(latlng);
            }

            ,
        function1: function(feature, latlng) {
                const iconData = feature.properties.icon_data;
                const flag = L.icon({
                    iconUrl: iconData.url,
                    iconSize: [35, 35],
                    tooltipAnchor: [20, 0]
                });
                const marker = L.marker(latlng, {
                    icon: flag
                });
                marker.bindTooltip('<img src="' + feature.properties.image + '" style="width: 30vw; height: 20vh; max-width: 250px; max-height: 250px;">');
                marker.on('click', function(e) {
                    var event = new CustomEvent('marker_click', {
                        detail: feature.properties.pk
                    });
                    window.dispatchEvent(event);
                });
                return marker;
            }

            ,
        function2: function(feature, latlng, index, context) {
                function ringSVG(opt) {
                    function describeArc(opt) {
                        const innerStart = polarToCartesian(opt.x, opt.y, opt.radius, opt.endAngle);
                        const innerEnd = polarToCartesian(opt.x, opt.y, opt.radius, opt.startAngle);
                        const outerStart = polarToCartesian(opt.x, opt.y, opt.radius + opt.ringThickness, opt.endAngle);
                        const outerEnd = polarToCartesian(opt.x, opt.y, opt.radius + opt.ringThickness, opt.startAngle);
                        const largeArcFlag = opt.endAngle - opt.startAngle <= 180 ? "0" : "1";
                        return ["M", outerStart.x, outerStart.y,
                            "A", opt.radius + opt.ringThickness, opt.radius + opt.ringThickness, 0, largeArcFlag, 0, outerEnd.x, outerEnd.y,
                            "L", innerEnd.x, innerEnd.y,
                            "A", opt.radius, opt.radius, 0, largeArcFlag, 1, innerStart.x, innerStart.y,
                            "L", outerStart.x, outerStart.y, "Z"
                        ].join(" ");
                    }

                    const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
                        return {
                            x: centerX + (radius * Math.cos((angleInDegrees - 90) * Math.PI / 180.0)),
                            y: centerY + (radius * Math.sin((angleInDegrees - 90) * Math.PI / 180.0))
                        };
                    }

                    opt = opt || {};
                    const defaults = {
                        width: 60,
                        height: 60,
                        radius: 20,
                        gapDeg: 5,
                        fontSize: 17,
                        text: `test`,
                        ringThickness: 7,
                        colors: []
                    };
                    opt = {
                        ...defaults,
                        ...opt
                    };

                    let startAngle = 90;
                    let paths = '';
                    const totalPerc = opt.colors.reduce((acc, val) => acc + val.perc, 0);
                    for (let i = 0; i < opt.colors.length; i++) {
                        const segmentPerc = opt.colors[i].perc / totalPerc;
                        const endAngle = startAngle + (segmentPerc * 360) - opt.gapDeg;
                        const d = describeArc({
                            x: opt.width / 2,
                            y: opt.height / 2,
                            radius: opt.radius,
                            ringThickness: opt.ringThickness,
                            startAngle,
                            endAngle
                        });
                        paths += `<path fill="${opt.colors[i].color}" d="${d}"></path>`;
                        startAngle = endAngle + opt.gapDeg;
                    }

                    console.log("SVG Paths: ", paths);

                    return `<svg width="${opt.width}" height="${opt.height}">
                    ${paths}
                    <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle" font-size="${opt.fontSize}"
                          fill="black">${opt.text || opt.goodPerc}
                    </text>
                </svg>`;
                }

                const leaves = index.getLeaves(feature.properties.cluster_id);
                const m_types = leaves.map(leaf => leaf.properties.type);

                const m_type_counts = m_types.reduce((acc, m_type) => {
                    acc[m_type] = (acc[m_type] || 0) + 1;
                    return acc;
                }, {});

                const colors = Object.keys(m_type_counts).map(m_type => ({
                    color: context.hideout.m_type_colors[m_type] || 'gray',
                    perc: m_type_counts[m_type]
                }));

                const scatterIcon = L.DivIcon.extend({
                    createIcon: function(oldIcon) {
                        let icon = L.DivIcon.prototype.createIcon.call(this, oldIcon);
                        return icon;
                    }
                });

                const total = feature.properties.point_count_abbreviated;

                const icon = new scatterIcon({
                    html: ringSVG({
                        text: `${total}`,
                        colors
                    }),
                    className: "marker-cluster",
                    iconSize: L.point(40, 40)
                });
                return L.marker(latlng, {
                    icon: icon
                });
            }

            ,
        function3: function(feature, latlng, context) {
            const p = feature.properties || {};
            const defaultRadius = 10; // Default radius value
            const defaultColor = '#3388ff'; // Default color (Leaflet's default blue)
            const color = p.color || defaultColor; // Use color from properties if available, otherwise use default

            const options = {
                color: color,
                fillColor: color,
                fillOpacity: 0.2,
                weight: 3
            };

            switch (feature.geometry.type) {
                case 'Point':
                    if (p.type === 'circlemarker') {
                        const radius = p._radius || defaultRadius;
                        return L.circleMarker(latlng, {
                            ...options,
                            radius: radius
                        });
                    } else if (p.type === 'circle') {
                        const radius = p._mRadius || defaultRadius;
                        return L.circle(latlng, {
                            ...options,
                            radius: radius
                        });
                    } else {
                        return L.marker(latlng);
                    }
                case 'LineString':
                    return L.polyline(feature.geometry.coordinates.map(c => [c[1], c[0]]), options);
                case 'Polygon':
                    return L.polygon(feature.geometry.coordinates[0].map(c => [c[1], c[0]]), options);
                default:
                    console.log('Unsupported geometry type:', feature.geometry.type);
                    return L.marker(latlng);
            }
        }
    }
});