<script setup>
import { ref, computed, watch, onMounted } from 'vue'

// Props 定义
const props = defineProps({
  lang: { type: String, default: 'zh' },
  type: { type: String, default: 'calendar' },
  checkDate: { type: Boolean, default: false },
  bgweek: { type: String, default: '#FF8F22' },
  bgday: { type: String, default: '#FF8F22' },
  signin_but_bg: { type: String, default: '#909399' },
  supplementary: { type: Boolean, default: true },
  already: { type: Array, default: () => [] },
  checkinDays: { type: [Number, String], default: 0 },
  integral: { type: [Number, String], default: 0 },
  isIntegral: { type: Boolean, default: false }
})

// Emits
const emit = defineEmits(['shift', 'change'])

// 响应式数据
const weeked = ref('')
const dayArr = ref([])
const localDate = ref('')
const currentDate = new Date()
const year = ref(currentDate.getFullYear())
const month = ref(currentDate.getMonth() + 1)
const day = ref(currentDate.getDate())
const aheadDay = ref(0)
const prv = ref(true)
const next = ref(true)
const is_day_signin = ref(false)

// 计算属性
const weekArr = computed(() =>
  props.lang === 'zh' ? ['日', '一', '二', '三', '四', '五', '六'] : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
)

const thisMonth = computed(() => currentDate.getMonth() + 1)

// 格式化数字
const formatNum = (num) => num < 10 ? `0${num}` : num

// 初始化日期
const initDate = () => {
  dayArr.value = []
  const totalDay = new Date(year.value, month.value, 0).getDate()

  for (let i = 1; i <= totalDay; i++) {
    const value = new Date(year.value, month.value - 1, i).getDay()

    if (i === 1 && value !== 0) {
      addBefore(value)
      aheadDay.value = value
    }

    const dateObj = {
      date: `${year.value}-${formatNum(month.value)}-${formatNum(i)}`,
      day: i,
      flag: false
    }
    dayArr.value.push(dateObj)

    if (i === totalDay && value !== 6) {
      addAfter(value)
    }
  }
}

// 补充前空白日期
const addBefore = (value) => {
  const totalDay = new Date(year.value, month.value - 1, 0).getDate()
  for (let i = 0; i < value; i++) {
    dayArr.value.push({
      date: '',
      day: totalDay - (value - i) + 1
    })
  }
}

// 补充后空白日期
const addAfter = (value) => {
  for (let i = 0; i < (6 - value); i++) {
    dayArr.value.push({
      date: '',
      day: i + 1
    })
  }
}

// 签到处理
const daySign = (obj) => {
  const index = aheadDay.value + day.value - 1
  if (dayArr.value[index].flag) return false

  dayArr.value[index].flag = true
  emit('change', obj.date)
  is_day_signin.value = true
  showSuccessToast('已签到')
}

// 补签处理
const signToday = (obj, index) => {
  if (props.type === 'calendar') return
  if (currentDate.getMonth() + 1 !== parseInt(obj.date.split('-')[1])) return

  if (obj.date && obj.day < day.value) {
    if (dayArr.value[index].flag) {
      showFailToast('已签到')
    } else {
      if (day.value > obj.day && !props.supplementary) return

      showSuccessToast(day.value > obj.day ? '补签成功' : '签到成功')
      dayArr.value[index].flag = true
      emit('change', obj.date)
    }
  }
}

// 月份切换
const changeMonth = (direction) => {
  if (direction === 'prev') {
    if (month.value === 1) {
      year.value--
      month.value = 12
    } else {
      month.value--
    }
  } else {
    if (month.value === 12) {
      year.value++
      month.value = 1
    } else {
      month.value++
    }
  }

  initDate()
  updateNavigationButtons()
}

// 更新导航按钮状态
const updateNavigationButtons = () => {
  prv.value = year.value >= currentDate.getFullYear() || month.value > currentDate.getMonth() + 2
  next.value = year.value <= currentDate.getFullYear() || month.value < currentDate.getMonth()
}

// 监听已签到数据变化
watch(() => props.already, (newVal) => {
  dayArr.value.forEach((day, index) => {
    const timestamp = new Date(day.date).getTime()
    day.flag = newVal.includes(timestamp)
    if (day.flag && day.date === localDate.value) {
      is_day_signin.value = true
    }
  })
}, { deep: true })

// 初始化
onMounted(() => {
  initDate()
  localDate.value = `${year.value}-${formatNum(month.value)}-${formatNum(day.value)}`
  weeked.value = weekArr.value[currentDate.getDay()]

  if (props.type !== 'calendar') {
    dayArr.value.forEach(day => day.flag = false)
  }
})
</script>

<template>
  <div class="calendar-container">
    <!-- 头部信息 -->
    <div class="header">
      <div class="checkin-info">
        <h4>已连续签到 <span>{{ checkinDays }}</span> 天</h4>
        <p v-if="isIntegral">今日获得+{{ integral }}信用分</p>
      </div>
      <!-- <div class="actions">
        <span v-if="supplementary" class="makeup-btn" @click="$emit('shift')">
          补签
        </span>
      </div> -->
    </div>

    <!-- 日历主体 -->
    <div class="calendar-body">
      <!-- 月份导航 -->
      <div class="month-nav">
        <div class="nav-btn" @click="changeMonth('prev')">
          <span v-show="prv">上月</span>
        </div>
        <div class="current-month">{{ year }}年{{ month }}月</div>
        <div class="nav-btn" @click="changeMonth('next')">
          <span v-show="next">下月</span>
        </div>
      </div>

      <!-- 星期栏 -->
      <div class="week-row">
        <div v-for="week in weekArr" :key="week" class="week-cell" :style="{ color: week === weeked ? bgweek : '' }">
          {{ week }}
        </div>
      </div>

      <!-- 日期格子 -->
      <div class="date-grid">
        <div v-for="(date, index) in dayArr" :key="index" class="date-cell" :class="{
          'empty': date.date === '',
          'selected': date.date === localDate || date.flag
        }" :style="{
            background: (date.date === localDate || date.flag) ? bgday : ''
          }" @click="signToday(date, index)">
          {{ date.day }}
          <div :class="{
            'dot': date.flag,
            'makeup': date.day < day,
            'today': date.day === day
          }" />
        </div>
      </div>
    </div>

    <!-- 签到按钮 -->
    <div class="sign-button">
      <button :disabled="thisMonth !== month" :style="{
        background: is_day_signin ?
          signin_but_bg :
          (thisMonth === month ? bgday : signin_but_bg)
      }" @click="daySign(dayArr[aheadDay + day - 1])">
        签到
      </button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.calendar-container {
  width: 100%;
  display: flex;
  flex-direction: column;

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px;
    background: #fff;
    border-radius: 10px;
    margin-bottom: 8px;

    .checkin-info {
      h4 {
        font-weight: 600;
        font-size: 18px;
        line-height: 25px;

        span {
          color: #FF871E;
          margin: 0 5px;
          font-size: 16px;
        }
      }

      p {
        font-size: 14px;
        line-height: 20px;
        color: #FF871E;
      }
    }

    .makeup-btn {
      font-size: 12px;
      color: #FF871E;
      border: 1px solid #FF871E;
      padding: 5px 10px;
      border-radius: 16px;

      &:active {
        opacity: 0.8;
      }
    }
  }

  .calendar-body {
    padding: 10px 20px;
    background: #fff;
    border-radius: 12px;

    .month-nav {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin: 15px 0;

      .nav-btn {
        min-width: 35px;
        cursor: pointer;

        &:active {
          opacity: 0.8;
        }
      }
    }

    .week-row {
      display: flex;
      justify-content: space-between;

      .week-cell {
        width: 35px;
        height: 35px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }

    .date-grid {
      display: flex;
      flex-wrap: wrap;

      .date-cell {
        width: 35px;
        height: 35px;
        margin: 5px;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;

        &.empty {
          color: #999;
        }

        &.selected {
          color: #fff;
          border-radius: 50%;
        }

        .dot {
          width: 5px;
          height: 5px;
          border-radius: 50%;
          position: absolute;
          bottom: 5%;
          left: 50%;
          transform: translateX(-50%);
          background: #fff;
        }
      }
    }
  }

  .sign-button {
    display: flex;
    justify-content: center;
    margin-top: 40px;

    button {
      width: 325px;
      height: 40px;
      border-radius: 15px;
      border: none;
      outline: none;
      color: #fff;
      font-size: 16px;

      &:active {
        opacity: 0.9;
      }

      &:disabled {
        opacity: 0.6;
      }
    }
  }
}
</style>