<template>
  <div ref="chart" style="width: 100%; height: 400px"></div>
</template>

<script>
import * as echarts from "echarts";
import entityApi from "~/apis/entityApi.js";
import { mapState } from "pinia";
import { useCommonStore } from "~/stores/commonStore";

/**
 * @vue-prop {Object|null} [selectedItem=null] - آیتم انتخاب شده
 * @vue-prop {String} [title="تغییرات زمانی"] - عنوان
 * @vue-prop {String} [time_unit="day"] - واحد زمانی
 * @vue-data {String} [gantt_time_unit="day"] - واحد زمانی گانت
 * @vue-data {Array} [gantt_data=[]] - داده‌های گانت
 * @vue-data {Object|null} [httpService=null] - سرویس HTTP
 * @vue-data {Number} [x_min=0] - حداقل مقدار محور x
 * @vue-data {Number} [x_max=10] - حداکثر مقدار محور x
 * @vue-data {Object|undefined} [entity=undefined] - موجودیت
 *
 * * @vue-computed {Function} [mapState.activeEntityViewSchemaGetter] - دریافت‌کننده طرح نمای موجودیت فعال
 */

export default {
  props: {
    selectedItem: {
      default: null,
    },
    title: {
      default: "تغییرات زمانی",
    },
    time_unit: {
      default: "day",
    },
  },
  data() {
    return {
      gantt_time_unit: "day",
      gantt_data: [],
      x_min: 0,
      x_max: 10,
      entity: undefined,
    };
  },
  computed: {
    ...mapState(useCommonStore, ["activeEntityViewSchemaGetter"]),
  },
  mounted() {
    if (this.selectedItem) {
      this.entity = this.selectedItem;
      this.gantt_time_unit = "month";
      this.getGanttData();
    } else {
      this.gantt_title = this.title;
      this.gantt_time_unit = this.time_unit;
      this.gantt_data = this.data;
      // this.setChartOptions(this.gantt_time_unit);
    }
  },
  watch: {
    selectedItem: {
      handler(newVal) {
        if (newVal) {
          this.getGanttData();
        }
      },
    },
  },
  methods: {
    /**
     * دریافت داده‌های نمودار گانت.
     * این متد با ارسال درخواست به سرور، داده‌های نمودار گانت را دریافت کرده و سپس نمودار را با استفاده از داده‌های دریافتی رندر می‌کند.
     */
    async getGanttData() {
      if (!this.selectedItem) {
        this.renderChart();
        return;
      }

      let payload = {
        id: this.selectedItem._id,
      };

      let url = entityApi.chart.ganttchart;
      let key = this.activeEntityViewSchemaGetter?.key;
      url = url.replace("{{index_key}}", key);
      if (key === "qasection" || key === "rgsection") {
        payload.qanon_id = this.selectedItem.qanon_id;
      }

      try {
        const { $api } = useNuxtApp();
        const res = await $api(url, {
          method: "post",
          baseURL: baseUrl(),
          body: payload,
        });

        this.x_min = res.meta.min;
        this.x_max = res.meta.max;
        this.gantt_data = res.data[0].data.map((item) => ({
          ...item,
          start: new Date(item.start),
          end: new Date(item.end),
        }));
      } catch (err) {
      } finally {
        this.renderChart();
      }

      // this.httpService
      //   .postRequest(url, payload)
      //   .then((res) => {
      //     this.x_min = res.meta.min;
      //     this.x_max = res.meta.max;
      //     this.gantt_data = res.data[0].data.map((item) => ({
      //       ...item,
      //       start: new Date(item.start),
      //       end: new Date(item.end),
      //     }));
      //   })
      //   .finally(() => {
      //     this.renderChart();
      //   })
      //   .catch((error) => {
      //     console.error("Error fetching Gantt data:", error);
      //   });
    },

    /**
     * رندر کردن نمودار.
     * این متد با استفاده از داده‌های نمودار گانت، نمودار را در DOM رندر می‌کند.
     */
    renderChart() {
      const chartDom = this.$refs.chart;
      const myChart = echarts.init(chartDom);
      const categories = this.gantt_data.map((item) => item.name);

      myChart.setOption({
        title: {
          text: this.title,
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow",
          },
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        xAxis: {
          type: "time",
        },
        yAxis: {
          type: "category",
          data: categories,
        },
        series: [
          {
            name: "Gantt",
            type: "custom",
            renderItem: function (params, api) {
              var categoryIndex = api.value(1);
              var start = api.coord([api.value(0), categoryIndex]);
              var end = api.coord([api.value(2), categoryIndex]);
              var height = api.size([0, 1])[1] * 0.6;

              return {
                type: "rect",
                shape: echarts.graphic.clipRectByRect(
                  {
                    x: start[0],
                    y: start[1] - height / 2,
                    width: end[0] - start[0],
                    height: height,
                  },
                  {
                    x: params.coordSys.x,
                    y: params.coordSys.y,
                    width: params.coordSys.width,
                    height: params.coordSys.height,
                  }
                ),
                style: {
                  fill: this.getRandomColor(),
                  transition: "fill 1s cubicInOut",
                },
              };
            }.bind(this),
            data: this.gantt_data.map((item) => {
              return [
                item.start.getTime(),
                categories.indexOf(item.name),
                item.end.getTime(),
              ];
            }),
            animationDurationUpdate: 1000,
            animationEasingUpdate: "cubicInOut",
          },
        ],
      });
    },

    /**
     * دریافت یک رنگ تصادفی.
     * این متد یک رنگ تصادفی از یک لیست از پیش تعیین شده برمی‌گرداند.
     *
     * @returns {string} - یک رشته حاوی کد رنگ به فرمت rgb
     */
    getRandomColor() {
      const colors = [
        "rgb(255, 99, 71)", // Tomato
        "rgb(255, 140, 0)", // Dark Orange
        "rgb(34, 139, 34)", // Forest Green
        "rgb(30, 144, 255)", // Dodger Blue
        "rgb(138, 43, 226)", // Blue Violet
        "rgb(255, 20, 147)", // Deep Pink
        "rgb(0, 191, 255)", // Deep Sky Blue
        "rgb(218, 165, 32)", // Goldenrod
        "rgb(220, 20, 60)", // Crimson
        "rgb(75, 0, 130)", // Indigo
      ];

      const randomIndex = Math.floor(Math.random() * colors.length);
      return colors[randomIndex];
    },

    /**
     * دریافت فرمت محور X.
     * این متد فرمت تاریخ و زمان محور X را بر اساس واحد زمانی گانت تعیین می‌کند.
     *
     * @returns {object} - یک شیء حاوی فرمت تاریخ و زمان
     */
    getXAxisFormat() {
      let format = {
        day: '%e<br><span style="opacity: 0.5; font-size: 1em">%a</span>',
      };
      if (this.gantt_time_unit == "day")
        format = {
          day: '%e<br><span style="opacity: 0.5; font-size: 1em">%a</span>',
        };
      else if (this.gantt_time_unit == "week") format = { week: "%e. %b" };
      else if (this.gantt_time_unit == "month") format = { month: "%b '%y" };
      else if (this.gantt_time_unit == "year") format = { year: "%Y" };

      return format;
    },
  },
};
</script>

<style>
/* افزودن هرگونه سبک مورد نیاز */
</style>
