import {
  PropType,
  computed,
  defineComponent,
  nextTick,
  onMounted,
  ref,
  toRefs,
  watch
} from 'vue';
import styles from '../index.module.less';
import icons from '../icons.json';
import { Badge, Icon, Image, Popover } from 'vant';
import * as echarts from 'echarts';
import { IMusicGradeDistribution } from '../type';
import icon_3 from '../image/icon_3.png';

type EChartsOption = echarts.EChartsOption;

const colors = [
  '134, 186, 255',
  '255, 219, 145',
  '133, 223, 207',

  '134, 186, 255',
  '255, 219, 145',
  '133, 223, 207',

  '134, 186, 255',
  '255, 219, 145',
  '133, 223, 207',

  '134, 186, 255',
  '255, 219, 145',
  '133, 223, 207'
];

export default defineComponent({
  name: 'MusicGroup',
  props: {
    data: {
      type: Array as PropType<IMusicGradeDistribution[]>,
      default: () => []
    }
  },
  setup(props) {
    const activeSubject = ref('');
    const echratsRef = ref();
    const { data } = toRefs(props);

    /** 根据声部 过滤数据源 */
    const list = computed(() => {
      // 初始化 声部
      if (!activeSubject.value) {
        activeSubject.value =
          data.value.find(item => item.subjectName)?.subjectName || '';
      }
      return data.value.filter(
        item => item.subjectName === activeSubject.value
      );
    });

    watch(
      () => list.value,
      () => {
        nextTick(() => {
          handleInit();
        });
      }
    );

    /** 乐团列表 */
    const musicGroups = computed(() => {
      const _list = Array.from(
        new Set(data.value.map(item => item.musicGroupName))
      );
      const obj: { [_key: string]: { text: string; color: string } } =
        _list.reduce(
          (
            obj: { [_key: string]: { text: string; color: string } },
            value: string,
            index: number
          ) => {
            obj[value] = {
              text: value,
              color: colors[index]
            };
            return obj;
          },
          {}
        );

      return obj;
    });

    /** 声部列表 */
    const subjects = computed(() => {
      const _names = Array.from(
        new Set(data.value.map(item => item.subjectName))
      ).filter(Boolean);
      return _names.map(n => {
        return {
          text: n
        };
      });
    });

    /** 年级列表 */
    const gradeList = computed(() => {
      return Array.from(new Set(data.value.map(item => item.grade))).reverse();
    });

    const filterData = (data: IMusicGradeDistribution[]) => {
      const musicGrade: {
        [_key: string]: { [_key: string]: IMusicGradeDistribution[] };
      } = {};
      for (let i = 0; i < data.length; i++) {
        const item = data[i];
        if (musicGrade[item.grade]) {
          // 年级有乐团
          if (musicGrade[item.grade][item.musicGroupName]) {
            musicGrade[item.grade][item.musicGroupName].push(item);
          } else {
            musicGrade[item.grade][item.musicGroupName] = [item];
          }
        } else {
          musicGrade[item.grade] = {};
          musicGrade[item.grade][item.musicGroupName] = [item];
        }
      }
      return musicGrade;
    };
    let myChart: echarts.ECharts;
    const handleInit = () => {
      if (!list.value.length) return;
      const musicGrade = filterData(list.value);
      // console.log('🚀 ~ musicGrade:', musicGrade);
      if (myChart) {
        myChart.dispose();
      }
      myChart = echarts.init(echratsRef.value);
      const option: EChartsOption = {
        grid: {
          left: 8,
          top: 5,
          right: 10,
          bottom: 5,
          containLabel: true
        },
        xAxis: {
          type: 'value',
          boundaryGap: [0, 0.01],
          minInterval: 1,
          splitLine: {
            lineStyle: {
              type: 'dashed',
              color: '#f2f2f2'
            }
          }
        },
        yAxis: {
          type: 'category',
          axisTick: {
            show: false
          },
          axisLabel: {
            color: '#777',
            fontSize: 10
          },
          axisLine: {
            lineStyle: {
              color: '#F2F2F2'
            }
          },
          data: gradeList.value
        },
        series: Object.values(musicGroups.value).map(group => {
          const _data = gradeList.value.map(grade => {
            const _list = musicGrade[grade]?.[group.text] || [];
            const total = _list.reduce(
              (_total, value) => (_total += value.studentNum),
              0
            );
            return total;
          });
          return {
            data: _data,
            type: 'bar',
            label: {
              show: true,
              position: 'right',
              color: '#777',
              formatter: _item => {
                return _item.value ? `${_item.value}` : '';
              }
            },
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                { offset: 0, color: `rgba(${group.color}, .5)` },
                { offset: 1, color: `rgba(${group.color}, 1)` }
              ])
            },
            barMaxWidth: 16
          };
        })
      };

      option && myChart.setOption(option);
    };

    return () => (
      <div class={styles.item}>
        <div class={styles.itemTop}>
          <Image class={styles.icon} src={icons[3]} />
          <div class={styles.title}>乐团年级分布</div>
          <div class={styles.des}>(单位：人)</div>
          <Popover
            class={styles.subjects}
            actions={subjects.value}
            placement="bottom-end"
            onSelect={value => {
              activeSubject.value = value.text;
            }}>
            {{
              reference: () => (
                <div>
                  {activeSubject.value}{' '}
                  <Icon name="arrow-down" color="rgba(216,216,216,1)" />
                </div>
              )
            }}
          </Popover>
        </div>
        <div
          style={{ display: data.value.length ? '' : 'none' }}
          class={styles.musicGroupContainer}>
          <div class={styles.musicGroupEcharts} ref={echratsRef}></div>
          <div
            class={styles.tags}
            onTouchmove={(e: Event) => e.stopPropagation()}
            onMousemove={(e: Event) => e.stopPropagation()}>
            {Object.values(musicGroups.value).map(item => (
              <div class={styles.tag}>
                <Badge
                  dot
                  color={`linear-gradient(180deg, rgba(${item.color}, .5) 0%, rgba(${item.color}, 1) 100%)`}
                />
                <div style={{ whiteSpace: 'nowrap' }}>{item.text}</div>
              </div>
            ))}
          </div>
        </div>

        {!list.value.length && (
          <div class={[styles.gradeContainer, styles.itemEmtry]}>
            <Image src={icon_3} />
          </div>
        )}
      </div>
    );
  }
});
