<template>
  <div class="ganttContainerBox">
    <div ref="ganttContainer" style="height: 100%;">
    </div>
    <!-- 任务详情信息弹出框 -->
    <el-dialog :class="''" :title="title" v-if="addFormVisible" append-to-body
      :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="840px" :top="'6vh'">
      <taskComponent ref="thskComponents" :integrationTask="integrationTask" :showOrNot="showOrNot"
        @closeBounced="closeBounced" :showMmeiLaiDe="true" :showMmeiLaiDeData="showMmeiLaiDeData"></taskComponent>
      <div slot="title" v-if="addForm.parentTid != null">
        <el-page-header @back="backToParentTask" :title="$t('parenttask')"
          :content="addForm.parentTname"></el-page-header>
      </div>
    </el-dialog>
    <!-- tooltip -->
    <div 
      v-if="tooltip.visible"
      :style="`top:${tooltip.y}px;left:${tooltip.x}px;`" 
      class="custom-tooltip-customize"
    >
      <div><b>开始时间:</b> {{ tooltip.task.start_date }}</div>
      <div><b>结束时间:</b> {{ tooltip.task.end_date }}</div>
      <div><b>计划工时:</b> {{ tooltip.task.time }} 小时 ({{ tooltip.task.dayDifference }} 天 )</div>
      <div><b>项目名称:</b> {{ tooltip.task.projectName }}</div>
      <div><b>计划名称:</b> {{ tooltip.task.planName }}</div>
    </div>
  </div>
</template>

<script>
import { gantt } from 'dhtmlx-gantt';
// import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
// import 'dhtmlx-gantt/codebase/locale/locale_cn'  // 本地化
import taskComponent from "@/components/taskComponent.vue"
export default {
  name: 'gantt',
  components: {
    taskComponent
  },
  props: {
    tasks: {
      type: Object,
      default() {
        return { data: [], links: [] }
      }
    },
    stafforpro: '',
    valueDate: [],
  },
  data() {
    return {
      containerRect: null,
      taskFormVisible: false,
      addForm: {},
      addLoading: false,
      title: '创建计划',
      commentList: [],
      dynamicTab: true,
      showOrNot: false,
      integrationTask: null,
      taskComponentFlg: false,
      addFormVisible: false,
      integrationTaskNingwai: {},
      integrationTask: {},
      user: JSON.parse(sessionStorage.getItem("user")),
      showMmeiLaiDeData: {},
      tooltip: {
        visible: false,
        task: null,
        x: 0,
        y: 0,
      }
    };
  },
  created: function () {
    // gantt.clearAll()
    // console.log("tasks",this.$props.tasks);
  },

  methods: {
    detaliTaskExposure(row) {
      const { taskId, ganttData } = row
      this.title = '编辑计划'
      this.showMmeiLaiDeData = JSON.parse(ganttData || '{}')
      setTimeout(() => {
        this.editTask({ taskId })
      }, 1000)
    },
    getDistanceToParent(element, parent) {
      let distance = 0;
      while (element && element !== parent) {
        distance += element.offsetTop;  // 获取当前元素相对于父元素顶部的距离
        element = element.offsetParent; // 获取上一级父元素
      }
      return distance;
    },
    closeBounced(obj) {
      console.log(obj, '<======== 点击事件')
      if (!obj.backToParentTaskSub) {
        this.addFormVisible = false
        this.taskComponentFlg = false

        if (obj.submitInsert) {
          this.$emit('closeBounced', obj)
        }

        if(obj.deleteTask) {
          this.$emit('closeBounced', obj)
        }
      }
    },
    backToParentTask() {
      console.log('点击， <======== 点击了backToParentTask')
    },
    addTask(row) {
      this.showOrNot = true
      this.addForm = {
        projectId: '', groupId: '', stagesId: '', taskLevel: 0, planHours: 8, taskType: 0, startDate: row.date
      }
      const userIdList = (row.userId && row.userId.split(',')) || []
      const executorListFront = userIdList.map(item => {
        return {
          executorId: item,
          planHours: 8
        }
      })
      let obj = {
        create: true,
        addForm: this.addForm,
        executorListFront,
        stage: this.addForm,
        integrationTaskNingwai: this.integrationTaskNingwai,
        taskVue: true,
        meetingId: this.addForm.meetingId
      }
      this.integrationTask = obj
      this.addFormVisible = true
    },
    editTask(row) {
      this.showOrNot = true
      this.http.post('/task/getTask', { id: row.taskId },
        res => {
          if (res.code == "ok") {
            const data = res.data
            if(this.user.roleId != 2283 && !data.executorId) {
              this.$message({
                message: '这条数据只有区域经理才能分配',
                type: 'warning'
              });
              return
            }
            this.addForm = {
              id: data.id
            }
            this.integrationTask = {
              id: data.id,
              task: data,
              num: 1,
              curProjectId: data.projectId || '',
              create: false,
              integrationTaskNingwai: {
                groupId: data.groupId,
                isDesc: false,
                order: "seq",
                projectId: data.projectId || '',
              },
              taskVue: data.projectId ? false : true,
              meetingId: this.addForm.meetingId
            }
            this.addFormVisible = true
          } else {
            this.$message({ message: res.msg, type: "error" });
          }
        },
        error => {
          this.$message({ message: error, type: "error" });
        });
    },
    handleEmptyClick(row) {
      if (row.taskId) {
        // 编辑任务
        this.title = '编辑计划'
        this.editTask(row)
      } else {
        // 新增任务
        this.title = '创建计划'
        this.addTask(row)
      }
    },
    // 定位数据
    focusAndSelectTaskFull(taskId) {
      if (gantt.isTaskExists(taskId)) {
        var task = gantt.getTask(taskId);
        gantt.showTask(taskId);
        gantt.selectTask(taskId);

        // 检查日期有效性
        if (!(task.start_date instanceof Date) || !(task.end_date instanceof Date)) {
          console.error("Invalid date format in task:", task);
          return;
        }

        var midTime = (task.start_date.getTime() + task.end_date.getTime()) / 2;
        var midDate = new Date(midTime);

        gantt.scrollTo(gantt.posFromDate(midDate) - 200, gantt.getScrollState().y);
      }
    },
    observeTaskLines(gantt) {
      console.log(gantt, '<==== gantt')
      const taskContainer = gantt.$task_data;

      this.observer = new MutationObserver(() => {
        this.bindTooltipEvents();
      });

      this.observer.observe(taskContainer, {
        childList: true,
        subtree: true
      });

      this.bindTooltipEvents(); // 初次执行
    },
    bindTooltipEvents() {
      console.log('开始执行')
      const taskLines = this.$refs.ganttContainer && this.$refs.ganttContainer.querySelectorAll(".gantt_task_line");

      (taskLines || []).forEach(line => {
        const taskId = line.getAttribute("task_id");
        if (!taskId || line.dataset.bound === "true") return;

        line.dataset.bound = "true";

        line.addEventListener("mouseenter", (e) => {
          const rect = line.getBoundingClientRect();
          const task = gantt.getTask(taskId);
          if(!task.taskId) {
            this.tooltip.visible = false;
            return
          }
          console.log(task)
          const list = task.text.split('/')
          const d1 = this.dayjs(task.start_date);
          const d2 = this.dayjs(task.end_date);
          this.tooltip.task = {
            ...task,
            end_date: this.dayjs(task.endDateStr).format('YYYY-MM-DD HH:mm:ss'),
            start_date: this.dayjs(task.startDateStr).format('YYYY-MM-DD HH:mm:ss'),
            projectName: list[0],
            planName: list[1],
            dayDifference:  d2.diff(d1, 'day'),
          };
          this.tooltip.x = rect.left + window.scrollX;
          this.tooltip.y = (rect.top - 180) - 10 + window.scrollY;
          this.tooltip.visible = true;
        });

        line.addEventListener("mouseleave", () => {
          this.tooltip.visible = false;
        });
      });
    },
    bindTaskLineEvents() {
      console.log("bindTaskLineEvents", this.$refs.ganttContainer)
      if(!this.$refs.ganttContainer) {
        return
      }
      const taskLines = this.$refs.ganttContainer.querySelectorAll(".gantt_task_line");
      (taskLines || []).forEach(line => {
        const taskId = line.getAttribute("task_id");
        if (!taskId) return;

        // 避免重复绑定
        if (line.dataset.tooltipBound) return;
        line.dataset.tooltipBound = "true";

        line.addEventListener("mouseenter", (e) => {
          const task = gantt.getTask(taskId);
          this.tooltip.task = task;
          this.tooltip.visible = true;

          const updateMouse = (moveEvent) => {
            this.tooltip.x = moveEvent.pageX;
            this.tooltip.y = moveEvent.pageY;
          };

          document.addEventListener("mousemove", updateMouse);

          line.addEventListener("mouseleave", () => {
            this.tooltip.visible = false;
            document.removeEventListener("mousemove", updateMouse);
          }, { once: true });
        });
      });
    }
  },
  mounted: function () {
    const userInfo = JSON.parse(sessionStorage.getItem("user"));
    gantt.clearAll()
    gantt.locale = {
      date: {
        month_full: [this.$t('yiYue'), this.$t('erYue'), this.$t('sanYue'), this.$t('siYue'), this.$t('thisTWuyue'), this.$t('liuYue'), this.$t('qiYue'), this.$t('baYue'), this.$t('jiuYue'), this.$t('shiYue'), this.$t('shiYiYue'), this.$t('shiErYue')],
        month_short: [this.$t('1Yue'), this.$t('2Yue'), this.$t('3Yue'), this.$t('4Yue'), this.$t('5Yue'), this.$t('6Yue'), this.$t('7Yue'), this.$t('8Yue'), this.$t('9Yue'), this.$t('10Yue'), this.$t('11Yue'), this.$t('12Yue')],
        day_full: [this.$t('xingQiRi'), this.$t('xingQiYi'), this.$t('xingQiEr'), this.$t('xingQiSan'), this.$t('xingQiSi'), this.$t('xingQiWu'), this.$t('xingQiLiu')],
        day_short: [this.$t('ri'), "一", "二", "三", "四", "五", "六"]
      },
      labels: {
        dhx_cal_today_button: this.$t('jinTian'),
        day_tab: this.$t('weekDay.day'),
        week_tab: this.$t('zhou'),
        month_tab: this.$t('weekDay.month'),
        new_event: this.$t('xinJianRiCheng'),
        icon_save: this.$t('save'),
        icon_cancel: this.$t('Shutdown'),
        icon_details: this.$t('xiangXi'),
        icon_edit: this.$t('bian-ji'),
        icon_delete: this.$t('btn.delete'),
        confirm_closing: this.$t('qingQueRenShiFouCheXiaoXiuGai'), //Your changes will be lost, are your sure?
        confirm_deleting: this.$t('shiFouShanChuRiCheng'),
        section_description: this.$t('other.describe'),
        section_time: this.$t('shiJianFanWei'),
        section_type: this.$t('types'),

        /* grid columns */

        column_text: this.$t('renWuMing'),
        column_start_date: this.$t('starttimes'),
        column_duration: this.$t('chiXuShiJian'),
        column_add: "",

        /* link confirmation */

        link: this.$t('guanLian'),
        confirm_link_deleting: this.$t('jiangBeiShanChu'),
        link_start: this.$t('kaiShi'),
        link_end: this.$t('jieShu'),

        type_task: this.$t('other.task'),
        type_project: this.$t('other.project'),
        type_milestone: this.$t('other.milestone'),

        minutes: this.$t('fenZhong'),
        hours: this.$t('time.hour'),
        days: this.$t('time.day'),
        weeks: this.$t('zhou'),
        months: this.$t('weekDay.month'),
        years: this.$t('nian')
      }
    };
    // gantt.config.autosize = true;
    // gantt.config.duration_unit = "hour";
    gantt.config.fit_tasks = true;
    gantt.config.drag_move = false;
    gantt.config.xml_date = "%Y-%m-%d";
    gantt.config.columns = [
      { name: "text", label: (this.stafforpro == this.$t('anRenYuanChaKan') ? this.$t('lable.name') : this.$t('headerTop.projectName')), align: "left", tree: true },
      // {name:"time",label:"计划工时(h)", align: "center" }
      // {name:"start_date", label:"开始时间", width:'*' , align: "center" },
      // {name:"duration",   label:"工时(天)", width:'*' ,   align: "center" }
    ];
    gantt.config.scale_unit = "month";	//按月显示
    gantt.config.date_scale = "%F, %Y";		//设置时间刻度的格式（X轴） 多个尺度

    gantt.config.scale_height = 50; //设置时间刻度的高度和网格的标题
    gantt.config.open_tree_initially = true;

    gantt.config.subscales = [
      { unit: "day", step: 1, date: "周%D,%d" }
    ];
    gantt.config.buttons_left = []
    gantt.config.buttons_right = ["gantt_cancel_btn"]
    gantt.config.drag_links = false
    gantt.config.drag_resize = false
    gantt.config.drag_progress = false
    gantt.config.details_on_dblclick = false
    gantt.config.lightbox.sections = [
      { name: "description", height: 76, map_to: "text", type: "textarea", focus: true }
    ];

    gantt.config.start_date = new Date(this.valueDate[0]);
    gantt.config.end_date = new Date(this.valueDate[1]);

    const that = this
    // 设置任务条内容显示
    gantt.templates.task_text = function (start, end, task) {
      const { leaderOrManager, taskPlan, taskStatus, checkFirstId, checkSecondId, startDateStr, endDateStr, time, text } = task
      const userIds = that.user.id

      const d1 = that.dayjs(task.start_date);
      const d2 = that.dayjs(task.end_date);
      const texts = `${startDateStr.split(' ')[0].split('-').join('')} - ${endDateStr.split(' ')[0].split('-').join('')}  ${time}h(${ d2.diff(d1, 'day')}天) ${text}`
      // 都审核通过
      if(taskPlan == 1 && taskStatus == 0 && task.text == '请假') {
        return `<div class="task_text">
            <div style="background: '#ff5757'">${texts}</div>
          </div>`
      }

      if(taskPlan == 1 && taskStatus == 0) {
        return `<div class="task_text">
            <div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div>
            <div class="exclamation-circle circle" style="color: ${task.taskPlanType == 3 ? '#f56c6c' : '#8ecaf8'}">V</div>
            <div>${texts}</div>
          </div>`
      }

      // 更改为统一的
      if([2,3,4,5,6].includes(taskStatus)) {
          return `<div class="task_text">
            ${task.taskStatus == 2 ? `<div class="circle greyStr"></div>` : ''}
            ${task.taskStatus == 3 ? `<div class="circle orangeStr"></div> <div class="circle"></div>` : ''}
            ${task.taskStatus == 4 ? `<div class="exclamation-circle circle greenStr" style="color: #8ecaf8">V</div> <div class="circle orangeStr"></div>` : ''}
            ${task.taskStatus == 5 ? `<div class="exclamation-circle circle redStr" style="color: #f56c6c">!</div> <div class="circle"></div>` : ''}
            ${task.taskStatus == 6 ? `<div class="exclamation-circle circle greenStr" style="color: #8ecaf8">V</div> <div class="exclamation-circle circle redStr" style="color: #f56c6c">!</div>` : ''}
            <div style="margin-left: 6px;">${texts}</div>
          </div>`;
      }

      // 正常人
      return `<div class="task_text" style="justify-content: center;">
          <div style="color: #333">${task.text}</div>
        </div>`;
    };
    gantt.config.grid_width = 350;
    gantt.plugins({ tooltip: true });
    gantt.templates.tooltip_text = function (start, end, task) {
      return
    };

    gantt.ext.tooltips.attach({
      selector: '.gantt_grid [' + gantt.config.task_attribute + ']',
      onmouseenter: (event, node) => {
        if (node.textContent.length > 19) {
          let sdom = document.createElement('span')
          sdom.innerText = node.innerText
          sdom.className = 'tooltiptext'
          node.appendChild(sdom)
        }

      },
      onmousemove: () => { },
      onmouseleave: (event, node) => {
        let sdom = document.getElementsByClassName('tooltiptext')[0]
        if (sdom) { node.removeChild(sdom) }

      },
      global: true
    })

    // 双击事件
    this.$refs.ganttContainer.addEventListener('dblclick', (event) => {
      const taskIdStr = gantt.locate(event);
      // if(userInfo.projectLeaderType != 1 && userInfo.projectLeaderType != 2 && userInfo.projectLeaderType != 3) {
      //   return
      // }
      this.showMmeiLaiDeData = {}
      if (taskIdStr && gantt.isTaskExists(taskIdStr)) {
        // 编辑任务
        const rows = gantt.getTask(taskIdStr)
        if (rows.id.indexOf('任务') != '-1') {
          const value = taskIdStr.split('任务_')[1]
          const taskId = value.split('_')[0]
          this.showMmeiLaiDeData = rows
          this.handleEmptyClick({ taskId })
        }
      } else {
        if(userInfo.projectLeaderType == 2) {
          return
        }
        // 获取 gantt_grid_data 容器
        const ganttGrid = document.querySelector('.gantt_grid_data');
        if (!ganttGrid) return;
        // // 计算点击位置
        const gridRect = ganttGrid.getBoundingClientRect();
        // const clickY = event.clientY - gridRect.top; // 相对 gantt_grid_data 的 Y 轴偏移量

        // // 获取任务行
        // const rows = ganttGrid.querySelectorAll('.gantt_row');
        // const rowHeight = rows.length > 0 ? rows[0].offsetHeight : 34; // 获取行高 (默认 40px)
        // // 计算索引
        // const rowIndex = Math.floor(clickY / rowHeight);
        // if (rowIndex >= rows.length || rowIndex < 0) return;

        // // 获取任务 ID
        // const rowElement = rows[rowIndex];

        // 新写的
        const rows = ganttGrid.querySelectorAll('.gantt_row');
        const clickedElement = event.toElement;  // 当前点击的元素
        const parentElement = clickedElement.closest('.gantt_task_row');
        const yzhozhi = this.getDistanceToParent(parentElement) - 219 // 219 固定值
        const yCoordinate = +((yzhozhi / 35).toFixed(0)) * 35
        let rowIndexs = 0
        for(const em in rows) {
          const str = (rows[em].style && rows[em].style.top) || '-1px'
          const nums = str.split('px')[0]
          if(nums == yCoordinate) {
            rowIndexs = em
          }
        }
        const rowElement = rows[rowIndexs]
        console.log(yCoordinate, rowIndexs)
        console.log(rowElement, '<,,,,,,,,,,=============== rowElement')

        const taskIdFromRow = rowElement.getAttribute('task_id'); // 获取任务 ID
        if (taskIdFromRow && gantt.isTaskExists(taskIdFromRow)) {
          const taskData = gantt.getTask(taskIdFromRow);
          console.log(taskData, '<=== taskData')
          if (taskData.userId) {
            // 新增任务
            let rollingDistance = 0
            const scrollElement = this.$refs.ganttContainer.querySelector('.gantt_hor_scroll');
            if (scrollElement) {
              rollingDistance = scrollElement.scrollLeft || 0
            }
            const userId = taskData.userId;
            const gridX = event.clientX - gridRect.left; // 相对 gantt_grid_data 的 X 轴偏移量
            const date = gantt.dateFromPos((gridX - 349) + rollingDistance);
            console.log('点击的日期：', date, this.dayjs(date).format('YYYY-MM-DD'));
            this.handleEmptyClick({ userId, date: this.dayjs(date).format('YYYY-MM-DD') })
          }
        }
      }
    });

    gantt.init(this.$refs.ganttContainer);
    this.containerRect = this.$refs.ganttContainer.getBoundingClientRect();
    gantt.parse(this.$props.tasks);

    // 等渲染完成后绑定每个任务条事件
    setTimeout(() => {
      this.observeTaskLines(gantt); // 开始监听任务条变化
    }, 2000)

    setTimeout(() => {
      const list = JSON.parse(localStorage.getItem('ganttChartTaskId') || '[]')
      if(list[0]) {
        this.focusAndSelectTaskFull(list[0])
      }

      localStorage.removeItem('ganttChartTaskId')
    }, 1000)
  }
}

</script>

<style>
@import "~dhtmlx-gantt/codebase/dhtmlxgantt.css";

.person_line {
  background: #8ecaf8;
  border: 1px solid;
  @include border_color("border_color");
}

.error_line {
  background: #ff5757;
  border: 1px solid;
  border-color: #ff5757;
}

.success_line {
  background: #5cb87a;
  border: 1px solid;
  border-color: #5cb87a;
}

.draft_line {
  background: #909399;
  border: 1px solid;
  border-color: #909399;
}

.reject_line {
  background: #FFBD4D;
  border: 1px solid;
  border-color: #FFBD4D;
}

.task_text {
  display: flex;
  flex-direction: row;
  align-items: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
}

.task_text>div {
  flex: 0 0 auto;
}

.circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid #fff;
  margin-left: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.exclamation-circle {
  background: #fff;
  font-size: 12px;
  font-weight: bold;
}

.pendingReviewOfCornerMarkers {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fdba6e;
  font-weight: bold;
}

.statuss .circle {
  border-color: #fdba6e;
}


/* .gantt_tooltip{
      z-index: 10000;
      top: 10px !important;
      left: 10px !important;
    } */
.tooltiptext {
  visibility: visible;
  background-color: #fff;
  color: #454545;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, .07);
  border-left: 1px solid rgba(0, 0, 0, .07);
  border-top: 1px solid rgba(0, 0, 0, .07);
  font-size: 8pt;
  line-height: 20px;
  padding: 10px;
  /* opacity: 0;
      transition: 0.5s; */

  position: absolute;
  z-index: 10000;
  bottom: 120%;
  left: 25px;
  max-width: 300px;
  /* word-wrap: break-word;
      word-break: break-all; */
  white-space: pre-wrap;
}

.custom-tooltip-customize {
  position: fixed;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  padding: 20px;
  border-radius: 6px;
}

.custom-tooltip-customize div {
  margin-bottom: 10px;
  line-height: 20px;
}

.custom-tooltip-customize div:last-child {
  margin-bottom: 0;
}

.orangeStr {
  background: #ffa500;
}

.greenStr {
  background: #32cd32;
}

.redStr {
  background: #ff0000;
}

.greyStr {
  background: #e0e0e0;
}

</style>