<template>
  <div style="width: 100%">
    <el-row justify-content="start">
      <el-col :span="4">
        <span style="background-color: #11acf5; color: #fff">
          <el-icon style="display: inline-block; padding-top: 2.5px"><Bottom /></el-icon>
        </span>
        <span>基于原始预算降低（百分比）</span>
      </el-col>
      <el-col :span="4">
        <span style="background-color: #11acf5; color: #fff">
          <el-icon style="display: inline-block; padding-top: 2.5px"><Top /></el-icon>
        </span>
        <span>基于原始预算升高（百分比）</span>
      </el-col>
      <el-col :span="4">
        <span style="background-color: #3fd4cf; color: #fff">
          <el-icon style="display: inline-block; padding-top: 2.5px"><Bottom /></el-icon>
        </span>
        <span>基于原始预算降低（数值）</span>
      </el-col>
      <el-col :span="4">
        <span style="background-color: #3fd4cf; color: #fff">
          <el-icon style="display: inline-block; padding-top: 2.5px"><Top /></el-icon>
        </span>
        <span>基于原始预算升高（数值）</span>
      </el-col>
      <el-col :span="4">
        <span style="background-color: #3359b5; color: #fff">
          <el-icon style="display: inline-block; padding-top: 2.5px"></el-icon>
        </span>
        <span>固定预算</span>
      </el-col>
    </el-row>
    <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 class="calendar-body">
        <template v-for="(hoursList, week) in items">
          <tr>
            <th class="td-normal">{{ WeekMap[week] }}</th>
            <td
                v-for="(info, hour) in hoursList"
                :key="hour"
                :style="getTdStyle(info)"
                class="un-selected"
                @mousedown="handleMouseDown(week, hour, $event)"
                @mouseover="handleMouseMove(week, hour)"
                @mouseup="handleMouseUp">
              {{ getCellText(info) }}
              <el-icon v-if="info.type !== 'FixBudget'" style="display: inline-block; padding-top: 2px">
                <Top v-if="info.type === 'UpPercent' || info.type === 'UpNumber'" />
                <Bottom v-if="info.type === 'DownPercent' || info.type === 'DownNumber'" />
              </el-icon>
            </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" :append-to-body="true" :before-close="closeDialog" :close-on-click-modal="false"
               title="编辑" width="520px">
      <el-form ref="formRef" :inline="true" :model="formData">
        <el-row  :gutter="20">
          <el-col :span="16">
            <el-form-item prop="type">
              <el-select v-model="formData.type" style="width: 280px" @change="changeKind">
                <el-option v-for="item in KindEnum" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item v-if="formData.type !== ''" :rules="{ validator: checkValue, trigger: 'blur' }" prop="value">
              <InputFloat v-model="formData.value" :prefix="isNumber ? '$' : ''" :suffix="!isNumber ? '%' : ''"
                          maxlength="111111"></InputFloat>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancelBid">取消</el-button>
          <el-button type="primary" @click="submitBid">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, Ref, watch } from 'vue';
import InputFloat from '/@/components/input-float/index.vue';
import XEUtils from 'xe-utils';


interface Props {
  data: { value: string; type: string }[][];
  disabled?: boolean;
}

interface FormData {
  type: string;
  value: string;
}

const props = defineProps<Props>();

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 selectedItems = ref({});

const KindEnum = [
  { label: '无需调整预算', value: '' },
  { label: '固定预算', value: 'FixBudget', color: '#3359b5' },
  { label: '基于原始预算降低（百分比）', value: 'DownPercent', color: '#11acf5' },
  { label: '基于原始预算升高（百分比）', value: 'UpPercent', color: '#11acf5' },
  { label: '基于原始预算降低（数值）', value: 'DownNumber', color: '#3fd4cf' },
  { label: '基于原始预算升高（数值）', value: 'UpNumber', color: '#3fd4cf' },
];

const formData: Ref<FormData> = ref({ type: 'FixBudget', value: '1.00' });
const isNumber = ref(true);
const formRef = ref();

const checkValue = (rule: any, value: string, callback: any) => {
  if (formData.value.type === 'FixBudget') {
    if (XEUtils.toNumber(value) < 1) {
      return new Error('固定预算必须大于1');
    }
  } else {
    if (XEUtils.toNumber(value) <= 0) {
      return new Error('数值必须大于0');
    }
  }
};

for (let i = 0; i < 7; i++) {
  selectedItems.value[i] = [];
  const tmp = [];
  for (let j = 0; j < 24; j++) {
    let type = '';
    let value = '';
    if (props.data.length !== 0) {
      type = props.data[i][j].type;
      value = props.data[i][j].value;
    }
    tmp.push({ type, value });
  }
  items.value.push(tmp);
}

const getCellBackgroundColor = (row: any) => {
  if (row.selected) return '#ccdbff';
  if (row.type) return KindEnum.find((item) => item.value === row.type).color;
  return '';
};

const getTdStyle = (info: any) => {
  if (props.disabled) {
    let backgroundColor = '';
    if (info.type) {
      backgroundColor = KindEnum.find((item) => item.value === info.type).color;
    } else {
      backgroundColor = '#fff';
    }
    return { cursor: 'not-allowed', background: backgroundColor };
  }
  return { background: getCellBackgroundColor(info) };
};

watch(
    () => props.data,
    () => {
      // console.log(191, 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({ type: '', value: '' });
          }
          props.data.push(tmp);
        }
      }
      for (let i = 0; i < 7; i++) {
        for (let j = 0; j < 24; j++) {
          items.value[i][j].type = props.data[i][j].type;
          items.value[i][j].value = props.data[i][j].value;
        }
      }
    },
    { deep: true, immediate: true }
);

const changeKind = () => {
  if (formData.value.type === 'DownPercent' || formData.value.type === 'UpPercent') {
    isNumber.value = false;
  } else {
    isNumber.value = true;
  }
  formRef.value.clearValidate('value');
};

const getCellText = (row: any) => {
  if (row.type === 'DownPercent' || row.type === 'UpPercent') return row.value + '%';
  if (row.value) return '$' + row.value;
  return '';
};

const handleMouseDown = (rowIndex: number, colIndex: number, event: any) => {
  if (props.disabled) return;
  if (event.button === 0) {
    mouseDown.value = true;
    startRowIndex.value = rowIndex;
    startColIndex.value = colIndex;
    items.value[rowIndex][colIndex].selected = true;
    selectedItems.value[rowIndex].push(colIndex);
  }
};

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

const handleMouseMove = (rowIndex: number, colIndex: number) => {
  if (props.disabled) return;
  if (mouseDown.value) {
    selectCell(rowIndex, colIndex);
  }
};

const 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);
    }
  }
};

const submitBid = () => {
  if (formData.value.type === '') {
    for (const row of Object.keys(selectedItems.value)) {
      for (const col of selectedItems.value[row]) {
        props.data[row][col].type = '';
        props.data[row][col].value = '';
      }
    }
  } else {
    for (const row of Object.keys(selectedItems.value)) {
      for (const col of selectedItems.value[row]) {
        props.data[row][col].type = formData.value.type;
        props.data[row][col].value = formData.value.value;
      }
    }
  }
  clearSelectedItems();
  clearCellBackgroundColor();
  dialogVisible.value = false;
};

const cancelBid = () => {
  clearSelectedItems();
  clearCellBackgroundColor();
  dialogVisible.value = false;
};

const closeDialog = (done: Function) => {
  cancelBid();
  done();
};

const clearCellBackgroundColor = () => {
  for (const hoursList of items.value) {
    for (const info of hoursList) {
      info.selected = false;
    }
  }
};
const clearSelectedItems = () => {
  for (var i = 0; i < 7; i++) {
    selectedItems.value[i] = [];
  }
};
const resetAllBid = () => {
  for (let i = 0; i < 7; i++) {
    for (let j = 0; j < 24; j++) {
      items.value[i][j].value = 0;
      items.value[i][j].selected = false;
      props.data[i][j].type = '';
      props.data[i][j].value = '';
    }
  }
};
</script>

<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;
      color: #fff;

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

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

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

  .fr {
    float: right;
  }

  .middle {
    float: center;
  }
}

.cell-text {
  color: #fff;
}
</style>
