import d3 from 'd3';
import $ from 'jquery';
import each from 'lodash/each';

export function handleColorRange(colorRange) {

    return d3.scale.ordinal()
        .range(colorRange);
}

export function prepareTooltipContainer(id) {
    $('#' + id + '_tooltip').remove();

    return d3.select('body')
        .append('div')
        .attr('id', id + '_tooltip')
        .attr('class', 'widget-tooltip')
        .style('opacity', 0);
}

export function prepareTooltipColor(toolTipContainer) {
    return toolTipContainer.append('span')
        .attr('class', 'tooltip-legend-color');
}

export function prepareTooltipText(toolTipContainer) {
    return toolTipContainer.append('span')
        .attr('class', 'tooltip-text');
}

export function handleAscSort(a, b) {

    return a.value < b.value ? -1 : a.value > b.value ? 1 : a.value >= b.value ? 0 : NaN;
}

export function handleDescSort(a, b) {

    return b.value < a.value ? -1 : b.value > a.value ? 1 : b.value >= a.value ? 0 : NaN;
}

export function calculateValueSum(dataSet) {
    let valueSum = 0;

    each(dataSet, (dataEntry) => {
        valueSum += dataEntry.value;
    });

    return valueSum;
}

export function renderInnerArcLabels(props, labelElement, arc, valueSum) {
    const {
        startAngle,
        innerLabelColor,
        innerLabelSize,
        innerLabelType,
        decimals
    } = props;

    function angle(d) {
        const a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;

        return a > 90 ? a - 180 : a;
    }

    function handleRotation(d) {
        /* istanbul ignore if */
        if (d.startAngle < 0) {

            return 'rotate(' + (angle(d) + 2 * startAngle) + ')';
        }

        return 'rotate(' + (angle(d)) + ')';
    }

    labelElement.append('text')
        .attr('transform', (d) => {
            return 'translate(' + arc.centroid(d) + ')' + handleRotation(d);
        })
        .attr('fill', innerLabelColor)
        .attr('text-anchor', 'middle')
        .text((d) => {
            switch (innerLabelType.toLowerCase()) {
                case 'label': return d.data.value === 0 ? '' : d.data.label;
                case 'labelvalue': return d.data.value === 0 ? '' : d.data.label + ': ' + d.data.value;
                case 'percent': return d.data.value === 0 ? '' : (d.data.value * 100 / valueSum).toFixed(decimals) + ' %';
                case 'labelpercent': return d.data.value === 0 ? '' : d.data.label + ': ' + (d.data.value * 100 / valueSum).toFixed(decimals) + ' %';
                default: return d.data.value === 0 ? '' : d.data.value;
            }
        })
        .style('font-size', innerLabelSize);
}

export function renderOuterArcLabels(props, labelElement, arc, valueSum) {
    const {
        startAngle,
        endAngle,
        outerLabelColor,
        radius,
        showLabelLine,
        outerLabelOffset,
        outerLabelSize,
        labelLineColor,
        labelLineWidth,
        labelLineDotRadius,
        labelLineDotColor,
        showLabelLineDot,
        outerLabelType,
        decimals
    } = props;

    labelElement.append('text')
        .attr('transform', (d) => {
            const c = arc.centroid(d),
                x = c[0],
                y = c[1],
                h = Math.sqrt(x * x + y * y);

            return 'translate(' + (x / h * (radius + outerLabelOffset)) + ',' +
                (y / h * (radius + outerLabelOffset)) + ')';
        })
        .attr('fill', outerLabelColor)
        .attr('text-anchor', (d) => {
            /* istanbul ignore next */
            if (startAngle !== 0 && endAngle !== 360) {
                if (d.startAngle < Math.PI) {
                    if (d.startAngle < 0) {

                        return 'end';
                    }

                    return 'start';
                }

                return 'end';
            }

            return (d.endAngle + d.startAngle) / 2 > Math.PI ? 'end' : 'start';
        })
        .attr('dy', '.35em')
        .text((d) => {
            switch (outerLabelType.toLowerCase()) {
                case 'value': return d.data.value === 0 ? '' : d.data.value;
                case 'labelvalue': return d.data.value === 0 ? '' : d.data.label + ': ' + d.data.value;
                case 'percent': return d.data.value === 0 ? '' : (d.data.value * 100 / valueSum).toFixed(decimals) + ' %';
                case 'labelpercent': return d.data.value === 0 ? '' : d.data.label + ': ' + (d.data.value * 100 / valueSum).toFixed(decimals) + ' %';
                default: return d.data.value === 0 ? '' : d.data.label;
            }
        })
        .style('font-size', outerLabelSize);
    /* istanbul ignore else */
    if (showLabelLine) {
        labelElement.append('line')
            .attr('x1', (d) => {
                const c = arc.centroid(d);

                return c[0];
            })
            .attr('y1', (d) => {
                const c = arc.centroid(d);

                return c[1];
            })
            .attr('x2', (d) => {
                const c = arc.centroid(d),
                    x = c[0],
                    y = c[1],
                    h = Math.sqrt(x * x + y * y),
                    OFFSET = -5;

                return (x / h * (radius + OFFSET + outerLabelOffset));
            })
            .attr('y2', (d) => {
                const c = arc.centroid(d),
                    x = c[0],
                    y = c[1],
                    h = Math.sqrt(x * x + y * y);

                return (y / h * (radius + outerLabelOffset));
            })
            .style('stroke', labelLineColor)
            .style('stroke-width', labelLineWidth);

    }
    /* istanbul ignore else */
    if (showLabelLineDot) {
        labelElement.append('circle')
            .attr('cx', (d) => {
                const c = arc.centroid(d);

                return c[0];
            })
            .attr('cy', (d) => {
                const c = arc.centroid(d);

                return c[1];
            })
            .attr('r', () => {
                return labelLineDotRadius;
            })
            .attr('fill', labelLineDotColor);
    }
}

