import { ChartDataSectionType } from 'app/constants';
import Chart from 'app/models/Chart';
import {
  ChartConfig,

} from 'app/types/ChartConfig';
import ChartDataSetDTO, {
} from 'app/types/ChartDataSet';
import { BrokerContext, BrokerOption } from 'app/types/ChartLifecycleBroker';
import {
  toFormattedValue,

  transformToDataSet,
} from 'app/utils/chartHelper';
import Config from './config';

import VChart from '@visactor/vchart';
import type { ISpec } from '@visactor/vchart/esm/typings';

class MetricChart extends Chart {
  config = Config;
  chart: any = null;

  constructor(props?) {
    super(
      props?.id || 'metricChart',
      props?.name || 'viz.palette.graph.names.metricChart',
      props?.icon || 'chartpie',
    );
  }

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

    // @ts-ignore
    const spec = this.getVChartSpec(options.dataset,options.config)
    this.chart = new VChart(spec,{dom:context.document.getElementById(options.containerId)!})
  }

  onUpdated(options: BrokerOption, context: BrokerContext) {
    if (!options.dataset || !options.dataset.columns || !options.config) {
      return;
    }
    if (!this.isMatchRequirement(options.config)) {
      this.chart?.release();
      this.chart = null; // 释放后置空
      return;
    }

    const spec = this.getVChartSpec(options.dataset, options.config) as ISpec;
    this.updateSpec(spec)
    this.chart?.renderSync();
  }

  onUnMount(options: BrokerOption, context: BrokerContext) {
    this.chart?.release();
    this.chart = null

  }

  private async updateSpec(spec:ISpec) {
    try {
      await this.chart?.updateSpec?.(spec);
    }catch(error) {
      console.error('Failed to update sankey chart:', error);
    }
  }

  private getVChartSpec(
    dataset: ChartDataSetDTO,
    config: ChartConfig,
  ):ISpec {
    console.log('dataset',dataset)
    console.log('config',config)
    const up = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDQ4IDQ4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00MC45OTk5IDI3LjAwMDVWMTUuMDAwNUgyOSIgc3Ryb2tlPSIjZTkxZDFkIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik02IDM3TDE2LjMzODUgMjQuNUwyNi4xODQ2IDMwLjVMNDEgMTUiIHN0cm9rZT0iI2U5MWQxZCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4='
    const down = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDQ4IDQ4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0yOSAzNC45OTk5SDQxVjIzIiBzdHJva2U9IiM3ZWQzMjEiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggZD0iTTYgMTNMMTYuMzM4NSAyNS41TDI2LjE4NDYgMTkuNUw0MSAzNSIgc3Ryb2tlPSIjN2VkMzIxIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg=='
    const rich:any =(text,type)=> {
      return {
        type: 'rich',
        text: [
          {
            text,
            fontWeight: 'bold',
            fontStyle: 'italic'
          },
          { image: type?up:down, width: 40, height: 40 },
        ]
      };
    }

    const columns = dataset?.columns || [];
    const data = this.getVChartData(dataset,config);
    const dataConfigs = config.datas || [];
    const aggregateConfigs = dataConfigs
      .filter(c => c.type === ChartDataSectionType.Aggregate)
      .flatMap(config => config.rows || []);
    console.log('columns',columns)
    const indicator = columns.map((item,index)=>{
      const value = toFormattedValue(data[0][index]);
      const { format,alias } = aggregateConfigs[index];
      const font = config.styles?.find((item) => item.key === 'commonTitle');
      const fontSizeOne = font?.rows?.find((item) => item.key === 'fontSizeOne')?.value
        ||font?.rows?.find((item) => item.key === 'fontSizeOne')?.default;
      const fontSizeTwo = font?.rows?.find((item) => item.key === 'fontSizeTwo')?.value
        ||font?.rows?.find((item) => item.key === 'fontSizeTwo')?.default;
      const labelSize = font?.rows?.find((item) => item.key === 'labelSize')?.value
        ||font?.rows?.find((item) => item.key === 'labelSize')?.default;
      const dxConfig = font?.rows?.find((item) => item.key === 'dx')?.value
        ||font?.rows?.find((item) => item.key === 'dx')?.default;
      const dyConfig = font?.rows?.find((item) => item.key === 'dy')?.value
        ||font?.rows?.find((item) => item.key === 'dy')?.default;
      const dx = index===0?-dxConfig: index%2===0 ? 0: -dxConfig;
      const dy = index===0 ?-dyConfig: Math.ceil(index/2)*dyConfig;
      const leftShift = font?.rows?.find((item) => item.key === 'leftShift')?.value
        ||font?.rows?.find((item) => item.key === 'leftShift')?.default;
      return {
        regionId: 'indicator',
        visible: true,
        title: {
          style: {
            text: toFormattedValue(value,format),
            dx: dx+leftShift,
            dy: dy,
            fontSize: index===0 ?fontSizeOne:fontSizeTwo,
            fontWeight: 800,
            textAlign: 'left',
          }
        },
        content: {
          style: {
            text: rich(alias?.name?alias?.name:item.name,Number(value)>=0),
            dx: dx+leftShift,
            dy: dy,
            fill: '#AAA',
            fontSize: labelSize,
            fontWeight: 600,
            textAlign: 'left'
          }
        }
      }
    })

    return  {
      type: 'common',
      layout: {
        type: 'grid',
        col: 1,
        row: 1,
        elements: [
          {
            modelId: 'indicator',
            col: 0,
            row: 0
          }
        ]
      },
      region: [
        {
          id: 'indicator'
        }
      ],
      indicator
    };
  }

  private getVChartData(
    dataset: ChartDataSetDTO,
    config: ChartConfig,
  ){
    const dataConfigs = config.datas || [];

    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,
    );

    return chartDataSet?.map((row) => aggregateConfigs.concat(infoConfigs).map(row.getCell, row));
  }


}


export default MetricChart;
