import { ChangeDetectorRef, Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core';
import { ModalHelper, _HttpClient } from '@delon/theme';
import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area';
import { G2PieClickItem, G2PieComponent, G2PieData } from '@delon/chart/pie';
import { format } from 'date-fns';
import { DataService } from '../../services/data.service';
import { Chart, registerShape, Util } from '@antv/g2';
import { G2TimelineClickItem, G2TimelineData } from '@delon/chart/timeline';
import { CurrencyPipe } from '@angular/common';
import { LOGS } from '_mock';
import { G2CustomComponent } from '@delon/chart/custom';
import { G2BarData } from '@delon/chart/bar';
import { GeometryLabelCfg } from '@antv/g2/lib/interface';

@Component({
  selector: 'app-datatable-dataindex',
  templateUrl: './dataindex.component.html',
  styleUrls: ['./dataindex.component.less'],
  providers: [CurrencyPipe]
})
export class DatatableDataindexComponent implements OnInit {
  @ViewChild('g2custom', { static: false }) g2custom!: G2CustomComponent;
  @ViewChild('RegionalPerforman', { static: false }) RegionalPerforman!: G2CustomComponent;
  @ViewChild('BillDirectProportion', { static: false }) BillDirectProportion!: G2CustomComponent;
  @ViewChild('SaleProportion', { static: false }) SaleProportion!: G2CustomComponent;
  salesData: any[] = [];

  totalAdvanceDeposit: { totalAmount: string; list: G2MiniAreaData[] } = { totalAmount: '0', list: this.genData() };
  totalPerformanceVolume: { totalAmount: string; list: G2MiniAreaData[] } = { totalAmount: '0', list: this.genData() };
  totalFreight: { totalAmount: string; list: G2MiniAreaData[] } = { totalAmount: '0', list: this.genData() };
  totalSurcharge: { totalAmount: string; list: G2MiniAreaData[] } = { totalAmount: '0', list: this.genData() };

  billTypeDatas: any = [
    { item: '货源单', count: 0, percent: 0 },
    { item: '合同单', count: 0, percent: 0 }
  ];

  regionalPerformanceCompletion: DataPerformanceTrendVO[] = [];

  constructor(private service: DataService, private currency: CurrencyPipe) {}

  ngOnInit(): void {
    this.initMiniAreaData();
    this.initOthersData();
  }

  private initMiniAreaData() {
    // 客户预存款总额
    this.service.request(this.service.$api_total_advance_deposit).subscribe((res: DataTotalVO) => {
      if (res) {
        this.totalAdvanceDeposit = this.formatMiniAreaData(res);
      }
    });
    // 业绩量总额
    this.service.request(this.service.$api_total_performance_volume).subscribe((res: DataTotalVO) => {
      if (res) {
        this.totalPerformanceVolume = this.formatMiniAreaData(res);
      }
    });
    // 司机应付总额
    this.service.request(this.service.$api_total_freight).subscribe((res: DataTotalVO) => {
      if (res) {
        this.totalFreight = this.formatMiniAreaData(res);
      }
    });
    // 业绩量总额
    this.service.request(this.service.$api_total_surcharge).subscribe((res: DataTotalVO) => {
      if (res) {
        this.totalSurcharge = this.formatMiniAreaData(res);
      }
    });
  }

  private initOthersData() {
    // 订单类型比例
    this.service.request(this.service.$api_getBillTypeProportion).subscribe(res => {
      if (res) {
        this.billTypeDatas = this.formatCoordinateData(res);
        this.initBillChart(this.g2custom['el'].nativeElement as any);
      }
    });
    // 大区业绩完成情况
    this.service.request(this.service.$api_getBillAmount).subscribe((res: DataPerformanceTrendVO[]) => {
      if (res) {
        // this.regionalPerformanceCompletion = res.map(item => ({ ...item, time: new Date(item.time)?.getTime() }));
        // this.initRegionalPerformanceChart(this.RegionalPerforman['el'].nativeElement as any, this.regionalPerformanceCompletion);
        this.regionalPerformanceCompletion = this.formatBarData(res);
        this.initBiaxialChart(this.RegionalPerforman['el'].nativeElement as any, this.regionalPerformanceCompletion, {
          y1Title: '业绩量(万)',
          y2Title: '业绩完成率',
          y3Title: '同期业绩完成率'
        });
      }
    });
    // 订单类型比例
    this.service.request(this.service.$api_getWayBillDirectProportion).subscribe(res => {
      if (res) {
        const billTypeDatas = this.formatCoordinateData(res.map((item: any) => ({ ...item, billType: item.wayBillType })));
        this.initBillChart(this.BillDirectProportion['el'].nativeElement as any, billTypeDatas);
      }
    });
    // 统计订单结算金额-趋势
    this.service.request(this.service.$api_get_bill_payment_amount).subscribe(res => {
      if (res) {
        this.salesData = this.formatBarData(res);
        this.initBiaxialChart(this.SaleProportion['el'].nativeElement as any, this.salesData, {
          y1Title: '业绩量(万)',
          y2Title: '业绩完成率',
          y3Title: '同期业绩完成率'
        });
      }
    });
  }

  handleClick(data: G2MiniAreaClickItem): void {
    this.service.msgSrv.info(`${data.item.x} - ${data.item.y}`);
  }

  /**
   * 构建订单类型秘鲁图
   * @param el
   */
  private initBillChart(el: HTMLElement, datas?: any[]): void {
    const data = datas || this.billTypeDatas;

    const chart = new Chart({
      container: el,
      autoFit: true,
      height: 380
    });
    // 新建一个 view 用来单独渲染Annotation
    const innerView = chart.createView();
    chart.coordinate('theta', {
      radius: 0.65,
      innerRadius: 0.6
    });

    chart.data(data);

    chart.scale('percent', {
      formatter: val => {
        val = val * 100 + '%';
        return val;
      }
    });

    chart.tooltip(false);

    // 声明需要进行自定义图例字段： 'item'
    chart.legend('item', {
      position: 'bottom', // 配置图例显示位置
      custom: true, // 关键字段，告诉 G2，要使用自定义的图例
      items: data.map((obj: any, index: any) => {
        return {
          name: obj.item, // 对应 itemName
          value: obj.percent, // 对应 itemValue
          marker: {
            symbol: 'circle', // marker 的形状
            style: {
              r: 5, // marker 图形半径
              fill: index === 0 ? '#E60012' : '#F09896' // marker 颜色，使用默认颜色，同图形对应
            }
          } // marker 配置
        };
      }),
      itemValue: {
        style: {
          fill: '#999'
        }, // 配置 itemValue 样式
        formatter: (val: any) => `${val * 100}%` // 格式化 itemValue 内容
      }
    });

    chart
      .interval()
      .adjust('stack')
      .position('percent')
      .color('item', ['#E60012', '#F09896'])
      .style({
        fillOpacity: 1,
        stroke: 'white',
        lineWidth: 8
      })
      .state({
        active: {
          style: element => {
            const shape = element.shape;
            return {
              lineWidth: 1,
              stroke: 'white',
              strokeOpacity: shape.attr('fillOpacity')
            };
          }
        }
      })
      .label('percent', percent => {
        return {
          content: data => {
            return ` ${percent * 100}%`;
          },
          style: { fontSize: 14 }
        };
      });

    innerView
      .annotation()
      .text({
        position: ['50%', '50%'],
        content: data[0].item,
        style: {
          fontSize: 14,
          fill: '#8c8c8c',
          textAlign: 'center'
        },
        offsetY: -10
      })
      .text({
        position: ['50%', '50%'],
        content: data[0].count,
        style: {
          fontSize: 16,
          fill: '##000',
          textAlign: 'center'
        },
        offsetY: 10
      });
    innerView.render(true);

    // 移除图例点击过滤交互
    chart.removeInteraction('legend-filter');
    chart.interaction('element-active');

    chart.render();

    // 监听 element 上状态的变化来动态更新 Annotation 信息
    chart.on('element:statechange', (ev: any) => {
      const { state, stateStatus, element } = ev.gEvent.originalEvent;

      // 本示例只需要监听 active 的状态变化
      if (state === 'active') {
        const data = element.getData();
        if (stateStatus) {
          // 更新 Annotation
          updateAnnotation(data);
        } else {
          // 隐藏 Annotation
          // clearAnnotation();
        }
      }
    });

    // 绘制 annotation
    let lastItem: any;
    function updateAnnotation(data: any) {
      if (data.item !== lastItem) {
        innerView.annotation().clear(true);
        innerView
          .annotation()
          .text({
            position: ['50%', '50%'],
            content: data.item,
            style: {
              fontSize: 14,
              fill: '#8c8c8c',
              textAlign: 'center'
            },
            offsetY: -10
          })
          .text({
            position: ['50%', '50%'],
            content: data.count,
            style: {
              fontSize: 16,
              fill: '##000',
              textAlign: 'center'
            },
            offsetY: 10
          });
        innerView.render(true);
        lastItem = data.item;
      }
    }

    // 清空 annotation
    function clearAnnotation() {
      innerView.annotation().clear(true);
      innerView.render(true);
      lastItem = null;
    }
  }

  /**
   * 构建面积图
   * @param el
   */
  private initAreaMap(el: HTMLElement, datas: any[]): void {
    const chart = new Chart({
      container: el,
      autoFit: true,
      height: 500
    });
    chart.data(datas);
    chart.scale('Data', {
      range: [0, 1],
      tickCount: 10,
      type: 'timeCat'
    });
    chart.scale('sales', {
      nice: true
    });
    chart.axis('Data', false);
    chart.axis('sales', false);
    chart.tooltip({
      showCrosshairs: true
    });

    // chart.annotation().dataMarker({
    //   position: ['2014-01', 1750],
    //   top: true,
    //   text: {
    //     content: '因政策调整导致销量下滑',
    //     style: {
    //       fontSize: 13
    //     }
    //   },
    //   line: {
    //     length: 30
    //   }
    // });

    chart.line().position('Data*sales');
    chart.area().position('Data*sales');
    chart.render();
  }

  /**
   * 构建大区业绩完成情况柱折双轴图
   * @param el
   * @param data
   */
  private initRegionalPerformanceChart(el: HTMLElement, data: DataPerformanceTrendVO[]) {
    const chart = new Chart({
      container: el,
      autoFit: true,
      height: 400
    });

    chart.data(data);
    chart.scale({
      time: {
        alias: '日期',
        type: 'time'
      },
      quantity: {
        alias: '金额',
        min: 0,
        sync: true, // 将 pv 字段数值同 time 字段数值进行同步
        nice: true
      }
    });

    chart.axis('quantity', {
      title: {}
    });

    chart.tooltip({
      showCrosshairs: true,
      shared: true
    });

    // 声明需要进行自定义图例字段： 'item'
    chart.legend({
      title: { text: '1111', spacing: 11 },
      offsetY: 10,
      position: 'bottom', // 配置图例显示位置
      custom: true, // 关键字段，告诉 G2，要使用自定义的图例
      items: [
        {
          name: '订单金额 （元）', // 对应 itemName
          value: '' // 对应 itemValue
        }
      ],
      itemValue: {
        style: {
          fill: '#999'
        } // 配置 itemValue 样式
      }
    });

    chart.line().position('time*quantity').color('#4FAAEB');
    chart.render();
  }

  /**
   * 构建业绩完成情况柱折双轴图
   * @param el
   * @param data
   */
  private initBiaxialChart(
    el: HTMLElement,
    data: any[],
    { y1Title, y2Title, y3Title }: { y1Title: string; y2Title: string; y3Title: string }
  ) {
    const chart = new Chart({
      container: el,
      autoFit: true,
      height: 380
    });
    chart.data(data);
    // 设置坐标轴
    chart.scale({
      y1: { alias: y1Title, min: 0, max: 1000000 },
      y2: { alias: y2Title, min: 0, max: 1, formatter: val => (val * 100).toFixed(0) + '%' },
      y3: { alias: y3Title, min: 0, max: 1, formatter: val => (val * 100).toFixed(0) + '%' }
    });
    // 设置
    chart.legend({
      custom: true,
      position: 'top-right',
      padding: [10, 0, 40, 0],
      items: [
        { value: 'y1', name: y1Title, marker: { symbol: 'circle', style: { fill: '#E60012', r: 5, fontSize: 13 } } },
        { value: 'y3', name: y3Title, marker: { symbol: 'circle', style: { fill: '#6CBFFF', r: 5, fontSize: 13 } } },
        { value: 'y2', name: y2Title, marker: { symbol: 'circle', style: { fill: '#50D4AB', r: 5, fontSize: 13 } } }
      ]
    });
    chart.axis('y2', {
      grid: null,
      title: null,
      label: {
        formatter: val => val
      }
    });
    chart.axis('y3', false);
    chart.tooltip({
      shared: true
    });
    chart.interval().position('x*y1').color('#E60012');
    chart
      .line()
      .position('x*y2')
      // .label('pre', val => ({ content: (val * 100).toFixed(0) + '%' }))
      .color('#6CBFFF')
      .size(3);
    chart.point().position('x*y2').color('#6CBFFF').size(3).shape('circle');
    chart
      .line()
      .position('x*y3')
      // .label('pre2', val => ({ content: (val * 100).toFixed(0) + '%' }))
      .color('#50D4AB')
      .size(3);
    chart.point().position('x*y3').color('#50D4AB').size(3).shape('circle');

    chart.interaction('active-region');
    chart.removeInteraction('legend-filter'); // 自定义图例，移除默认的分类图例筛选交互
    chart.render();
  }

  private formatMiniAreaData(data: DataTotalVO) {
    return {
      totalAmount: `${this.currency.transform(data.totalAmount || 0)}万`,
      list: data.list?.map(item => ({
        x: item.time,
        y: item.quantity
      }))
    };
  }

  /**
   * 初始化饼图数据格式
   * @param data
   * @returns
   */
  private formatCoordinateData(data: DataBillTypeProportion[]): any[] {
    const total = data.map(item => item.quantity).reduce((pre, next) => pre + next);
    const rs: any[] = [];
    data.forEach(item => {
      rs.push({
        item: (BILLTYPE as any)[item.billType],
        count: item.quantity,
        percent: Number((item.quantity / total).toFixed(2))
      });
    });
    return rs;
  }

  private formatBarData(data: DataPerformanceTrendVO[]): any[] {
    return data.map(item => ({
      x: item.time,
      y1: item.quantity,
      y2: Math.floor(Math.random() * 100) / 100,
      y3: Math.floor(Math.random() * 100) / 100
    }));
  }

  private genData(): G2MiniAreaData[] {
    const beginDay = new Date().getTime();
    const res: G2MiniAreaData[] = [];
    for (let i = 0; i < 20; i += 1) {
      res.push({
        x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'),
        y: Math.floor(Math.random() * 1)
      });
    }
    return res;
  }
}

interface DataTotalVO {
  totalAmount: number;
  list: DataPerformanceTrendVO[];
}

interface DataPerformanceTrendVO {
  quantity: number;
  time: number;
}

interface DataBillTypeProportion {
  billType: BILLTYPE;
  quantity: number;
}

enum BILLTYPE {
  'HY' = '货源单',
  'HT' = '合同单',
  'ZF' = '直付',
  'CDZ' = '车队长'
}
