<script lang="ts" setup>
import { ref, onMounted, watch, reactive } from 'vue';
import { ElMessage } from 'element-plus';

interface Props {
  data: number[][];
  disabled: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
});
const bidData = ref(props.data);

const mouseDown = ref(false);
const startRowIndex = ref(0);
const startColIndex = ref(0);
const items = ref([]);
const WeekMap = {
  0: '星期一',
  1: '星期二',
  2: '星期三',
  3: '星期四',
  4: '星期五',
  5: '星期六',
  6: '星期日',
};
const dialogVisible = ref(false);
const bid = ref(1.00);
const selectedItems = ref({});

const form = ref({
  bid: 1.00, // 将 bid 添加到 form 对象中
});

const rules = ref({
  bid: [
    { required: true, message: '请输入数值小于100的数值，可精确到小数点后2位', trigger: 'blur' },
    {
      validator: (rule, value, callback) => {
        if (Number(value) > 100) {
          return callback(new Error('请输入数值小于100的数值，可精确到小数点后2位'));
        }
        return callback();
      },
      trigger: 'blur'
    }
  ]
});
const formRef = ref(null);

//根据 props.disabled 和 info.selected 来返回一个包含样式的对象，用于设置单元格的样式
function getTdStyle(info: any) {
  if (props.disabled) {
    return {cursor: 'not-allowed', background: '#fff'};
  }
  return {background: info.selected ? '#ccdbff' : ''};
}

for (let i = 0; i < 7; i++) {
  selectedItems.value[i] = [];
  const tmp = [];
  for (let j = 0; j < 24; j++) {
    tmp.push({value: bidData.value.length === 0 ? 0 : bidData.value[i][j], selected: false});
  }
  items.value.push(tmp);
}

//在单元格上按下鼠标时触发的函数
function handleMouseDown(rowIndex: number, colIndex: number, event: any) {
  if (props.disabled) return;
  if (event.button === 0) {
    clearCellBackgroundColor();

    mouseDown.value = true;
    startRowIndex.value = rowIndex;
    startColIndex.value = colIndex;
    items.value[rowIndex][colIndex].selected = true;
    selectedItems.value[rowIndex].push(colIndex);
  }
}

function handleMouseUp(event: any) {
  if (props.disabled) return;
  if (event.button === 0) {
    mouseDown.value = false;
    startColIndex.value = 0;
    startRowIndex.value = 0;
    dialogVisible.value = true;
  }
}

//在单元格上移动鼠标时触发的函数，用于选择多个单元格。
function handleMouseMove(rowIndex: number, colIndex: number) {
  if (props.disabled) return;
  //if (info.selected) {
  //  info.selected = false;
  //}
  if (mouseDown.value) {
    selectCell(rowIndex, colIndex);
  }
}

//选择多个单元格
function selectCell(rowIndex: number, colIndex: number) {
  if (props.disabled) return;
  const rowStart = Math.min(startRowIndex.value, rowIndex);
  const rowEnd = Math.max(startRowIndex.value, rowIndex);
  const cellStart = Math.min(startColIndex.value, colIndex);
  const cellEnd = Math.max(startColIndex.value, colIndex);

  for (let i = rowStart; i <= rowEnd; i++) {
    for (let j = cellStart; j <= cellEnd; j++) {
      items.value[i][j].selected = true;
      selectedItems.value[i].push(j);
    }
  }
}

//提交出价，将选中的单元格的值设置为 bid，并清除选中状态和单元格背景色。
function submitBid() {
  for (const row of Object.keys(selectedItems.value)) {
    for (const col of selectedItems.value[row]) {
      items.value[row][col].value = Number(form.value.bid);
      bidData.value[row][col] = Number(form.value.bid);
    }
  }
  clearSelectedItems();
  clearCellBackgroundColor();
  dialogVisible.value = false;
}

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      submitBid();
    }
  });
};

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  cancelBid()
  formEl.resetFields()
}

//取消出价
function cancelBid() {
  clearSelectedItems();
  clearCellBackgroundColor();
  dialogVisible.value = false;
}

//清除所有单元格的背景色。
function clearCellBackgroundColor() {
  for (const hoursList of items.value) {
    for (const info of hoursList) {
      info.selected = false;
    }
  }
}

function clearSelectedItems() {
  for (var i = 0; i < 7; i++) {
    selectedItems.value[i] = [];
  }
}

//重置所有单元格的出价为 1，并清除选中状态。
function resetAllBid() {
  for (let i = 0; i < 7; i++) {
    for (let j = 0; j < 24; j++) {
      items.value[i][j].value = 1;
      items.value[i][j].selected = false;
      bidData.value[i][j] = 1; // TODO: 不知道是什么东西
    }
  }
}

function closeDialog(done: Function) {
  cancelBid();
  done();
}

const applyBid = (timeRangeValue: string, scheduleValue: string, bidValue: number) => {
  const timeRangeMap = {
    'Option1': {start: 0, end: 23},
    'Option2': {start: 0, end: 6},
    'Option3': {start: 7, end: 11},
    'Option4': {start: 9, end: 16},
    'Option5': {start: 12, end: 16},
    'Option6': {start: 17, end: 20},
    'Option7': {start: 21, end: 23},
  };

  const scheduleMap = {
    'Option1': [0, 1, 2, 3, 4, 5, 6],
    'Option2': [0, 1, 2, 3, 4],
    'Option3': [5, 6],
  };

  const {start, end} = timeRangeMap[timeRangeValue];
  const days = scheduleMap[scheduleValue];

  days.forEach(day => {
    for (let hour = start; hour <= end; hour++) {
      items.value[day][hour].selected = true;
      items.value[day][hour].value = bidValue;
      bidData.value[day][hour] = bidValue;
    }
  });
};

defineExpose({
  applyBid,
});

watch(
    () => props.data,
    () => {
      if (props.data.length === 0) {
        for (let i = 0; i < 7; i++) {
          const tmp = [];
          for (let j = 0; j < 24; j++) {
            tmp.push(0);
          }
          props.data.push(tmp);
        }
      }
      for (let i = 0; i < 7; i++) {
        for (let j = 0; j < 24; j++) {
          items.value[i][j].value = props.data[i][j];
        }
      }
      bidData.value = props.data;
    },
    {immediate: true}
);

</script>

<template>
  <div class="calendar">
    <table class="calendar-table calendar-table-hour">
      <thead class="calendar-head">
      <tr>
        <th class="week-td" rowspan="8">星期 / 时间</th>
        <th colspan="12">00:00 - 12:00</th>
        <th colspan="12">12:00 - 24:00</th>
        <th class="week-td" colspan="4" rowspan="2" style="display: none">小时</th>
      </tr>
      <tr>
        <th v-for="(_, i) in 24" :key="i" colspan="1">{{ i }}</th>
      </tr>
      </thead>
      <tbody>
      <template v-for="(hoursList, week) in items">
        <tr>
          <th>{{ WeekMap[week] }}</th>
          <td
              v-for="(info, hour) in hoursList"
              :key="hour"
              :style="getTdStyle(info)"
              @mousedown="handleMouseDown(week, hour, $event)"
              @mouseover="handleMouseMove(week, hour)"
              @mouseup="handleMouseUp">
            <span class="cell-text"> {{
                info.value ? Number(info.value).toFixed(2) : ''
              }} </span>
          </td>
        </tr>
      </template>
      <tr>
        <th class="clear-bar" colspan="28">
          <span class="middle">可拖动鼠标选择时间段</span>
          <el-button :disabled="disabled" class="hover-link fr" link @click="resetAllBid">全部重置</el-button>
        </th>
      </tr>
      </tbody>
    </table>
  </div>
  <el-dialog v-model="dialogVisible" :before-close="closeDialog" :close-on-click-modal="false" title="修改出价系数"
             width="30%">
    <el-form ref="formRef" :model="form" :rules="rules" style="display: inline-block;">
      <el-form-item label="Bid" prop="bid" label-width="80px">
        <el-input
            v-model="form.bid"
            clearable
            oninput="value=value.replace(/[^\d.]/g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').replace(/^\./g, '')"
            placeholder="1.0"
            style="width: 150px;"
        ></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetForm(formRef)">取消</el-button>
          <el-button type="primary" @click="submitForm(formRef)">确认</el-button>
        </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.calendar {
  background-color: #fff;
  -webkit-user-select: none;
  position: relative;
  display: inline-block;

  .calendar-table {
    border-collapse: collapse;
  }

  .week-td {
    width: 90px;
  }
}

table {
  display: table;
  border-collapse: separate;
  box-sizing: border-box;
  text-indent: initial;
  border-spacing: 2px;
  border-color: gray;

  thead {
    display: table-header-group;
    vertical-align: middle;
    border-color: inherit;
  }

  tr {
    border: 1px solid #e0e5f4;
    font-size: 12px;
    text-align: center;
    line-height: 32px;
    color: rgba(0, 0, 0, 0.5);

    th {
      min-width: 40px;
      border: 1px solid #e0e5f4;
      font-size: 12px;
      text-align: center;
      line-height: 32px;
      background: #f7f8fa;
    }

    td {
      border: 1px solid #e0e5f4;
      font-size: 12px;
      text-align: center;
      line-height: 32px;
      min-width: 40px;

      &:hover {
        background: #ccdbff;
        cursor: pointer;
      }

      .cell-text {
        color: black;
      }
    }
  }
}

.clear-bar {
  line-height: 32px;
  padding: 0 12px;

  .hover-link {
    color: #1c6bde;
    font-size: 13px;
    margin-top: 7px;
  }

  .fr {
    float: right;
  }

  .middle {
    float: center;
  }
}
</style>
