/**
 * Datart
 *
 * Copyright 2021
 *
 * Licensed 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.
 */


import Chart from 'app/models/Chart';
import { ChartSelectionManager } from 'app/models/ChartSelectionManager';
import { BrokerContext, BrokerOption } from 'app/types/ChartLifecycleBroker';
import Config from './config';
import { init } from 'echarts';
import ChartDataSetDTO, { IChartDataSet } from '../../../types/ChartDataSet';
import { ChartConfig, ChartDataSectionField, ChartStyleConfig, SelectedItem } from '../../../types/ChartConfig';
import { ChartDrillOption } from '../../../models/ChartDrillOption';
import {
  getDrillableRows,
  transformToDataSet,
} from '../../../utils/chartHelper';
import { ChartDataSectionType } from '../../../constants';
import { SankeyConfig, SankeyData, SankeyLinks, SankeyNodes } from './types';


class BasicSankeyChart extends Chart {
  config = Config;
  chart: any = null;
  selectionManager?: ChartSelectionManager;

  protected isCircle = false;
  protected isRose = false;

  constructor(props?) {
    super(
      props?.id || 'snakey',
      props?.name || 'viz.palette.graph.names.pieChart',
      props?.icon || 'chartpie',
    );
    this.meta.requirements = props?.requirements || [
      { group: [0, 1], aggregate: [1, 999] },
    ];
  }

  onMount(options: BrokerOption, context: BrokerContext) {
    if (
      options.containerId === undefined ||
      !context.document ||
      !context.window
    ) {
      return;
    }

    this.chart = init(
      context.document.getElementById(options.containerId)!,
      'default',
    );
    this.selectionManager = new ChartSelectionManager(this.mouseEvents);
    this.selectionManager.attachWindowListeners(context.window);
    this.selectionManager.attachZRenderListeners(this.chart);
    this.selectionManager.attachEChartsListeners(this.chart);
  }

  onUpdated(options: BrokerOption, context: BrokerContext) {
    if (!options.dataset || !options.dataset.columns || !options.config) {
      return;
    }
    if (!this.isMatchRequirement(options.config)) {
      // 清空当前实例，会移除实例中所有的组件和图表。
      this.chart?.clear();
      return;
    }
    this.selectionManager?.updateSelectedItems(options?.selectedItems);
    this.chart?.hideLoading();
    const newOptions = this.getOptions(
      options.dataset,
      options.config,
      options.drillOption,
      options.selectedItems,
    )
    this.chart?.setOption(Object.assign({}, newOptions), true);
  }

  // ECharts
  onUnMount(options: BrokerOption, context: BrokerContext) {
    this.selectionManager?.removeWindowListeners(context.window);
    this.selectionManager?.removeZRenderListeners(this.chart);
    this.chart?.dispose();
  }

  onResize(options: BrokerOption, context: BrokerContext) {
    this.chart?.resize(context);
  }

  private getOptions(
    dataset: ChartDataSetDTO,
    config: ChartConfig,
    drillOption?: ChartDrillOption,
    selectedItems?: SelectedItem[],
  ) {
    const styleConfigs = config.styles || [];
    const dataConfigs = config.datas || [];
    const groupConfigs: ChartDataSectionField[] = getDrillableRows(
      dataConfigs,
      drillOption,
    );
    const aggregateConfigs = dataConfigs
      .filter(c => c.type === ChartDataSectionType.Aggregate)
      .flatMap(config => config.rows || []);
    const infoConfigs = dataConfigs
      .filter(c => c.type === ChartDataSectionType.Info)
      .flatMap(config => config.rows || []);

    // const chartDataSet = transformToDataSet(
    //   dataset.rows,
    //   dataset.columns,
    //   dataConfigs,
    // );
    const fields = (dataConfigs || []).flatMap(config => config.rows || []);

    const datasetFormat = this.transformToSankey(dataset);
    const chartDataSet:SankeyData = {
      "nodes": [
        {
          "name": "Agricultural 'waste'"
        },
        {
          "name": "Bio-conversion"
        },
        {
          "name": "Liquid"
        },
        {
          "name": "Losses"
        },
        {
          "name": "Solid"
        },
        {
          "name": "Gas"
        },
        {
          "name": "Biofuel imports"
        },
        {
          "name": "Biomass imports"
        },
        {
          "name": "Coal imports"
        },
        {
          "name": "Coal"
        },
        {
          "name": "Coal reserves"
        },
        {
          "name": "District heating"
        },
        {
          "name": "Industry"
        },
        {
          "name": "Heating and cooling - commercial"
        },
        {
          "name": "Heating and cooling - homes"
        },
        {
          "name": "Electricity grid"
        },
        {
          "name": "Over generation / exports"
        },
        {
          "name": "H2 conversion"
        },
        {
          "name": "Road transport"
        },
        {
          "name": "Agriculture"
        },
        {
          "name": "Rail transport"
        },
        {
          "name": "Lighting & appliances - commercial"
        },
        {
          "name": "Lighting & appliances - homes"
        },
        {
          "name": "Gas imports"
        },
        {
          "name": "Ngas"
        },
        {
          "name": "Gas reserves"
        },
        {
          "name": "Thermal generation"
        },
        {
          "name": "Geothermal"
        },
        {
          "name": "H2"
        },
        {
          "name": "Hydro"
        },
        {
          "name": "International shipping"
        },
        {
          "name": "Domestic aviation"
        },
        {
          "name": "International aviation"
        },
        {
          "name": "National navigation"
        },
        {
          "name": "Marine algae"
        },
        {
          "name": "Nuclear"
        },
        {
          "name": "Oil imports"
        },
        {
          "name": "Oil"
        },
        {
          "name": "Oil reserves"
        },
        {
          "name": "Other waste"
        },
        {
          "name": "Pumped heat"
        },
        {
          "name": "Solar PV"
        },
        {
          "name": "Solar Thermal"
        },
        {
          "name": "Solar"
        },
        {
          "name": "Tidal"
        },
        {
          "name": "UK land based bioenergy"
        },
        {
          "name": "Wave"
        },
        {
          "name": "Wind"
        }
      ],
      "links": [
        {
          "source": "Agricultural 'waste'",
          "target": "Bio-conversion",
          "value": 124.729
        },
        {
          "source": "Bio-conversion",
          "target": "Liquid",
          "value": 0.597
        },
        {
          "source": "Bio-conversion",
          "target": "Losses",
          "value": 26.862
        },
        {
          "source": "Bio-conversion",
          "target": "Solid",
          "value": 280.322
        },
        {
          "source": "Bio-conversion",
          "target": "Gas",
          "value": 81.144
        },
        {
          "source": "Biofuel imports",
          "target": "Liquid",
          "value": 35
        },
        {
          "source": "Biomass imports",
          "target": "Solid",
          "value": 35
        },
        {
          "source": "Coal imports",
          "target": "Coal",
          "value": 11.606
        },
        {
          "source": "Coal reserves",
          "target": "Coal",
          "value": 63.965
        },
        {
          "source": "Coal",
          "target": "Solid",
          "value": 75.571
        },
        {
          "source": "District heating",
          "target": "Industry",
          "value": 10.639
        },
        {
          "source": "District heating",
          "target": "Heating and cooling - commercial",
          "value": 22.505
        },
        {
          "source": "District heating",
          "target": "Heating and cooling - homes",
          "value": 46.184
        },
        {
          "source": "Electricity grid",
          "target": "Over generation / exports",
          "value": 104.453
        },
        {
          "source": "Electricity grid",
          "target": "Heating and cooling - homes",
          "value": 113.726
        },
        {
          "source": "Electricity grid",
          "target": "H2 conversion",
          "value": 27.14
        },
        {
          "source": "Electricity grid",
          "target": "Industry",
          "value": 342.165
        },
        {
          "source": "Electricity grid",
          "target": "Road transport",
          "value": 37.797
        },
        {
          "source": "Electricity grid",
          "target": "Agriculture",
          "value": 4.412
        },
        {
          "source": "Electricity grid",
          "target": "Heating and cooling - commercial",
          "value": 40.858
        },
        {
          "source": "Electricity grid",
          "target": "Losses",
          "value": 56.691
        },
        {
          "source": "Electricity grid",
          "target": "Rail transport",
          "value": 7.863
        },
        {
          "source": "Electricity grid",
          "target": "Lighting & appliances - commercial",
          "value": 90.008
        },
        {
          "source": "Electricity grid",
          "target": "Lighting & appliances - homes",
          "value": 93.494
        },
        {
          "source": "Gas imports",
          "target": "Ngas",
          "value": 40.719
        },
        {
          "source": "Gas reserves",
          "target": "Ngas",
          "value": 82.233
        },
        {
          "source": "Gas",
          "target": "Heating and cooling - commercial",
          "value": 0.129
        },
        {
          "source": "Gas",
          "target": "Losses",
          "value": 1.401
        },
        {
          "source": "Gas",
          "target": "Thermal generation",
          "value": 151.891
        },
        {
          "source": "Gas",
          "target": "Agriculture",
          "value": 2.096
        },
        {
          "source": "Gas",
          "target": "Industry",
          "value": 48.58
        },
        {
          "source": "Geothermal",
          "target": "Electricity grid",
          "value": 7.013
        },
        {
          "source": "H2 conversion",
          "target": "H2",
          "value": 20.897
        },
        {
          "source": "H2 conversion",
          "target": "Losses",
          "value": 6.242
        },
        {
          "source": "H2",
          "target": "Road transport",
          "value": 20.897
        },
        {
          "source": "Hydro",
          "target": "Electricity grid",
          "value": 6.995
        },
        {
          "source": "Liquid",
          "target": "Industry",
          "value": 121.066
        },
        {
          "source": "Liquid",
          "target": "International shipping",
          "value": 128.69
        },
        {
          "source": "Liquid",
          "target": "Road transport",
          "value": 135.835
        },
        {
          "source": "Liquid",
          "target": "Domestic aviation",
          "value": 14.458
        },
        {
          "source": "Liquid",
          "target": "International aviation",
          "value": 206.267
        },
        {
          "source": "Liquid",
          "target": "Agriculture",
          "value": 3.64
        },
        {
          "source": "Liquid",
          "target": "National navigation",
          "value": 33.218
        },
        {
          "source": "Liquid",
          "target": "Rail transport",
          "value": 4.413
        },
        {
          "source": "Marine algae",
          "target": "Bio-conversion",
          "value": 4.375
        },
        {
          "source": "Ngas",
          "target": "Gas",
          "value": 122.952
        },
        {
          "source": "Nuclear",
          "target": "Thermal generation",
          "value": 839.978
        },
        {
          "source": "Oil imports",
          "target": "Oil",
          "value": 504.287
        },
        {
          "source": "Oil reserves",
          "target": "Oil",
          "value": 107.703
        },
        {
          "source": "Oil",
          "target": "Liquid",
          "value": 611.99
        },
        {
          "source": "Other waste",
          "target": "Solid",
          "value": 56.587
        },
        {
          "source": "Other waste",
          "target": "Bio-conversion",
          "value": 77.81
        },
        {
          "source": "Pumped heat",
          "target": "Heating and cooling - homes",
          "value": 193.026
        },
        {
          "source": "Pumped heat",
          "target": "Heating and cooling - commercial",
          "value": 70.672
        },
        {
          "source": "Solar PV",
          "target": "Electricity grid",
          "value": 59.901
        },
        {
          "source": "Solar Thermal",
          "target": "Heating and cooling - homes",
          "value": 19.263
        },
        {
          "source": "Solar",
          "target": "Solar Thermal",
          "value": 19.263
        },
        {
          "source": "Solar",
          "target": "Solar PV",
          "value": 59.901
        },
        {
          "source": "Solid",
          "target": "Agriculture",
          "value": 0.882
        },
        {
          "source": "Solid",
          "target": "Thermal generation",
          "value": 400.12
        },
        {
          "source": "Solid",
          "target": "Industry",
          "value": 46.477
        },
        {
          "source": "Thermal generation",
          "target": "Electricity grid",
          "value": 525.531
        },
        {
          "source": "Thermal generation",
          "target": "Losses",
          "value": 787.129
        },
        {
          "source": "Thermal generation",
          "target": "District heating",
          "value": 79.329
        },
        {
          "source": "Tidal",
          "target": "Electricity grid",
          "value": 9.452
        },
        {
          "source": "UK land based bioenergy",
          "target": "Bio-conversion",
          "value": 182.01
        },
        {
          "source": "Wave",
          "target": "Electricity grid",
          "value": 19.013
        },
        {
          "source": "Wind",
          "target": "Electricity grid",
          "value": 289.366
        }
      ]
    }
    const chartDataSet2:SankeyData = {
      nodes: [
        { name: "Agricultural 'waste'" },
        { name: 'Bio-conversion' },
        { name: 'Liquid' },
        { name: 'Losses' },
        { name: 'Solid' },
        { name: 'Gas' },
        { name: 'Biofuel imports' },
        { name: 'Biomass imports' },
        { name: 'Coal imports' },
        { name: 'Coal' },
        { name: 'Coal reserves' },
        { name: 'District heating' },
        { name: 'Industry' },
        { name: 'Heating and cooling - commercial' },
        { name: 'Heating and cooling - homes' },
        { name: 'Electricity grid' },
        { name: 'Over generation / exports' },
        { name: 'H2 conversion' },
        { name: 'Road transport' },
        { name: 'Agriculture' },
        { name: 'Rail transport' },
        { name: 'Lighting & appliances - commercial' },
        { name: 'Lighting & appliances - homes' },
        { name: 'Gas imports' },
        { name: 'Ngas' },
        { name: 'Gas reserves' },
        { name: 'Thermal generation' },
        { name: 'Geothermal' },
        { name: 'H2' },
        { name: 'Hydro' },
        { name: 'International shipping' },
        { name: 'Domestic aviation' },
        { name: 'International aviation' },
        { name: 'National navigation' },
        { name: 'Marine algae' },
        { name: 'Nuclear' },
        { name: 'Oil imports' },
        { name: 'Oil' },
        { name: 'Oil reserves' },
        { name: 'Other waste' },
        { name: 'Pumped heat' },
        { name: 'Solar PV' },
        { name: 'Solar Thermal' },
        { name: 'Solar' },
        { name: 'Tidal' },
        { name: 'UK land based bioenergy' },
        { name: 'Wave' },
        { name: 'Wind' }
      ],
      links: [
        { source: 0, target: 1, value: 124.729 },
        { source: 1, target: 2, value: 0.597 },
        { source: 1, target: 3, value: 26.862 },
        { source: 1, target: 4, value: 280.322 },
        { source: 1, target: 5, value: 81.144 },
        { source: 6, target: 2, value: 35 },
        { source: 7, target: 4, value: 35 },
        { source: 8, target: 9, value: 11.606 },
        { source: 10, target: 9, value: 63.965 },
        { source: 9, target: 4, value: 75.571 },
        { source: 11, target: 12, value: 10.639 },
        { source: 11, target: 13, value: 22.505 },
        { source: 11, target: 14, value: 46.184 },
        { source: 15, target: 16, value: 104.453 },
        { source: 15, target: 14, value: 113.726 },
        { source: 15, target: 17, value: 27.14 },
        { source: 15, target: 12, value: 342.165 },
        { source: 15, target: 18, value: 37.797 },
        { source: 15, target: 19, value: 4.412 },
        { source: 15, target: 13, value: 40.858 },
        { source: 15, target: 3, value: 56.691 },
        { source: 15, target: 20, value: 7.863 },
        { source: 15, target: 21, value: 90.008 },
        { source: 15, target: 22, value: 93.494 },
        { source: 23, target: 24, value: 40.719 },
        { source: 25, target: 24, value: 82.233 },
        { source: 5, target: 13, value: 0.129 },
        { source: 5, target: 3, value: 1.401 },
        { source: 5, target: 26, value: 151.891 },
        { source: 5, target: 19, value: 2.096 },
        { source: 5, target: 12, value: 48.58 },
        { source: 27, target: 15, value: 7.013 },
        { source: 17, target: 28, value: 20.897 },
        { source: 17, target: 3, value: 6.242 },
        { source: 28, target: 18, value: 20.897 },
        { source: 29, target: 15, value: 6.995 },
        { source: 2, target: 12, value: 121.066 },
        { source: 2, target: 30, value: 128.69 },
        { source: 2, target: 18, value: 135.835 },
        { source: 2, target: 31, value: 14.458 },
        { source: 2, target: 32, value: 206.267 },
        { source: 2, target: 19, value: 3.64 },
        { source: 2, target: 33, value: 33.218 },
        { source: 2, target: 20, value: 4.413 },
        { source: 34, target: 1, value: 4.375 },
        { source: 24, target: 5, value: 122.952 },
        { source: 35, target: 26, value: 839.978 },
        { source: 36, target: 37, value: 504.287 },
        { source: 38, target: 37, value: 107.703 },
        { source: 37, target: 2, value: 611.99 },
        { source: 39, target: 4, value: 56.587 },
        { source: 39, target: 1, value: 77.81 },
        { source: 40, target: 14, value: 193.026 },
        { source: 40, target: 13, value: 70.672 },
        { source: 41, target: 15, value: 59.901 },
        { source: 42, target: 14, value: 19.263 },
        { source: 43, target: 42, value: 19.263 },
        { source: 43, target: 41, value: 59.901 },
        { source: 4, target: 19, value: 0.882 },
        { source: 4, target: 26, value: 400.12 },
        { source: 4, target: 12, value: 46.477 },
        { source: 26, target: 15, value: 525.531 },
        { source: 26, target: 3, value: 787.129 },
        { source: 26, target: 11, value: 79.329 },
        { source: 44, target: 15, value: 9.452 },
        { source: 45, target: 1, value: 182.01 },
        { source: 46, target: 15, value: 19.013 },
        { source: 47, target: 15, value: 289.366 }
      ]
    }
    console.log(datasetFormat)
    const series = this.getSeries(
      styleConfigs,
      datasetFormat,
      groupConfigs,
      aggregateConfigs,
      infoConfigs,
      selectedItems,
    );

    return { series };
  }

  private transformToSankey(
    dataset: ChartDataSetDTO,
  ):SankeyData{
    const {columns,rows} = dataset;
    console.log(columns)
    console.log(rows)

    let sankeyNodes:SankeyNodes[] = [];
    const addedNodes = {};
    (rows||[]).forEach((row) => {
      const region = row[0];
      const product = row[1];
      if (!addedNodes[region]) {
        sankeyNodes.push({name: region});
        addedNodes[region] = true;
      }
      if (!addedNodes[product]) {
        sankeyNodes.push({name: product});
        addedNodes[product] = true;
      }
    });

    let sankeyLinks: SankeyLinks[] = [];
    (rows||[]).forEach((row) => {
      const region = row[0];
      const product = row[1];
      const value = row[2];
      sankeyLinks.push({source: region, target: product, value});
    });

    return {
      nodes:sankeyNodes,
      links:sankeyLinks
    }
  }

  private getSeries(
    styleConfigs: ChartStyleConfig[],
    chartDataSet: SankeyData,
    groupConfigs: ChartDataSectionField[],
    aggregateConfigs: ChartDataSectionField[],
    infoConfigs: ChartDataSectionField[],
    selectedItems?: SelectedItem[],
  ): SankeyConfig[] {
    return [
      {
        type: 'sankey',
        data: chartDataSet.nodes,
        links:chartDataSet.links,
        emphasis: {
          focus: 'adjacency'
        },
        lineStyle: {
          color: 'gradient',
          curveness: 0.5
        }
      }
    ];
  }

}

export default BasicSankeyChart;
