/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/* eslint-disable no-param-reassign */
/* eslint-disable react/sort-prop-types */
import d3 from 'd3';
import PropTypes from 'prop-types';
import { sankey as d3Sankey } from 'd3-sankey';
import { getNumberFormatter, NumberFormats, CategoricalColorNamespace } from '@superset-ui/core';

const propTypes = {
  data: PropTypes.arrayOf(
    PropTypes.shape({
      source: PropTypes.string,
      target: PropTypes.string,
      value: PropTypes.number,
    }),
  ),
  width: PropTypes.number,
  height: PropTypes.number,
  colorScheme: PropTypes.string,
};

const formatNumber = getNumberFormatter(NumberFormats.FLOAT);

function Sankey(element, props) {
  const { data, width, height, colorScheme } = props;

  const div = d3.select(element);
  div.classed('superset-legacy-chart-sankey', true);
  const margin = {
    top: 5,
    right: 5,
    bottom: 5,
    left: 5,
  };
  const innerWidth = width - margin.left - margin.right;
  const innerHeight = height - margin.top - margin.bottom;

  div.selectAll('*').remove();
  const svg = div
    .append('svg')
    .attr('width', innerWidth + margin.left + margin.right)
    .attr('height', innerHeight + margin.top + margin.bottom)
    .append('g')
    .attr('transform', `translate(${margin.left},${margin.top})`);

  const tooltip = div.append('div').attr('class', 'sankey-tooltip').style('opacity', 0);

  const colorFn = CategoricalColorNamespace.getScale(colorScheme);

  const sankey = d3Sankey().nodeWidth(15).nodePadding(10).size([innerWidth, innerHeight]);

  const path = sankey.link();

  let nodes = {};
  // Compute the distinct nodes from the links.
  const links = data.map(row => {
    const link = { ...row };
    link.source = nodes[link.source] || (nodes[link.source] = { name: link.source });
    link.target = nodes[link.target] || (nodes[link.target] = { name: link.target });
    link.value = Number(link.value);

    return link;
  });
  nodes = d3.values(nodes);

  sankey.nodes(nodes).links(links).layout(32);

  function getTooltipHtml(d) {
    let html;

    if (d.sourceLinks) {
      // is node
      html = `${d.name} Value: <span class='emph'>${formatNumber(d.value)}</span>`;
    } else {
      const val = formatNumber(d.value);
      const sourcePercent = d3.round((d.value / d.source.value) * 100, 1);
      const targetPercent = d3.round((d.value / d.target.value) * 100, 1);

      html = [
        "<div class=''>Path Value: <span class='emph'>",
        val,
        '</span></div>',
        "<div class='percents'>",
        "<span class='emph'>",
        Number.isFinite(sourcePercent) ? sourcePercent : '100',
        '%</span> of ',
        d.source.name,
        '<br/>',
        `<span class='emph'>${Number.isFinite(targetPercent) ? targetPercent : '--'}%</span> of `,
        d.target.name,
        '</div>',
      ].join('');
    }

    return html;
  }

  function onmouseover(d) {
    tooltip
      .html(() => getTooltipHtml(d))
      .transition()
      .duration(200)
      .style('left', `${d3.event.offsetX + 10}px`)
      .style('top', `${d3.event.offsetY + 10}px`)
      .style('opacity', 0.95);
  }

  function onmouseout() {
    tooltip.transition().duration(100).style('opacity', 0);
  }

  const link = svg
    .append('g')
    .selectAll('.link')
    .data(links)
    .enter()
    .append('path')
    .attr('class', 'link')
    .attr('d', path)
    .style('stroke-width', d => Math.max(1, d.dy))
    .sort((a, b) => b.dy - a.dy)
    .on('mouseover', onmouseover)
    .on('mouseout', onmouseout);

  function dragmove(d) {
    d3.select(this).attr(
      'transform',
      `translate(${d.x},${(d.y = Math.max(0, Math.min(height - d.dy, d3.event.y)))})`,
    );
    sankey.relayout();
    link.attr('d', path);
  }

  const node = svg
    .append('g')
    .selectAll('.node')
    .data(nodes)
    .enter()
    .append('g')
    .attr('class', 'node')
    .attr('transform', d => `translate(${d.x},${d.y})`)
    .call(
      d3.behavior
        .drag()
        .origin(d => d)
        .on('dragstart', function dragStart() {
          this.parentNode.append(this);
        })
        .on('drag', dragmove),
    );
  const minRectHeight = 5;
  node
    .append('rect')
    .attr('height', d => (d.dy > minRectHeight ? d.dy : minRectHeight))
    .attr('width', sankey.nodeWidth())
    .style('fill', d => {
      const name = d.name || 'N/A';
      d.color = colorFn(name.replace(/ .*/, ''));

      return d.color;
    })
    .style('stroke', d => d3.rgb(d.color).darker(2))
    .on('mouseover', onmouseover)
    .on('mouseout', onmouseout);

  node
    .append('text')
    .attr('x', -6)
    .attr('y', d => d.dy / 2)
    .attr('dy', '.35em')
    .attr('text-anchor', 'end')
    .attr('transform', null)
    .text(d => d.name)
    .filter(d => d.x < innerWidth / 2)
    .attr('x', 6 + sankey.nodeWidth())
    .attr('text-anchor', 'start');
}

Sankey.displayName = 'Sankey';
Sankey.propTypes = propTypes;

export default Sankey;
