<template>
  <view class="checkin-page">
    <view class="checkin-container">
      <!-- 课程信息卡片 -->
      <view class="course-card">
        <view class="course-title">{{ course.theme }}</view>
        <view class="course-info">
          <view class="info-item">
            <u-icon name="calendar-fill" class="info-icon"></u-icon>
            <text>{{ course.date }} - {{ course.period }}</text>
          </view>
          <view class="info-item">
            <u-icon name="map-fill" class="info-icon"></u-icon>
            <text>{{ course.address }}</text>
          </view>
          <view class="info-item">
            <u-icon name="account-fill" class="info-icon"></u-icon>
            <text>{{ course.teacher?course.teacher.name:'' }}</text>
          </view>
        </view>
      </view>

      <!-- 状态检测卡片 -->
      <view class="status-card">
        <h6 class="card-title">
          <u-icon name="shield-checkmark" class="title-icon"></u-icon>
          签到状态检测
        </h6>
        <view class="status-item">
          <text class="status-label">定位状态</text>
          <view :class="['status-value', 'status-' + locationStatus.type]">
            <u-icon :name="getStatusIcon(locationStatus.type)"></u-icon>
            <text>{{ locationStatus.text }}</text>
          </view>
          <view v-if="showOpenLocationSetting" class="open-permission" @tap="requestLocationPermission">打开定位权限</view>
        </view>
        <view class="status-item">
          <text class="status-label">打卡范围</text>
          <view :class="['status-value', 'status-' + rangeStatus.type]">
            <u-icon :name="getStatusIcon(rangeStatus.type)"></u-icon>
            <text>{{ rangeStatus.text }}</text>
          </view>
        </view>
      </view>

      <!-- 距离信息 -->
      <view v-if="distance !== null" class="distance-info">
        <view class="distance-value">{{ formattedDistance }}</view>
        <view class="distance-label">距离课程地点</view>
      </view>

      <!-- 提示信息 -->
      <view v-if="alertInfo.message" :class="['alert-custom', 'alert-' + alertInfo.type]">
        <u-icon :name="getStatusIcon(alertInfo.type)" class="alert-icon"></u-icon>
        <text>{{ alertInfo.message }}</text>
      </view>

      <!-- 签到操作 -->
      <view class="checkin-actions">
        <u-button
          type="primary"
          class="checkin-btn"
          :disabled="!canCheckin"
          @click="performCheckin"
        >
          <u-icon name="map" class="btn-icon"></u-icon>
          {{ hasCheckedIn ? '已签到' : '位置签到' }}
        </u-button>
        <u-button
          type="success"
          class="recheck-btn"
          @click="initializeCheckin"
        >
          <u-icon name="reload" class="btn-icon"></u-icon>
          重新定位
        </u-button>
      </view>

      <!-- 签到记录 -->
      <view class="status-card">
        <h6 class="card-title">
          <u-icon name="order" class="title-icon"></u-icon>
          签到记录
        </h6>
        <view v-if="checkinHistory.length === 0" class="history-empty">
          暂无签到记录
        </view>
        <view v-else class="history-list">
          <view v-for="(record, index) in checkinHistory" :key="index" class="history-item">
            <text>签到时间: {{ record.created_at }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      course_content_id:'',
      course: {},
      userLocation: null,
      distance: null,
      canCheckin: false,
      hasCheckedIn: false,
      locationStatus: { type: 'default', text: '未定位' },
      rangeStatus: { type: 'default', text: '未计算' },
      alertInfo: { type: '', message: '' },
      checkinHistory: [],
      showOpenLocationSetting: false
    };
  },
  computed: {
    formattedDistance() {
      const d = this.distance
      if (d == null) return ''
      // >= 1km 显示为整 km；< 1km 显示米
      if (d >= 1000) return `${Math.round(d / 1000)}km`
      return `${d}m`
    }
  },
  onLoad(options) {
    console.log("options?.course_content_id",options?.course_content_id)
    this.course_content_id = options?.course_content_id
    // this.loadCheckinHistory();
    // 进入页面：先检查定位权限
    // this.checkPermissionAndInit();
    this.initializeCheckin()
  },
  methods: {
    async checkPermissionAndInit() {
      this.showOpenLocationSetting = false
      let granted = false
      try {
        const setting = await new Promise((resolve) => {
          uni.getSetting({ success: resolve, fail: () => resolve({}) })
        })
        const auth = setting?.authSetting || {}
        granted = !!auth['scope.getLocation']
      } catch (e) {}
      if (!granted) {
        this.locationStatus = { type: 'warning', text: '未获取定位权限' }
        this.rangeStatus = { type: 'default', text: '未计算' }
        this.canCheckin = false
        this.showOpenLocationSetting = true
        return
      }
      await this.initializeCheckin()
    },
    requestLocationPermission() {
      uni.authorize({
        scope: 'scope.getLocation',
        success: () => {
          this.showOpenLocationSetting = false
          this.initializeCheckin()
        },
        fail: () => {
          uni.openSetting({
            success: (res) => {
              const ok = res?.authSetting && res.authSetting['scope.getLocation']
              if (ok) {
                this.showOpenLocationSetting = false
                this.initializeCheckin()
              }
            }
          })
        }
      })
    },

    // 获取当前位置经纬度（Promise 形式）
    // 本地调试：从三个坐标中随机返回；接入真机定位时，改回 uni.getLocation
    getLocation() {
      return new Promise((resolve, reject) => {
        const candidates = [
          { lat: 31.401992, lng: 120.686876 },
          { lat: 32.899321, lng: 120.682145 },
          { lat: 31.272715, lng: 120.670337 }
        ]
        const idx = Math.floor(Math.random() * candidates.length)
        resolve(candidates[idx])
        // 真实定位：
        // uni.getLocation({
        //   type: 'gcj02',
        //   success: (res) => resolve({ lat: res.latitude, lng: res.longitude }),
        //   fail: (err) => reject(err)
        // })
      })
    },
        // 获取课表信息
    async getCourse() {
      const res = await this.$u.api.courseContentDetail({
        course_content_id: this.course_content_id
      });
      const data = res || {}
      // 兼容后端字段：latitude/longitude 或 lat/lng
      const lat = data.latitude
      const lng = data.longitude
      this.course = {
        ...this.course,
        ...data,
        location: { lat, lng },
        allowedDistance: 500
      }
    },
    // 获取签到记录
    async signGet() {
      const res = await this.$u.api.signGet({
        course_content_id: this.course_content_id
      });
      const rows = res?.list || []
      this.checkinHistory = Array.isArray(rows) ? rows : []
      if (this.checkinHistory.length > 0) {
        this.hasCheckedIn = true
        this.canCheckin = false
        this.alertInfo = { type: 'warning', message: '已存在签到记录，不能重复打卡' }
      }
    },

    // 获取距离并更新状态（合并 signDistance + calculateDistance ）
    async signDistance() {
      let distance = null
      let allowed = this.course.allowedDistance || 500
      try {
        const res = await this.$u.api.signDistance({
          course_content_id: this.course_content_id,
          latitude: this.userLocation.lat,
          longitude: this.userLocation.lng
        })
        const data = res || {}
        // 接口返回单位为 km，这里转为 m
        if (data && data.distance != null && !isNaN(parseFloat(data.distance))) {
          const km = parseFloat(data.distance)
          distance = Math.round(km * 1000)
        }
        if (data && data.content_check_range != null && !isNaN(parseFloat(data.content_check_range))) {
          const kmRange = parseFloat(data.content_check_range)
          allowed = Math.round(kmRange * 1000)
        }
      } catch (e) {}
      if (distance === null) {
        const distLocal = this.getDistanceFromLatLonInM(
          this.userLocation.lat, this.userLocation.lng,
          this.course.location.lat, this.course.location.lng
        )
        distance = Math.round(distLocal)
      }
      this.distance = distance
      this.course.allowedDistance = allowed

      if (this.distance <= allowed) {
        this.rangeStatus = { type: 'success', text: '在打卡范围内' };
        this.canCheckin = !this.hasCheckedIn;
        this.alertInfo = this.hasCheckedIn
          ? { type: 'warning', message: '已存在签到记录，不能重复打卡' }
          : { type: 'success', message: `您已进入打卡范围，距离${this.formatDistanceVal(this.distance)}。` };
      } else {
        const over = Math.max(0, this.distance - allowed)
        this.rangeStatus = { type: 'error', text: `超出范围约${this.formatDistanceVal(over)}` };
        this.canCheckin = false;
        this.alertInfo = { type: 'warning', message: `您需要进入${this.formatDistanceVal(allowed)}范围内才能签到。` };
      }
    },
    // 签到
    async signCheck() {
      const res = await this.$u.api.signCheck({
        course_content_id: this.course_content_id,
        latitude: this.userLocation.lat,
        longitude: this.userLocation.lng
      });
      // 根据返回结果更新本地状态
      this.hasCheckedIn = true
      this.canCheckin = false
      this.alertInfo = { type: 'success', message: '签到成功' }
      // 可选：重新拉取签到记录
      try { await this.signGet() } catch (e) {}
    },
    async initializeCheckin() {
      this.locationStatus = { type: 'warning', text: '定位中...' };
      this.rangeStatus = { type: 'default', text: '未计算' };
      this.canCheckin = false;
      this.distance = null;
      this.alertInfo = { type: '', message: '' };
      try {
        // 1. 课表
        await this.getCourse()
        await this.signGet()
        // 2. 定位
        const loc = await this.getLocation()
        console.log(loc)
        this.userLocation = loc
        this.locationStatus = { type: 'success', text: '定位成功' };
        // 3. 距离与状态
        await this.signDistance()
      } catch (e) {
        this.locationStatus = { type: 'error', text: '定位失败' };
        this.rangeStatus = { type: 'error', text: '无法计算' };
        this.alertInfo = { type: 'error', message: '获取信息或位置失败，请检查权限和网络。' };
      }
    },
    // calculateDistance 已并入 signDistance
    getDistanceFromLatLonInM(lat1, lon1, lat2, lon2) {
      const R = 6371;
      const dLat = this.deg2rad(lat2 - lat1);
      const dLon = this.deg2rad(lon2 - lon1);
      const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      return R * c * 1000;
    },
    deg2rad(deg) {
      return deg * (Math.PI / 180);
    },
    formatDistanceVal(m) {
      if (m == null) return ''
      const n = Number(m)
      if (isNaN(n)) return ''
      if (n >= 1000) return `${Math.round(n / 1000)}km`
      return `${Math.round(n)}m`
    },
    getStatusIcon(type) {
      const icons = {
        success: 'checkmark-circle-fill',
        error: 'close-circle-fill',
        warning: 'error-circle-fill',
        default: 'question-circle-fill'
      };
      return icons[type] || 'question-circle-fill';
    },
    async performCheckin() {
      if (this.hasCheckedIn) {
        uni.showToast({ title: '您今天已经签过到了', icon: 'none' });
        return;
      }
      if (!this.canCheckin) return
      try {
        await this.signCheck()
        uni.showToast({ title: '签到成功！', icon: 'success' });
      } catch (e) {
        uni.showToast({ title: '签到失败', icon: 'none' });
      }
    },
    loadCheckinHistory() {
      const records = uni.getStorageSync('checkinHistory') || [];
      this.checkinHistory = records;
      if (records.length > 0) {
        const lastRecordTime = new Date(records[0].time);
        if (lastRecordTime.toDateString() === new Date().toDateString()) {
          this.hasCheckedIn = true;
        }
      }
    }
  }
};
</script>

<style scoped>
.checkin-page {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
  padding: 20rpx;
}
.checkin-container {
  max-width: 400px;
  margin: 0 auto;
}
.course-card, .status-card {
  background: white;
  border-radius: 32rpx;
  box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.1);
  padding: 32rpx;
  margin-bottom: 30rpx;
}
.course-title {
  font-size: 36rpx;
  font-weight: 600;
  text-align: center;
  margin-bottom: 24rpx;
}
.course-info {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}
.info-item {
  display: flex;
  align-items: center;
  gap: 16rpx;
  padding: 12rpx;
  background: #f8f9fa;
  border-radius: 16rpx;
  font-size: 26rpx;
}
.info-icon {
  color: #3498db;
}
.card-title {
  display: flex;
  align-items: center;
  gap: 12rpx;
  font-size: 30rpx;
  font-weight: 600;
  margin-bottom: 16rpx;
}
.status-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16rpx 0;
  border-bottom: 1rpx solid #e9ecef;
  font-size: 28rpx;
}
.status-item:last-child {
  border-bottom: none;
}
.status-label {
  font-weight: 500;
}
.status-value {
  display: flex;
  align-items: center;
  gap: 8rpx;
}
.status-success { color: #2ecc71; }
.status-error { color: #e74c3c; }
.status-warning { color: #f1c40f; }
.status-default { color: #909399; }

.distance-info {
  text-align: center;
  padding: 24rpx;
  background: #fff;
  border-radius: 32rpx;
  margin-bottom: 24rpx;
}
.distance-value {
  font-size: 48rpx;
  font-weight: 700;
  color: #3498db;
}
.distance-label {
  font-size: 26rpx;
  color: #6c757d;
  margin-top: 8rpx;
}
.alert-custom {
  border-radius: 24rpx;
  padding: 24rpx;
  margin-bottom: 24rpx;
  display: flex;
  align-items: center;
  gap: 16rpx;
  font-size: 26rpx;
  color: #fff;
}
.alert-success { background: #2ecc71; }
.alert-error { background: #e74c3c; }
.alert-warning { background: #f1c40f; }

.checkin-actions {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  margin-bottom: 30rpx;
}
.checkin-btn /deep/ .u-btn, .recheck-btn /deep/ .u-btn {
  height: 90rpx;
}
.btn-icon {
  margin-right: 12rpx;
}
.history-empty {
  text-align: center;
  color: #999;
  padding: 30rpx 0;
  font-size: 26rpx;
}
.history-list {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}
.history-item {
  display: flex;
  justify-content: space-between;
  font-size: 24rpx;
  color: #666;
  background: #f8f9fa;
  padding: 12rpx;
  border-radius: 12rpx;
}
</style> 