<script setup>
import { defineProps, onMounted, watch, ref, reactive, inject } from "vue";
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
import { postAlertSchedule } from "@/apis/alert";
import * as yup from "yup";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

const { openToast } = inject("app_toast");
const { timesListData } = inject("notify_table");
const props = defineProps({
  openModal: Function,
  onCancel: Function,
  editRecord: Object,
  weekDate: Object,
});

let scheme = yup.object({
  schedule_name: yup.string().required(t("button.required")),
});

const form = ref(null);
const schedule_array = ref([]);
const formState = ref({
  id: 0,
  schedule_name: "",
});

const { formErrorMsg, handleSubmit, handleErrorReset } = useFormErrorMessage(
  scheme.value
);

const closeModal = () => {
  props.onCancel();
  formState.value = {
    id: 0,
    schedule_name: "",
  };
  clear();
};

const tableHeader = ref([
  "00",
  "01",
  "02",
  "03",
  "04",
  "05",
  "06",
  "07",
  "08",
  "09",
  "10",
  "11",
  "12",
  "13",
  "14",
  "15",
  "16",
  "17",
  "18",
  "19",
  "20",
  "21",
  "22",
  "23",
]);

const rowUnit = ref([]); //每一單位格子
const timeContent = ref([]); //選中的時間段原始數據
const timeSection = ref([]); //時間段，可以返回給後端
const timeStr = ref([]); //時間段，前端顯示的數據
let beginDay = ref(0);
let beginTime = ref(0);
let downEvent = ref(false);

// 其他變數保持不變
const hoverRange = reactive({
  startDay: 0,
  endDay: 0,
  startSlot: 0,
  endSlot: 0,
});

const handleMouseMove = (i, day) => {
  if (!downEvent.value) return;
  hoverRange.startDay = Math.min(beginDay.value, day);
  hoverRange.endDay = Math.max(beginDay.value, day);
  hoverRange.startSlot = Math.min(beginTime.value, i);
  hoverRange.endSlot = Math.max(beginTime.value, i);
};

const initSchedule = () => {
  for (let i = 0; i < 7; i++) {
    const dayIndex = i;
    const defaultTimes = schedule_array.value[dayIndex] || [];
    let arr = [];
    for (let j = 0; j < 96; j++) {
      const timeSlot = j / 4;
      const isDefault = defaultTimes.some((timeRange) => {
        const [start, end] = timeRange.split("~").map((t) => {
          const [hours, minutes] = t.split(":").map(Number);
          return hours + minutes / 60;
        });
        return timeSlot >= start && timeSlot < end;
      });

      arr.push({ class: isDefault ? "ui-selected" : null, timeData: j });
    }
    rowUnit.value.push(arr);
    timeContent.value.push({
      arr: arr
        .filter((item) => item.class === "ui-selected")
        .map((item) => item.timeData),
    });
    timeSection.value.push(defaultTimes);
    timeStr.value.push(defaultTimes.join(", "));
  }
};

const handleMouseDown = (i, day) => {
  downEvent.value = true; //滑鼠不在範圍內的不算
  beginDay.value = day;
  beginTime.value = i;
};

const handleMouseUp = (i, day) => {
  let begin = beginTime.value;
  let start = begin <= i ? begin : i; //x軸起點
  let length = Math.abs(begin - i);
  let end = start + length; //x軸終點
  let dayStart = beginDay.value <= day ? beginDay.value : day; //y軸起點
  let dayLength = Math.abs(beginDay.value - day);
  let dayEnd = dayStart + dayLength; //y軸終點

  const isAdd = () => {
    //當選取範圍內所有的都是選取狀態時,則執行取消選取
    for (let x = dayStart; x < dayEnd + 1; x++) {
      for (let y = start; y < end + 1; y++) {
        if (rowUnit.value[x][y].class === null) return true;
      }
    }
    return false;
  };

  if (downEvent.value) {
    //當點擊事件是在table内才觸發選取操作
    if (isAdd()) {
      for (let x = dayStart; x < dayEnd + 1; x++) {
        for (let y = start; y < end + 1; y++) {
          if (rowUnit.value[x][y].class === null) {
            rowUnit.value[x][y].class = "ui-selected";
            timeContent.value[x].arr.push(rowUnit.value[x][y].timeData);
          }
        }
      }
    } else {
      for (let x = dayStart; x < dayEnd + 1; x++) {
        for (let y = start; y < end + 1; y++) {
          if (rowUnit.value[x][y].class === "ui-selected") {
            rowUnit.value[x][y].class = null;
            let c = rowUnit.value[x][y].timeData;
            let kong = "";
            for (let i = 0; i < timeContent.value[x].arr.length; i++) {
              if (c === timeContent.value[x].arr[i]) {
                kong = i;
              }
            }
            timeContent.value[x].arr.splice(kong, 1);
          }
        }
      }
    }
    //過濾時間段,將鄰近的時間段合併
    filterTime(dayStart, dayEnd);
  }
  downEvent.value = false;

  hoverRange.startDay = hoverRange.endDay = 0;
  hoverRange.startSlot = hoverRange.endSlot = 0;
};

const filterTime = (start, end) => {
  const toStr = (num) => {
    if (Number.isInteger(num)) {
      return `${num < 10 ? "0" + num : num}:00`;
    } else {
      const intPart = Math.floor(num);
      const fracPart = num - intPart;
      const str = intPart < 10 ? "0" + intPart : intPart.toString();
      return `${str}:${
        fracPart === 0.25 ? "15" : fracPart === 0.5 ? "30" : "45"
      }`;
    }
  };

  const timeToStr = (arr) => {
    return arr.map(([start, end]) => `${toStr(start)}~${toStr(end)}`);
  };

  for (let i = start; i <= end; i++) {
    const sortedArr = [...new Set(timeContent.value[i].arr)].sort(
      (a, b) => a - b
    );
    const sections = [];
    for (let j = 0; j < sortedArr.length; j++) {
      if (j === 0 || sortedArr[j] !== sortedArr[j - 1] + 1) {
        sections.push([sortedArr[j], sortedArr[j]]);
      } else {
        sections[sections.length - 1][1] = sortedArr[j];
      }
    }

    timeSection.value[i] = timeToStr(
      sections.map(([start, end]) => [start / 4, (end + 1) / 4])
    );
    timeStr.value[i] = timeSection.value[i].join(", ");
  }
};

const clear = () => {
  schedule_array.value = [];
  rowUnit.value = [];
  timeContent.value = [];
  timeSection.value = [];
  timeStr.value = [];
};

const onOk = async () => {
  const values = await handleSubmit(scheme, formState.value);

  const res = await postAlertSchedule({
    ...values,
    schedule_json: timeSection.value ? JSON.stringify(timeSection.value) : "",
  });

  if (res.isSuccess) {
    timesListData();
    closeModal();
  } else {
    openToast("error", res.msg, "#outliers_time_item");
  }
};

watch(
  () => props.editRecord,
  (newValue) => {
    if (newValue) {
      formState.value = {
        ...newValue,
      };
      schedule_array.value = newValue?.schedule_json
        ? JSON.parse(newValue?.schedule_json)
        : [];
      initSchedule();
    }
  }
);
</script>

<template>
  <button class="btn btn-sm btn-add mr-3" @click.stop.prevent="openModal">
    <font-awesome-icon :icon="['fas', 'plus']" />{{ $t("button.add") }}
  </button>
  <Modal
     id="outliers_time_item"
    :open="open"
    :onCancel="closeModal"
    width="1400"
    :title="t('alert.warning_time')"
  >
    <template #modalContent>
      <form ref="form">
        <Input :value="formState" class="mt-2" name="schedule_name">
          <template #topLeft>{{ $t("alert.schedule_name") }}</template>
          <template #bottomLeft>
            <span class="text-error text-base">
              {{ formErrorMsg.schedule_name }}
            </span>
          </template>
        </Input>
        <p class="text-light text-lg my-2">{{ $t("alert.schedule_content") }}</p>
        <div class="weektime mt-5">
          <div class="calendar">
            <table class="calendar-table w-full">
              <thead class="calendar-head">
                <tr>
                  <th rowspan="6" class="w-20 py-4">
                    {{ $t("alert.day_time") }}
                  </th>
                  <th colspan="48">00:00 - 12:00</th>
                  <th colspan="48">12:00 - 24:00</th>
                </tr>
                <tr>
                  <td
                    colspan="4"
                    v-for="(item, index) in tableHeader"
                    :key="index"
                  >
                    {{ item }}
                  </td>
                </tr>
              </thead>
              <tbody id="tableBody">
                <tr v-for="(day, index) in weekDate" :key="index">
                  <td>{{ day }}</td>
                  <td
                    v-for="(item, i) in rowUnit[index - 1]"
                    :key="i"
                    @mousedown.prevent="handleMouseDown(i, index - 1)"
                    @mouseup.prevent="handleMouseUp(i, index - 1)"
                    @mousemove.prevent="handleMouseMove(i, index - 1)"
                    class="calendar-atom-time"
                    :class="{
                      'ui-selected': item.class === 'ui-selected',
                      'hover-highlight':
                        downEvent &&
                        index - 1 >= hoverRange.startDay &&
                        index - 1 <= hoverRange.endDay &&
                        i >= hoverRange.startSlot &&
                        i <= hoverRange.endSlot,
                    }"
                  ></td>
                </tr>
                <tr>
                  <td colspan="97" class="py-2">
                    <span class="text-base me-2">{{
                      $t("alert.click_time_period")
                    }}</span>
                    <a
                      @click="
                        () => {
                          clear();
                          initSchedule();
                        }
                      "
                      class="cursor-pointer text-active text-base"
                    >
                       {{ $t("alert.clear") }}
                    </a>
                  </td>
                </tr>
                <tr>
                  <td colspan="97" class="timeContent">
                    <div
                      v-for="(item, index) in timeStr"
                      :key="index"
                      v-show="item.length"
                    >
                      <span>{{ weekDate[index + 1] }}: </span>
                      <strong>
                        <span>{{ item }}</span>
                      </strong>
                    </div>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </form>
    </template>
    <template #modalAction>
      <button
        type="reset"
        class="btn btn-outline-success mr-2"
        @click.prevent="closeModal"
      >
        {{ $t("button.cancel") }}
      </button>
      <button
        type="submit"
        class="btn btn-outline-success"
        @click.prevent="onOk"
      >
        {{ $t("button.submit") }}
      </button>
    </template>
  </Modal>
</template>

<style lang="css" scoped>
.weektime .calendar {
  -webkit-user-select: none;
  position: relative;
  display: inline-block;
  width: 100%;
}

.weektime .calendar .calendar-table tr .calendar-atom-time:hover {
  background: #ccc;
}

.weektime .calendar .calendar-table tr .ui-selected {
  background: #00ffb3;
}

.weektime .calendar .calendar-table tr .ui-selected:hover {
  background: #ccc;
}

.weektime .calendar .calendar-table tr,
.weektime .calendar .calendar-table td,
.weektime .calendar .calendar-table th {
  border: 1px solid #ccc;
  font-size: 13px;
  text-align: center;
  line-height: 1.8em;
  transition: background 200ms ease;
}

.weektime .calendar .calendar-table tbody tr {
  height: 35px;
}

.weektime .calendar .calendar-table tbody tr td:first-child {
  background: #123;
}

.weektime .calendar .calendar-table thead th,
.weektime .calendar .calendar-table thead td {
  background: #123;
}

.hover-highlight {
  background: rgba(0, 255, 145, 0.5); /* 淡藍色透明背景 */
  border: 1px dashed #00ffb3; /* 藍色虛線邊框 */
}
</style>
