export class SeriesMarkersPrimitive {
    constructor(markers) {
        this._markers = markers || [];
        this._paneViews = [new MarkersPaneView(this)];
    }
    
    setMarkers(markers) {
        this._markers = markers;
        if (this._requestUpdate) {
            this._requestUpdate();
        }
    }
    
    attached(param) {
        this._chart = param.chart;
        this._series = param.series;
        this._requestUpdate = param.requestUpdate;
        this._requestUpdate();
    }
    
    detached() {
        this._chart = undefined;
        this._series = undefined;
        this._requestUpdate = undefined;
    }
    
    updateAllViews() {}
    
    paneViews() {
        return this._paneViews;
    }
}

class MarkersPaneView {
    constructor(source) {
        this._source = source;
    }
    
    renderer() {
        return new MarkersRenderer(this._source);
    }
}

class MarkersRenderer {
    constructor(source) {
        this._source = source;
    }
    
    draw(target) {
        if (!this._source._chart || !this._source._series) return;
        
        // Lightweight Charts v5 wraps context
        const ctx = target.context;
        const series = this._source._series;
        const chart = this._source._chart;
        const markers = this._source._markers;
        
        ctx.save();
        
        // Ensure markers are sorted by time (usually already done)
        for (const marker of markers) {
            const timeCoordinate = chart.timeScale().timeToCoordinate(marker.time);
            if (timeCoordinate === null) continue;
            
            // To position above or below bar, we need the candle data or we use the marker.value if provided
            // For true aboveBar/belowBar without candle data, we might just use series.priceToCoordinate on marker.value
            let price = marker.value;
            // Fallbacks if no value provided (which our calculator does provide)
            if (!price) continue;
            
            const priceCoordinate = series.priceToCoordinate(price);
            if (priceCoordinate === null) continue;
            
            const x = timeCoordinate;
            const size = 5;
            const margin = 12; // Gap between price and marker
            const isAbove = marker.position === 'aboveBar';
            const y = isAbove ? priceCoordinate - margin : priceCoordinate + margin;
            
            ctx.fillStyle = marker.color || '#26a69a';
            ctx.beginPath();
            
            if (marker.shape === 'arrowUp' || (!marker.shape && !isAbove)) {
                ctx.moveTo(x, y - size);
                ctx.lineTo(x - size, y + size);
                ctx.lineTo(x + size, y + size);
            } else if (marker.shape === 'arrowDown' || (!marker.shape && isAbove)) {
                ctx.moveTo(x, y + size);
                ctx.lineTo(x - size, y - size);
                ctx.lineTo(x + size, y - size);
            } else if (marker.shape === 'circle') {
                ctx.arc(x, y, size, 0, Math.PI * 2);
            } else if (marker.shape === 'square') {
                ctx.rect(x - size, y - size, size * 2, size * 2);
            } else if (marker.shape === 'custom' && marker.text) {
                ctx.font = '12px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(marker.text, x, y);
                continue;
            } else {
                // Default triangle
                if (isAbove) {
                    ctx.moveTo(x, y + size);
                    ctx.lineTo(x - size, y - size);
                    ctx.lineTo(x + size, y - size);
                } else {
                    ctx.moveTo(x, y - size);
                    ctx.lineTo(x - size, y + size);
                    ctx.lineTo(x + size, y + size);
                }
            }
            ctx.fill();
        }
        ctx.restore();
    }
}
