<template>
  <view class="checkin-page">
    <view class="checkin-container">
      <!-- 课程信息卡片 -->
      <view class="course-card">
        <view class="course-title">{{ course.theme?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.date:'' }} - {{ course.period?course.period:'' }}</text>
          </view>
          <view class="info-item">
            <u-icon name="map-fill" class="info-icon"></u-icon>
            <text>{{ course.address?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" v-if="courseContentList.length > 0">
        <h6 class="card-title">
          <u-icon name="order" class="title-icon"></u-icon>
          当前其他可签到课程
        </h6>
        <view v-for="item in courseContentList" class="history-list">
          <view class="history-item">
            <text>{{ item.theme }}</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>
        <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="handleRecheckClick"
        >
          <u-icon :name="hasLocationPermission ? 'reload' : 'location'" class="btn-icon"></u-icon>
          {{ hasLocationPermission ? '重新定位' : '获取定位权限' }}
        </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 {
      courseContentList:[],
      course_content_id:'',
      course: {},
      userLocation: null,
      distance: null,
      canCheckin: false,
      hasCheckedIn: false,
      locationStatus: { type: 'default', text: '未定位' },
      rangeStatus: { type: 'default', text: '未计算' },
      alertInfo: { type: '', message: '' },
      checkinHistory: [],
      hasLocationPermission: false,
      // 坐标系统配置
      coordinateConfig: {
        // 后端返回的坐标系统：'wgs84' 或 'gcj02'
        backendSystem: 'wgs84',
        // 是否启用坐标转换
        enableConversion: true
      }
    };
  },
  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:", options)
    this.course_content_id = options?.course_content_id
    
    // 测试坐标转换功能
    this.testCoordinateConversion()
    
    // 进入页面：先检查定位权限
    console.log("开始检查权限...")
    this.checkPermissionAndInit();
  },
  methods: {
  //获取同一天的课程列表
  async getCourseList() {
    const res = await this.$u.api.myCourseContent({
      date: this.course.date
    });
    
    // 检查返回的数据是否为空
    if (!res.list || res.list.length === 0) {
      // 如果没有课程数据，禁用签到按钮
      this.canCheckin = false;
      this.courseContentList = [];
      return;
    }
    
    this.courseContentList = res.list.filter(item => item.id != this.course.id)
  },
    async checkPermissionAndInit() {
      console.log('开始检查权限...')
      let granted = false
      try {
        const setting = await new Promise((resolve) => {
          uni.getSetting({ success: resolve, fail: () => resolve({}) })
        })
        console.log('获取设置结果:', setting)
        const auth = setting?.authSetting || {}
        console.log('权限设置:', auth)
        granted = !!auth['scope.userLocation']
        this.hasLocationPermission = granted
        console.log('权限检测结果:', granted, 'hasLocationPermission:', this.hasLocationPermission)
      } catch (e) {
        console.log('权限检测异常:', e)
        this.hasLocationPermission = false
      }
      
      // 无论权限状态如何，都先获取课程信息
      console.log('开始获取课程信息...')
      await this.getCourse()
      await this.signGet()
      
      if (!granted) {
        console.log('无权限，设置状态为未获取定位权限')
        this.locationStatus = { type: 'warning', text: '未获取定位权限' }
        this.rangeStatus = { type: 'default', text: '未计算' }
        this.canCheckin = false
        // 即使没有权限，也显示课程信息，但不进行定位相关操作
        return
      }
      
      // 有权限则继续完整的签到流程
      console.log('有权限，开始完整签到流程')
      await this.initializeCheckin()
    },
    handleRecheckClick() {
      console.log('按钮被点击，当前权限状态:', this.hasLocationPermission)
      if (this.hasLocationPermission) {
        console.log('有权限，执行重新定位')
        this.initializeCheckin()
      } else {
        console.log('无权限，请求定位权限')
        this.requestLocationPermission()
      }
    },
    
    requestLocationPermission() {
      console.log('开始请求定位权限...')
      uni.authorize({
        scope: 'scope.userLocation',
        success: () => {
          console.log('定位权限授权成功')
          this.hasLocationPermission = true
          this.locationStatus = { type: 'warning', text: '定位中...' }
          this.initializeCheckin()
        },
        fail: (err) => {
          console.log('定位权限授权失败:', err)
          uni.openSetting({
            success: (res) => {
              const ok = res?.authSetting && res.authSetting['scope.userLocation']
              if (ok) {
                console.log('通过设置页面获取定位权限成功')
                this.hasLocationPermission = true
                this.locationStatus = { type: 'warning', text: '定位中...' }
                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
      let lat = data.latitude || data.lat
      let lng = data.longitude || data.lng
      
      // 根据配置进行坐标转换
      let convertedLng = lng
      let convertedLat = lat
      
      if (this.coordinateConfig.enableConversion && this.coordinateConfig.backendSystem !== 'gcj02') {
        const [converted] = this.convertCoordinates(lng, lat, this.coordinateConfig.backendSystem, 'gcj02')
        convertedLng = converted[0]
        convertedLat = converted[1]
      }
      
        console.log('原始坐标:', { lng, lat, system: this.coordinateConfig.backendSystem })
        console.log('转换后坐标:', { lng: convertedLng, lat: convertedLat, system: 'gcj02' })
      
      this.course = {
        ...this.course,
        ...data,
        location: { 
          lat: convertedLat, 
          lng: convertedLng,
          originalLat: lat,
          originalLng: lng,
          coordinateSystem: 'gcj02'
        },
        allowedDistance: 500
      }
      this.getCourseList()
    },
    // 获取签到记录
    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 {
        // 用户位置是GCJ-02坐标系（uni.getLocation返回的）
        const userLat = this.userLocation.lat
        const userLng = this.userLocation.lng
        
        console.log('用户位置坐标:', { lat: userLat, lng: userLng, system: 'gcj02' })
        console.log('课程位置坐标:', { 
          lat: this.course.location.lat, 
          lng: this.course.location.lng, 
          system: this.course.location.coordinateSystem 
        })
        
        const res = await this.$u.api.signDistance({
          course_content_id: this.course_content_id,
          latitude: userLat,
          longitude: userLng
        })
        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(batch_sign = 0) {
      try {
        const res = await this.$u.api.signCheck({
          course_content_id: this.course_content_id,
          latitude: this.userLocation.lat,
          longitude: this.userLocation.lng,
          batch_sign: batch_sign // 新增参数
        });
        
        // 根据返回结果更新本地状态
        this.hasCheckedIn = true
        this.canCheckin = false
        
        // 根据批量签到状态显示不同的成功提示
        if (batch_sign === 1) {
          this.alertInfo = { type: 'success', message: '批量签到成功！已签到所有课程' }
          uni.showToast({ title: '批量签到成功！', icon: 'success' });
        } else {
          this.alertInfo = { type: 'success', message: '签到成功' }
          uni.showToast({ title: '签到成功！', icon: 'success' });
        }
        
        // 可选：重新拉取签到记录
        try { await this.signGet() } catch (e) {}
      } catch (e) {
        console.error('签到失败:', e);
        uni.showToast({ title: '签到失败', icon: 'none' });
      }
    },
    async initializeCheckin() {
      this.locationStatus = { type: 'warning', text: '定位中...' };
      this.rangeStatus = { type: 'default', text: '未计算' };
      this.canCheckin = false;
      this.distance = null;
      this.alertInfo = { type: '', message: '' };
      try {
        // 1. 定位
        const loc = await this.getLocation()
        console.log(loc)
        this.userLocation = loc
        this.locationStatus = { type: 'success', text: '定位成功' };
        // 2. 距离与状态
        await this.signDistance()
      } catch (e) {
        this.locationStatus = { type: 'error', text: '定位失败' };
        this.rangeStatus = { type: 'error', text: '无法计算' };
        this.alertInfo = { type: 'error', message: '获取信息或位置失败，请检查权限和网络。' };
      }
    },
    // 坐标转换工具方法
    // WGS84 转 GCJ-02 (火星坐标系)
    wgs84ToGcj02(lng, lat) {
      const a = 6378245.0;
      const ee = 0.00669342162296594323;
      
      if (this.outOfChina(lng, lat)) {
        return [lng, lat];
      }
      
      let dLat = this.transformLat(lng - 105.0, lat - 35.0);
      let dLng = this.transformLng(lng - 105.0, lat - 35.0);
      
      const radLat = lat / 180.0 * Math.PI;
      let magic = Math.sin(radLat);
      magic = 1 - ee * magic * magic;
      const sqrtMagic = Math.sqrt(magic);
      
      dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI);
      dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);
      
      return [lng + dLng, lat + dLat];
    },
    
    // GCJ-02 转 WGS84
    gcj02ToWgs84(lng, lat) {
      if (this.outOfChina(lng, lat)) {
        return [lng, lat];
      }
      
      let dLat = this.transformLat(lng - 105.0, lat - 35.0);
      let dLng = this.transformLng(lng - 105.0, lat - 35.0);
      
      const radLat = lat / 180.0 * Math.PI;
      let magic = Math.sin(radLat);
      magic = 1 - 0.00669342162296594323 * magic * magic;
      const sqrtMagic = Math.sqrt(magic);
      
      dLat = (dLat * 180.0) / ((6378245.0 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic) * Math.PI);
      dLng = (dLng * 180.0) / (6378245.0 / sqrtMagic * Math.cos(radLat) * Math.PI);
      
      return [lng - dLng, lat - dLat];
    },
    
    // 判断是否在中国境内
    outOfChina(lng, lat) {
      return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
    },
    
    // 转换纬度
    transformLat(lng, lat) {
      let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
      ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin(lat / 3.0 * Math.PI)) * 2.0 / 3.0;
      ret += (160.0 * Math.sin(lat / 12.0 * Math.PI) + 320 * Math.sin(lat * Math.PI / 30.0)) * 2.0 / 3.0;
      return ret;
    },
    
    // 转换经度
    transformLng(lng, lat) {
      let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lat));
      ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin(lng / 3.0 * Math.PI)) * 2.0 / 3.0;
      ret += (150.0 * Math.sin(lng / 12.0 * Math.PI) + 300.0 * Math.sin(lng / 30.0 * Math.PI)) * 2.0 / 3.0;
      return ret;
    },
    
    // 统一坐标转换方法
    convertCoordinates(lng, lat, fromSystem = 'gcj02', toSystem = 'gcj02') {
      if (fromSystem === toSystem) {
        return [lng, lat];
      }
      
      if (fromSystem === 'wgs84' && toSystem === 'gcj02') {
        return this.wgs84ToGcj02(lng, lat);
      }
      
      if (fromSystem === 'gcj02' && toSystem === 'wgs84') {
        return this.gcj02ToWgs84(lng, lat);
      }
      
      // 如果是从WGS84到其他坐标系，先转到GCJ-02
      if (fromSystem === 'wgs84') {
        const gcj02 = this.wgs84ToGcj02(lng, lat);
        return this.convertCoordinates(gcj02[0], gcj02[1], 'gcj02', toSystem);
      }
      
      return [lng, lat];
    },
    
    // 测试坐标转换（开发调试用）
    testCoordinateConversion() {
      // 北京天安门坐标示例
      const wgs84Lng = 116.397128
      const wgs84Lat = 39.916527
      
      console.log('=== 坐标转换测试 ===')
      console.log('WGS84坐标:', { lng: wgs84Lng, lat: wgs84Lat })
      
      const gcj02 = this.wgs84ToGcj02(wgs84Lng, wgs84Lat)
      console.log('转换为GCJ-02:', { lng: gcj02[0], lat: gcj02[1] })
      
      const backToWgs84 = this.gcj02ToWgs84(gcj02[0], gcj02[1])
      console.log('转换回WGS84:', { lng: backToWgs84[0], lat: backToWgs84[1] })
      
      const diff = {
        lng: Math.abs(backToWgs84[0] - wgs84Lng),
        lat: Math.abs(backToWgs84[1] - wgs84Lat)
      }
      console.log('转换精度误差:', diff)
      console.log('=== 测试结束 ===')
    },
    
    // 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
      
      // 检查是否有其他可签到课程
      if (this.courseContentList.length > 0) {
        // 弹出确认对话框询问是否要一次性合并签到所有课程
        console.log(this.courseContentList)
        uni.showModal({
          title: '批量签到提示',
          content: `检测到您还有${this.courseContentList.length}门课程可以签到，是否要一次性合并签到所有课程？`,
          confirmText: '批量签到',
          cancelText: '单个签到',
          success: async (res) => {
            if (res.confirm) {
              // 用户选择合并签到
              await this.signCheck(1);
            } else {
              // 用户选择仅签到当前课程
              await this.signCheck(0);
            }
          },
          fail: (err) => {
            console.log(err)
          }
        });
      } else {
        // 没有其他课程，直接签到
        await this.signCheck(0);
      }
    },
    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> 