import { ganteRef, CATEGORIES } from "../../configuration/constants";
import { throttle } from '../../utils'

export default {
  // 组件名称
  name: ganteRef,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${ganteRef}" class="${ganteRef}"></div>
    `;
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${ganteRef} {
          position: absolute;
          min-width: 400px;
          min-height: 200px;
          width: 100%;
          height: 100%;
        }
        .${ganteRef} .gantt_task_line {
          border: 2px solid rgba(0,0,0,.1);
        }
        .${ganteRef} .gantt_task_line.gantt_task_inline_color .gantt_task_progress {
          background-color: #fff;
          opacity: .3;
        }
        
        .gantt_hor_scroll::-webkit-scrollbar, .gantt_ver_scroll::-webkit-scrollbar {
          width: 10px;
          height: 10px;
        }
        .gantt_hor_scroll::-webkit-scrollbar-thumb, .gantt_ver_scroll::-webkit-scrollbar-thumb {
          -webkit-border-radius: 10px;
          border-radius: 10px;
          background-color: rgba(0,0,0,.2);
        }
        .gantt_hor_scroll::-webkit-scrollbar-thumb:hover, .gantt_ver_scroll::-webkit-scrollbar-thumb:hover {
          background-color: rgba(0,0,0,.1);
        }
        .gantt_hor_scroll::-webkit-scrollbar-track, .gantt_ver_scroll::-webkit-scrollbar-track {
          background-color: rgba(0,0,0,.1);
        }
      </style>
    `;
  },

  // 编辑器右侧块管理器中显示属性配置
  blockOptions() {
    return {
      category: CATEGORIES.ECHARTS,
      label: `
        <svg class="gjs-block-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1474"><path d="M1022 480.3V303.8c0-6.5-5.3-11.8-11.8-11.8H456.1c-6.5 0-11.8-5.3-11.8-11.8V137.9c0-6.5-5.3-11.8-11.8-11.8H313.8c-6.5 0-11.8-5.3-11.8-11.8V63.8c0-6.5-5.3-11.8-11.8-11.8H13.8C7.3 52.1 2 57.3 2 63.8v176.5c0 6.5 5.3 11.8 11.8 11.8h276.5c6.5 0 11.8-5.3 11.8-11.8v-50.5c0-6.5 5.3-11.8 11.8-11.8h66.7c6.5 0 11.8 5.3 11.8 11.8v90.4c0 6.5-5.3 11.8-11.8 11.8h-66.7c-6.5 0-11.8 5.3-11.8 11.8v176.5c0 6.5 5.3 11.8 11.8 11.8h66.7c6.5 0 11.8 5.3 11.8 11.8v16.4c0 6.5-5.3 11.8-11.8 11.8h-66.7c-6.5 0-11.8 5.3-11.8 11.8v176.5c0 6.5 5.3 11.8 11.8 11.8h276.5c6.5 0 11.8-5.3 11.8-11.8v-50.5c0-6.5 5.3-11.8 11.8-11.8h66.7c6.5 0 11.8 5.3 11.8 11.8v90.4c0 6.5-5.3 11.8-11.8 11.8H614c-6.5 0-11.8 5.3-11.8 11.8v176.5c0 6.5 5.3 11.8 11.8 11.8h376.5c6.5 0 11.8-5.3 11.8-11.8V783.7c0-6.5-5.3-11.8-11.8-11.8H756.1c-6.5 0-11.8-5.3-11.8-11.8V617.8c0-6.5-5.3-11.8-11.8-11.8H613.8c-6.5 0-11.8-5.3-11.8-11.8v-50.5c0-6.5-5.3-11.8-11.8-11.8H456.1c-6.5 0-11.8-5.3-11.8-11.8v-16.4c0-6.5 5.3-11.8 11.8-11.8h554.2c6.4 0.1 11.7-5.1 11.7-11.6z m-81.8 441.6H663.8c-6.5 0-11.8-5.3-11.8-11.8v-76.5c0-6.5 5.3-11.8 11.8-11.8h276.5c6.5 0 11.8 5.3 11.8 11.8v76.5c-0.1 6.6-5.4 11.8-11.9 11.8zM363.8 342h596.5c6.5 0 11.8 5.3 11.8 11.8v76.5c0 6.5-5.3 11.8-11.8 11.8H363.8c-6.5 0-11.8-5.3-11.8-11.8v-76.5c0-6.5 5.3-11.8 11.8-11.8z" p-id="1475"></path></svg>
        <div class="gjs-block-label">甘特图</div>
      `,
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: "甘特图",
      icon: "globe",
      docUrl:
        "https://xuelangyun.yuque.com/docs/share/5570479e-fd44-4833-83bf-8c9ef5eaab9b?# 《甘特图》",
      author: "宗介",
      email: "zongjie.wxt@xuelangyun.com",
      inPorts: [
        {
          uuid: "in1",
          subType: "json",
          description: {
            zh_CN: "输入1",
          },
        },
      ],
      // outPorts: [
      //   {
      //     uuid: "out1",
      //     subType: "json",
      //     description: {
      //       zh_CN: "输出1",
      //     },
      //   },
      // ],
    };
  },

  // 组件属性
  componentOptions() {
    return {
      name: ganteRef,
      resizable: true,
      dmode: "absolute",
      droppable: false,
      traits: [
        {
          name: "columnItem",
          label: "左侧字段",
          changeProp: 1,
        },
        {
          name: "gridWidth",
          label: "左侧面板宽度",
          changeProp: 1,
          type: 'number',
          min: 0
        },
        {
          name: "columnWidth",
          label: "左侧字段宽度",
          changeProp: 1,
          type: 'number',
          min: 0
        },
        {
          name: 'tooltips',
          label: '鼠标悬浮字段',
          changeProp: 1,
          type: 'key-value',
          width: '50%:50%',
          splitor: ':',
          placeholder: '字段:名称'
        },
        {
          name: 'timelines',
          label: '时间轴',
          changeProp: 1,
          type: 'key-value',
          width: '25%:75%',
          placeholder: '行:类型',
          options: [{id: 'year', name: '年'}, {id: 'month', name: '月,年'}, {id: 'month2', name: '年-月'}, {id: 'dayDate', name: '年-月-日'}, {id: 'day', name: '日'}, {id: 'dayWeek', name: '日（周）'}, {id: 'hour', name: '小时:分'}, {id: 'minute', name: '时:分钟'}, {id: 'minute2', name: '时:分:秒'}]
        },
        {
          name: 'timelinesHeight',
          label: '时间轴高度',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1
        },
        {
          name: 'durationUnit',
          label: '期间单位',
          changeProp: 1,
          type: 'select',
          options: [{id: 'minute', name: '分钟'}, {id: 'hour', name: '小时'}, {id: 'day', name: '天'}, {id: 'week', name: '星期'}, {id: 'month', name: '月'}, {id: 'year', name: '年'}]
        },
        {
          name: 'taskText',
          label: '显示字段',
          changeProp: 1
        },
        {
          name: 'startDate',
          label: '开始前',
          changeProp: 1,
          type: 'number'
        },
        {
          name: 'endDate',
          label: '结束后',
          changeProp: 1,
          type: 'number'
        },
        {
          name: 'background',
          label: '背景色',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'bordercolor',
          label: '边框颜色',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'fontcolor',
          label: '字体颜色',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'rowBgcolor',
          label: '任务行背景',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'oddRowBgcolor',
          label: '任务odd行背景',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'rowbordercolor',
          label: '任务行边框',
          changeProp: 1,
          type: 'color'
        },
        {
          name: 'row_height',
          label: '行高',
          changeProp: 1,
          type: 'number'
        },
        {
          name: 'bar_height',
          label: 'Bar Height',
          changeProp: 1,
          type: 'number'
        }
      ],
      defaultData: JSON.stringify([
        { id: 1, text: "Project #1", owner: "张三", start_date: null, duration: null, type: "project", parent: 0, progress: 0, open: true },
        { id: 2, text: "Task #3", owner: "张三", start_date: "2019-08-01 00:00", duration: null, type: "project", render: "split", parent: 1, progress: null },
        { id: 21, text: "Task #21", owner: "张三", start_date: "2019-08-01 00:00", duration: 4, parent: 2, progress: 0.6, color: "#ffc300" },
        { id: 22, text: "Task #33", owner: "张三", start_date: "2019-08-04 00:00", duration: 2, parent: 2, progress: 0.6, color: "#ffc300" },
        { id: 23, text: "Task #1", owner: "张三", start_date: "2019-08-06 00:00", duration: 3, parent: 2, progress: 0.6, color: "#ffc300" },
        { id: 3, text: "Task #3", owner: "张三", start_date: "2019-08-01 00:00", duration: null, type: "project", render: "split", parent: 1, progress: null },
        { id: 31, text: "Task #2", owner: "张三", start_date: "2019-08-01 00:00", end_date: "2019-08-03 12:30", parent: 3, progress: 0.5, color: '#db3e1c' },
        { id: 32, text: "Task #2", owner: "张三", start_date: "2019-08-03 00:00", end_date: "2019-08-06 12:30", parent: 3, progress: 0.5, color: '#db3e1c' },
        { id: 4, text: "Task #3", owner: "张三", start_date: "2019-08-03 00:00", duration: null, type: "project", render: "split", parent: 1, progress: null },
        { id: 41, text: "Task #3.1", owner: "张三", start_date: "2019-08-05 00:00", duration: 3, parent: 4, progress: 0.2, color: '#42db1c' },
        { id: 42, text: "Task #3.2", owner: "张三", start_date: "2019-08-08 00:00", duration: 2, parent: 4, progress: 0, color: '#42db1c' }
      ]).replace(/\"/g, '\\"'),
      columnItem: "id",
      columnWidth: 200,
      gridWidth: 200,
      tooltips: 'text:任务名称,start_date:开始时间,end_date:结束时间',
      timelines: '1:month,2:dayWeek',
      timelinesHeight: 60,
      durationUnit: 'day',
      taskText: 'text',
      startDate: 1,
      endDate: 2
    }
  },

  onModelScript() {
    const defaultData = JSON.parse("{[ defaultData ]}".replace(/\\\"/g, '"'));
    const columnItem = Boolean('{[ columnItem ]}') ? ('{[ columnItem ]}').toString() : 'wbs';
    const tooltips = ('{[ tooltips ]}').toString();
    const timelines = Boolean('{[ timelines ]}') ? ('{[ timelines ]}').toString() : '1:month,2:day';
    const timelinesHeight = Boolean('{[ timelinesHeight ]}') ? parseInt('{[ timelinesHeight ]}') : 0;
    const startDate = Boolean('{[ startDate ]}') ? -parseInt('{[ startDate ]}') : 0;
    const endDate = Boolean('{[ endDate ]}') ? parseInt('{[ endDate ]}') : 0;
    const columnWidth = Boolean('{[ columnWidth ]}') ? parseInt('{[ columnWidth ]}') : 0;
    const gridWidth = Boolean('{[ gridWidth ]}') ? parseInt('{[ gridWidth ]}') : 0;
    const row_height = Boolean('{[ row_height ]}') ? parseInt('{[ row_height ]}') : 0;
    const bar_height = Boolean('{[ bar_height ]}') ? parseInt('{[ bar_height ]}') : 0;
    const rowBgcolor = '{[ rowBgcolor ]}';
    const rowbordercolor = '{[ rowbordercolor ]}';
    const oddRowBgcolor = '{[ oddRowBgcolor ]}';
    const bordercolor = '{[ bordercolor ]}';
    const background = '{[ background ]}';
    const fontcolor = '{[ fontcolor ]}';
    const durationUnit = ('{[ durationUnit ]}').toString();
    const taskText = '{[ taskText ]}';

    const _id = this.getAttribute('id');
    const eventName = `call-${_id}`;
    const self = this;

    const setColsKey = function(col, targetObj, splitor) {
      const k_v = col.split(splitor);
      const k = k_v[0].trim();
      const v = k_v[1].trim();
      targetObj[k] = v;
    };

    const getKeyValue = function(targetObj, sourceStr, splitor) {
      if (sourceStr.indexOf(',') > 0) {
        sourceStr.split(',').forEach(function(col) {
          setColsKey(col, targetObj, splitor);
        });
      } else if (sourceStr.indexOf(splitor) > 0) {
        setColsKey(sourceStr, targetObj, splitor);
      }
    };
    const timelinesMap = {
      "year": {format: "%Y", unit: 'year'},
      "month": {format: "%F, %Y", unit: 'month'},
      "month2": {format: "%Y-%m", unit: 'month'},
      "day": {format: "%d", unit: 'day'},
      "dayWeek": {format: "%d（%D）", unit: 'day'},
      "dayDate": {format: "%Y-%m-%d", unit: 'day'},
      "hour": {format: "%H:%i", unit: 'hour'},
      "minute": {format: "%H:%i", unit: 'minute'},
      "minute2": {format: "%H:%i:%s", unit: 'minute'}
    };
    const tooltipMap = {};
    getKeyValue(tooltipMap, tooltips, ':');
    const timelineMap = {};
    getKeyValue(timelineMap, timelines, ':');
    let format = "%Y-%m-%d %H:%i:%s";
    gantt.config.readonly = true;
    gantt.config.scroll_size = 10;
    gantt.config.scale_height = timelinesHeight;
    if (row_height) gantt.config.row_height = row_height;
    if (bar_height) gantt.config.bar_height = bar_height;
    gantt.i18n.setLocale("cn");
    gantt.templates.task_text = function(start, end, task){
      if (Boolean(taskText)) {
        return taskText in task ? task[taskText] : taskText;
      }
      return '';
    };
    if (Boolean(background) || Boolean(bordercolor) || Boolean(fontcolor) || Boolean(rowBgcolor) || Boolean(rowbordercolor) || Boolean(oddRowBgcolor)) {
      let styleText = ``;
      if (Boolean(background)) {
        styleText += `
          .gantt_row, .gantt_task_row, .gantt_row.odd,
          .gantt_grid_scale, .gantt_task_scale,
          .gantt_container {
            background: ${background};
          }
          .gantt_hor_scroll::-webkit-scrollbar, .gantt_ver_scroll::-webkit-scrollbar {
            width: 10px;
            height: 10px;
          }
          .gantt_hor_scroll::-webkit-scrollbar-thumb, .gantt_ver_scroll::-webkit-scrollbar-thumb {
            background-color: rgba(255,255,255,.2);
          }
          .gantt_hor_scroll::-webkit-scrollbar-thumb:hover, .gantt_ver_scroll::-webkit-scrollbar-thumb:hover {
            background-color: rgba(255,255,255,.1);
          }
          .gantt_hor_scroll::-webkit-scrollbar-track, .gantt_ver_scroll::-webkit-scrollbar-track {
            background-color: rgba(255,255,255,.1);
          }
          .gantt_grid_data .gantt_row.odd:hover, .gantt_grid_data .gantt_row:hover {
            background-color: rgba(255,255,255,.2);
          }
        `
      }
      if (Boolean(bordercolor)) {
        styleText += `
          .gantt_layout_cell_border_right,
          .gantt_task .gantt_task_scale .gantt_scale_cell,
          .gantt_task_cell {
            border-right-color: ${bordercolor};
          }
          .gantt_layout_cell_border_bottom,
          .gantt_row, .gantt_task_row,
          .gantt_grid_scale, .gantt_task_scale {
            border-bottom-color: ${bordercolor};
          }
          .gantt_scale_line,
          .gantt_layout_cell_border_top {
            border-top-color: ${bordercolor};
          }
          .gantt_layout_cell_border_left {
            border-left-color: ${bordercolor};
          }
          .gantt_container {
            border-color: ${bordercolor};
          }
          .gantt_task_grid_row_resize_wrap .gantt_task_grid_row_resize {
            background-color: ${bordercolor};
          }
        `
      }
      if (Boolean(fontcolor)) {
        styleText += `
          .gantt_grid_scale .gantt_grid_head_cell,
          .gantt_task .gantt_task_scale .gantt_scale_cell,
          .gantt_grid_data .gantt_cell {
            color: ${fontcolor};
          }
        `
      }
      if (Boolean(rowBgcolor)) {
        styleText += `
          .gantt_task_row {
            background-color: ${rowBgcolor}!important;
          }
        `
      }
      if (Boolean(rowbordercolor)) {
        styleText += `
          .gantt_task_row {
            border-bottom-color: ${rowbordercolor}!important;
          }
        `
      }
      if (Boolean(oddRowBgcolor)) {
        styleText += `
          .gantt_task_row.odd {
            background-color: ${oddRowBgcolor}!important;
          }
        `
      }
      const textNode = document.createTextNode(styleText);
      let style;
      const timer = requestAnimationFrame(function() {
        if ($('body > style.customize').length) {
          $('body > style.customize').empty();
          style = $('body > style.customize')[0];
        } else {
          style = document.createElement("style");
          style.type = "text/css";
          style.className = "customize";
          $('body').prepend(style);
        }
        if (!style.childNodes.length || style.childNodes[0].data.indexOf(className) == -1) {
          style.appendChild(textNode);
        }
        cancelAnimationFrame(timer);
      })
    }
    // Tooltip
    gantt.plugins({ tooltip: true, drag_timeline: true });
    gantt.attachEvent("onGanttReady", function(){
      var tooltips = gantt.ext.tooltips;
      tooltips.tooltip.setViewport(gantt.$task_data);
    });
    gantt.config.duration_unit = durationUnit;
    gantt.config.date_format = format;
    gantt.templates.tooltip_date_format = function (date) {
      var formatFunc = gantt.date.date_to_str(format);
      return formatFunc(date);
    };
    gantt.templates.tooltip_text = function (start, end, task) {
      let str = '';
      const tooltipKeys = Object.keys(tooltipMap);
      const maxIndex = tooltipKeys.length - 1;
      tooltipKeys.forEach(function(key, i) {
        if (key == 'end_date' || key == 'start_date') {
          const param = key == 'end_date' ? end : start;
          str += tooltipMap[key] + ': ' + gantt.templates.tooltip_date_format(param)
          if (i < maxIndex) {
            str += '<br />'
          }
        } else if (key in task) {
          str += tooltipMap[key] + ': ' + task[key]
          if (i < maxIndex) {
            str += '<br />'
          }
        }
      })
      return str
    }
    gantt.attachEvent("onBeforeGanttRender", function () {
      var range = gantt.getSubtaskDates();
      var scaleUnit = gantt.getState().scale_unit;
      if (range.start_date && range.end_date) {
        gantt.config.start_date = gantt.calculateEndDate(range.start_date, startDate, scaleUnit);
        gantt.config.end_date = gantt.calculateEndDate(range.end_date, endDate, scaleUnit);
      }
    });
    // 时间线 scales
    const scales = Object.values(timelineMap).map(function(item) {
      return {
        unit: timelinesMap[item].unit,
        step: 1,
        format: timelinesMap[item].format
      }
    });
    const setScales = function(params) {
      gantt.config.scales = params;
    }
    setScales(scales);
    // Columns
    gantt.config.resize_rows = true;
    gantt.config.grid_resize = true;
    const column = { name: columnItem, min_width: 100, width: columnWidth, resize: true };
    if (columnItem == 'wbs') {
      column.label = ' ';
      column.template = gantt.getWBSCode;
    } else if (columnItem == 'text') {
      column.tree = true;
    }
    gantt.config.columns = [column];

    gantt.config.layout = {
      css: "gantt_container",
      cols: [
        {
          width: gridWidth,
          min_width: 100,
          rows: [
            { view: "grid", scrollX: "gridScroll", scrollable: true, scrollY: "scrollVer" },
            { view: "scrollbar", id: "gridScroll", group: "horizontal" }
          ]
        },
        { resizer: true, width: 1 },
        {
          rows: [
            { view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
            { view: "scrollbar", id: "scrollHor", group: "horizontal" }
          ]
        },
        { view: "scrollbar", id: "scrollVer" }
      ]
    };
    gantt.init(this.id);
    gantt.parse({ tasks: defaultData });

    // 有 dashboardHost 说明是运行模式
    if (window.spSocket) {
      window.spSocket.subscribe({
        eventName: eventName,
        callback: function (_data) {
          let _in1Str = _data.data.in1;
          if (_in1Str) {
            const data = JSON.parse(_in1Str);
            if ("tasks" in data) {
              gantt.clearAll();
              if ("scales" in data && data.scales.length) {
                setScales(data.scales)
                gantt.init(self.id);
              }
              if ("data" in data.tasks && data.tasks.data.length) {
                gantt.parse(data.tasks);
              }
            };
          }
        },
      });
    }
  },

  onViewInit() {
    this.updateScript();
    const evn = `
      change:columnItem
      change:columnWidth
      change:gridWidth
      change:tooltips
      change:timelines
      change:timelinesHeight
      change:durationUnit
      change:taskText
      change:startDate
      change:endDate
      change:rowBgcolor
      change:rowbordercolor
      change:oddRowBgcolor
      change:background
      change:bordercolor
      change:fontcolor
      change:row_height
      change:bar_height
    `;
    this.listenTo(this.model, evn, this.updateScript);
    this.listenTo(this.model, evn, this.em.handleUpdates.bind(this.em));
    this.listenTo(this.em, 'update:component:style:height update:component:style:width', throttle.bind(this, this.updateScript.bind(this)));
  },
};
