// nova-werun/pages/home/sport/sport-start/index.js
const Parse = getApp().Parse;
const company = getApp().globalData.company;
const uid = Parse.User.current()?.id
let request = require('../../../../../utils/request')
const dateF = require("../../../../../utils/date")


let {
  statusBarHeight
} = wx.getSystemInfoSync()
let custom = wx.getMenuButtonBoundingClientRect()
let customHeight = custom.height

Page({
  /**
   * 页面的初始数据
   */
  data: {
    navheight: 0, //导航高度px
    isStop: false, //计时是否暂停
    longitude: 0, //经度
    latitude: 0, //纬度
    markers: [], //地图标记点
    showPermissions: true, //权限弹框-开
    journey: 0, //运动的路程-米
    calorie: 0, //卡路里-千卡
    pace: 0, //配速-min/km
    timer: 0, //已记的时长-秒
    status: 'noStart', //运动状态 'noStart'未开始,'inSports'运动中,'paused'暂停
    percentage: '', //长按结束运动百分比
    endHaloInterval: null, //光环计时器
    endHaloStartDate: null, //光环开始时间戳
    endHaloEndDate: null, //光环结束时间戳
    isRefershLaLo: true, //是否刷新经纬度
    stage: 'start', //运动过程 start,progress,end
    actData: null, //运动数据
    formattedTime: '00:00:00', // 用于存储格式化后的时间
    step: 0, //运动步数
    type: 'walk', //运动类型-步行
    actDataList: [], //未运动结束数据
    isShowActDataList: false, //是否展示未运动结束的数据
    checkActDataId: null, //点击的未结束运动
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: async function (options) {
    wx.offLocationChange()
    this.setData({
      navheight: customHeight + statusBarHeight + 5,
      type: options.type || 'walk', //运动方式 run/walk
      a_reg: options.a_reg || '', //所属报名记录 ActivityRegister.id
    })

    console.log(options)
    this.getActivityData()
    this.beforeUnload()
    // this.getWeRun()
  },


  /**获取运动数据 */
  async getActivityData() {
    let {
      a_reg,
      type
    } = this.data

    let query = new Parse.Query('ActivityData')
    query.equalTo('company', company)
    query.equalTo('user', uid)
    query.equalTo('type', type)
    query.notEqualTo('isDeleted', true)
    query.descending('createdAt')
    if (a_reg) { //如果传递了报名记录-直接进行这个运动
      console.log('如果传递了报名记录-直接进行这个运动')
      let actData
      query.equalTo('actRegister', a_reg)
      actData = await query.first()
      if (actData?.get('status') == 'end') {
        wx.showToast({
          title: '已结算成绩',
          icon: 'none'
        })
        wx.navigateBack({
          delta: 1
        })
        return
      }
      if (!actData?.id) {
        console.log('未查询出运动数据')
        let regQuery = new Parse.Query('ActivityRegister')
        let act_reg = await regQuery.get(a_reg)
        await this.creatActDateFun(act_reg)
        return
      } else {
        console.log('运动未结束')
        wx.showToast({
          title: '运动未结束',
          icon: 'none'
        })
        await this.assignmentFun(actData?.id)
        this.setData({
          actData
        })
      }
    } else { //未传递-显示当前类型（run/walk）所有未结束的运动
      console.log('/未传递-显示当前类型所有未结束的运动')
      let actDataCount
      actDataCount = await query.count()
      if (actDataCount <= 0 || !actDataCount) {
        await this.creatActDateFun()
        return
      } else {
        let sql = `SELECT act_d."objectId",act_d."startDate",act_d."createdAt",act."title",act_r."booking",act."endDate" AS act_end
        FROM "ActivityData" act_d
        LEFT JOIN "Activity" act ON act."objectId" = act_d."activity"
        LEFT JOIN "ActivityRegister" act_r ON act_r."objectId" = act_d."actRegister" AND act_r."isDeleted" IS NOT TRUE
        WHERE act_d."company"='${company}'
        AND act_d."user"='${uid}'
        AND act_d."status" NOT IN ('end')
        AND act_d."type"='${type}'
        AND act_d."isDeleted" IS NOT TRUE
        ORDER BY act_d."startDate" DESC
        LIMIT 20`
        let actDataList = await request.customSQL(sql) || []
        if (actDataList?.length <= 0 || !actDataList) {
          await this.creatActDateFun()
          return
        } else {
          console.log(actDataList)
          let actDataList2 = actDataList?.map(item => {
            let obj = item
            if (item.startDate || item.createdAt) obj.sport_startDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.startDate || item.createdAt)
            if (item.booking?.from?.iso) obj.booking.fromDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.booking.from.iso)
            /**该运动是否可继续 */
            let isAttend = false
            let now = new Date()
            if (item.act_end) {
              let end = new Date(item.act_end)
              isAttend = now < end
              obj.actEndDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.act_end)
              console.log('end', end, isAttend)
            }
            if (item.booking?.to?.iso) {
              let to = new Date(item.booking?.to?.iso)
              isAttend = now < to
              obj.booking.toDate = dateF.formatTime("YYYY.mm.dd HH:MM", item.booking.to.iso)
              console.log('to', to, isAttend)
            }
            obj.isAttend = isAttend
            return obj
          })
          this.setData({
            actDataList: actDataList2,
            isShowActDataList: true,
          })
          console.log(actDataList2)
        }
      }
    }
  },
  /**关闭未结束运动弹框 */
  closeActDataList() {
    this.creatActDateFun()
    this.setData({
      isShowActDataList: false
    })
  },
  /**点击未结束运动 */
  async checkActEndDate(e) {
    let {
      actDataList,
      type
    } = this.data
    console.log(e)
    let {
      index
    } = e.currentTarget.dataset
    let act_end_data_id = actDataList[index].objectId
    let log_query = new Parse.Query('ActivityRunLog')
    log_query.equalTo('company', company)
    log_query.equalTo('user', uid)
    log_query.equalTo('actData', act_end_data_id)
    log_query.equalTo('type', type)
    log_query.notEqualTo('isDeleted', true)
    log_query.descending('createdAt')
    let log = await log_query.first()
    let that = this
    console.log(actDataList[index])
    if (actDataList[index].isAttend || !actDataList[index].title) {
      wx.showModal({
        title: `${actDataList[index].title||'日常运动'}`,
        content: `${actDataList[index].sport_startDate||'未知时间'}开始运动，已运动 ${log?.get('distance')||0} m, ${log?.get('steps')||0} 步，消耗 ${log?.get('burnCalories')||0} 千卡,是否继续进行？`,
        success: async (res) => {
          if (res.confirm) {
            console.log('用户点击确定')

            await that.assignmentFun(act_end_data_id)
            that.setData({
              isShowActDataList: false
            })
          } else if (res.cancel) {
            console.log('用户点击取消')
          }
        }
      })
    } else if (!actDataList[index].isAttend) {
      wx.showModal({
        title: `${actDataList[index].title||'日常运动'}`,
        content: `${actDataList[index].sport_startDate||'未知时间'}开始运动，已运动 ${log?.get('distance')||0} m, ${log?.get('steps')||0} 步，消耗 ${log?.get('burnCalories')||0} 千卡。当前报名记录已过期，可查看其他报名或其他活动。`,
        showCancel: false,
        confirmText: '结束运动',
        success: async (res) => {
          if (res.confirm) {
            await that.setEndActDateFun(act_end_data_id)
            actDataList.splice(index, 1)
            that.setData({
              actDataList
            })
            wx.showToast({
              title: '已结束',
              icon: 'none'
            })
          }
        }
      })
    }

  },
  /**继续未结束运动 */
  async goOnactEndDate() {
    let {
      checkActDataId
    } = this.data
    await this.assignmentFun(checkActDataId)
    this.setData({
      isShowActDataList: false
    })
  },
  /**全部结束 */
  async itemId() {
    wx.showModal({
      content: '确认结束列表内显示的全部运动吗？',
      success:async (res)=> {
        if (res.confirm) {
          wx.showLoading({
            title: '...',
          })
          let {
            actDataList
          } = this.data
          for (let i in actDataList) {
            let itemId = actDataList[i].objectId
            await this.setEndActDateFun(itemId)
          }
          this.creatActDateFun()
          wx.hideLoading()
          this.setData({
            isShowActDataList: false
          })
        }
      }
    })

  },

  /**
   * 新建运动数据
   * @param {*} act_reg 活动报名记录 Parse.Object
   */
  async creatActDateFun(act_reg) {
    let {
      type
    } = this.data
    let ActivityData = Parse.Object.extend('ActivityData')
    let actData = new ActivityData()
    if (act_reg?.id && act_reg?.get('activity')?.id) {
      actData.set('activity', {
        __type: 'Pointer',
        className: 'Activity',
        objectId: act_reg?.get('activity')?.id
      })
      actData.set('actRegister', {
        __type: 'Pointer',
        className: 'ActivityRegister',
        objectId: act_reg?.id
      })
    }
    actData.set('company', {
      __type: 'Pointer',
      className: 'Company',
      objectId: company
    })
    actData.set('user', {
      __type: 'Pointer',
      className: '_User',
      objectId: uid
    })
    actData.set('type', type)
    actData.set('startDate', new Date())
    console.log('未查询出显示这个', actData)
    await this.setData({
      actData
    })
  },
  /**
   * 运动数据赋值操作
   * @param {*} actDataId 运动数据id
   */
  async assignmentFun(actDataId) {
    let {
      type
    } = this.data
    let log_query = new Parse.Query('ActivityRunLog')
    log_query.equalTo('company', company)
    log_query.equalTo('user', uid)
    log_query.equalTo('actData', actDataId)
    log_query.equalTo('type', type)
    log_query.notEqualTo('isDeleted', true)
    log_query.descending('createdAt')
    let log = await log_query.first()
    let data_query = new Parse.Query('ActivityData')
    let actData = await data_query.get(actDataId)
    this.setData({
      actData
    })
    this.setData({
      stage: 'progress',
      status: 'paused',
      isRefershLaLo: true,
      timer: log?.get('sportDate') || 0,
      pace: log?.get('matchSpeed') || 0,
      calorie: log?.get('burnCalories') || 0,
      journey: log?.get('distance') || 0,
      step: log?.get('steps' || 0),
      formattedTime: this.formatTime(log?.get('sportDate') || 0),

    })
  },

  /**
   * 结束运动
   * @param {*} actDataId 运动数据id
   */
  async setEndActDateFun(actDataId) {
    let {
      type
    } = this.data
    let log_query = new Parse.Query('ActivityRunLog')
    log_query.equalTo('company', company)
    log_query.equalTo('user', uid)
    log_query.equalTo('actData', actDataId)
    log_query.equalTo('type', type)
    log_query.notEqualTo('isDeleted', true)
    log_query.descending('createdAt')
    let log = await log_query.first()
    let data_query = new Parse.Query('ActivityData')
    let data = await data_query.get(actDataId)
    log?.get('steps') && data.set('steps', log?.get('steps') || 0)
    log?.get('distance') && data.set('distance', log?.get('distance') || 0)
    log?.get('matchSpeed') && data.set('matchSpeed', log?.get('matchSpeed') || 0)
    log?.get('sportDate') && data.set('sportDate', log?.get('sportDate') || 0)
    log?.get('burnCalories') && data.set('burnCalories', log?.get('burnCalories') || 0)
    data.set('endDate', log?.get('createdAt') || new Date())
    data.set('status', 'end')
    await data.save()
    if (log?.id) {
      log.set('stage', 'end')
      await log.save()
    }
  },

  /**监听页面退出事件 */
  beforeUnload() {
    wx.enableAlertBeforeUnload({ //获取不到"确认/取消"按钮事件
      message: '未开始运动、暂停运动中以及运动结束请忽略本提示。若当前正在运动，退出本页面将在微信后台记录。关闭小程序、关闭小程序运行权限、长时间未进入小程序、手机退出微信等操作都将暂停记录。',
    })
  },

  /**检查用户授权状况 */
  examineAuthorization() {
    let that = this
    wx.getSetting({
      success(res) {
        console.log(res)
        if (!res.authSetting['scope.userLocation'] || !res.authSetting['scope.userLocationBackground']) {
          that.openPermissions()
        } else {
          that.closePermissions()
        }
      }
    })
  },
  /**权限弹框-开 */
  openPermissions() {
    this.setData({
      showPermissions: true
    })
  },
  /**权限弹框-关 */
  async closePermissions() {
    await this.setData({
      showPermissions: false
    })
    let {
      type
    } = this.data
    let tip = '运动'
    switch (type) {
      case 'run':
        tip = '跑步'
        break;
      case 'walk':
        tip = '步行'
        break;
      default:
        break;
    }
    wx.showToast({
      title: `开启${tip}之旅吧~`,
      icon: 'none'
    })
    this.refersh()
  },
  /**打开微信权限设置页面 */
  openWxSetting() {
    wx.openSetting({
      success(res) {
        console.log(res.authSetting)
      },
      fail(err) {
        console.log(err)
      }
    })
  },


  async refersh() {
    this.startSports()
  },
  /**刷新初始位置 */
  startSports() {
    let that = this
    wx.getLocation({
      type: 'gcj02',
      success: async (res) => {
        console.log(res)
        let {
          longitude,
          latitude,
        } = res
        let markers = [{
          iconPath: "https://file-cloud.fmode.cn/13WZ0W7u3l/20240724/7ebg0k104325941.png",
          width: 20,
          height: 20,
          longitude: longitude,
          latitude: latitude,
          id: 0,
        }]
        await that.setData({
          longitude,
          latitude,
          markers
        })
      },
      fail: (err) => {
        console.error(err);
        wx.showToast({
          title: '获取位置失败',
          icon: 'none'
        });
      }
    });
  },

  /**
   * 位置监听开启
   */
  async setTime() {
    await this.setData({
      status: 'inSports',
      isRefershLaLo: true,
    })
    let that = this
    wx.offLocationChange()
    setTimeout(() => {
      that.monitorLocationChange()
      console.log('执行经纬度获取')
    }, 1000);
  },
  /**开始运动 */
  async startInterval() {
    await this.setData({
      longitude: 0, //经度
      latitude: 0, //纬度
      markers: [], //地图标记点
      journey: 0, //运动的路程-米
      step: 0,
      calorie: 0, //卡路里-千卡
      pace: 0, //配速-min/km
      interval: null, //计时器
      timer: 0, //已记的时长-秒
      formattedTime: '00:00:00', // 用于存储格式化后的时间
      status: 'inSports', //运动中
      stage: 'start',
    })
    //===================这里在getActivityData方法设置=====================
    // let {
    //   type,actData
    // } = this.data
    // if(!actData){
    //   let ActivityData = Parse.Object.extend('ActivityData')
    //   actData = new ActivityData()
    //   actData.set('company', {
    //     __type: 'Pointer',
    //     className: 'Company',
    //     objectId: company
    //   })
    //   actData.set('user', {
    //     __type: 'Pointer',
    //     className: '_User',
    //     objectId: uid
    //   })
    //   actData.set('startDate', new Date())
    //   actData.set('type', type)
    // }
    // this.setData({
    //   actData
    // })
    setTimeout(() => {
      this.setTime()
    }, 1000);
  },

  /** 暂停运动*/
  async pausedInterval() {
    wx.offLocationChange()
    this.setData({
      status: 'paused',
    })
    let {
      actData,
      timer,
      pace,
      calorie,
      journey,
      step
    } = this.data
    console.log(actData)
    actData.set('status', 'paused')
    actData.set('distance', parseFloat(journey))
    actData.set('steps', parseInt(step))
    actData.set('sportDate', parseInt(timer))
    actData.set('matchSpeed', parseFloat(pace))
    actData.set('burnCalories', parseFloat(calorie))
    await actData.save()
    console.log('暂停')
  },
  /**继续运动 */
  goOn() {
    this.setTime()
  },
  /**长按结束-起 */
  onStart() {
    let endHaloStartDate = new Date()
    this.setData({
      endHaloStartDate
    })
    let {
      endHaloInterval
    } = this.data
    endHaloInterval = setInterval(() => {
      let now = new Date()
      let elapsedTime = now - endHaloStartDate
      let percentage = Math.min((elapsedTime / 4000) * 100, 100);
      this.setData({
        percentage: `conic-gradient(from 0deg, #015EEA ${percentage}%, white 0%)`,
      });
    }, 40);
    this.setData({
      endHaloInterval
    })
  },
  /**长按结束-终 */
  async onEnd() {
    let {
      endHaloStartDate,
      endHaloInterval,
      actData,
    } = this.data
    let endHaloEndDate = new Date()
    let a = endHaloEndDate - endHaloStartDate
    if (a >= 4000) { //长按4秒
      clearInterval(endHaloInterval)
      wx.offLocationChange()
      wx.stopLocationUpdate({
        success: (res) => {
          console.log('后台定位已停止');
        },
        fail: (res) => {
          console.error('停止后台定位失败', res);
        }
      });

      await this.setData({
        status: 'noStart',
        endHaloStartDate: null,
        endHaloStartDate: null,
        percentage: '',
        endHaloInterval: null,
        stage: 'end'
      })
      await this.setActivityRunLog()
      let {
        actData,
        timer,
        pace,
        calorie,
        journey,
        step
      } = this.data
      console.log(actData)
      actData.set('status', 'end')
      actData.set('endDate', new Date())
      actData.set('distance', parseFloat(journey))
      actData.set('sportDate', parseInt(timer))
      actData.set('steps', parseInt(step))
      actData.set('matchSpeed', parseFloat(pace))
      actData.set('burnCalories', parseFloat(calorie))
      await actData.save()
      wx.showToast({
        title: '已结束本次运动',
        icon: 'none'
      })
    } else {
      clearInterval(endHaloInterval)
      this.setData({
        endHaloStartDate: null,
        endHaloStartDate: null,
        percentage: '',
        endHaloInterval: null,
      })
    }
  },
  /**监听位置变化 */
  monitorLocationChange() {
    let that = this
    wx.startLocationUpdateBackground({
      success: (res) => {
        wx.onLocationChange(async (change_res) => {
          console.log(change_res.longitude, change_res.latitude)
          let {
            longitude, //经度
            latitude, //纬度
            journey, //路程-m
            calorie, //卡路里-千卡
            pace, //配速-min/km
            timer, //计时
            isRefershLaLo,
          } = that.data
          timer = timer + 1 || 1
          let formattedTime = that.formatTime(parseInt(timer))
          if (isRefershLaLo) {
            longitude = change_res.longitude
            latitude = change_res.latitude
            let {
              actData
            } = that.data
            console.log(actData)
            actData.set('status', 'inSports')
            await actData.save()
            that.setData({
              isRefershLaLo: false,
              actData
            })
          }
          let distance = that.haversine(latitude, longitude, change_res.latitude, change_res.longitude)?.toFixed(2)
          journey = (parseFloat(journey || 0) + parseFloat(distance || 0))?.toFixed(2)
          calorie = that.getCalorie(50, journey) //体重50kg
          pace = distance ? (distance * 6) / 100 : 0
          let step = parseInt(parseInt(journey) / 0.6)
          await that.setData({
            formattedTime,
            step,
            timer,
            journey,
            longitude: change_res.longitude,
            latitude: change_res.latitude,
            calorie,
            pace: parseFloat(pace)?.toFixed(2),
          })
          let time = timer % 5
          if (time === 0) {
            await that.setActivityRunLog()
            that.setData({
              stage: 'progress'
            })
            // console.log('执行保存数据')
          }
        });
      },
      fail: (res) => {
        this.openPermissions()
      }
    });
  },

  /**微信步数获取-弃用-使用0.6米/步 */
  async getWeRun() {
    wx.login({
      success: (res) => {
        console.log(res)
        wx.request({
          url: `https://api.weixin.qq.com/sns/jscode2session?appid=wxe6ecc0193c09696c&secret=0ee1172c8729c547d33f0ab45715d7ec&js_code=${res.code}&grant_type=authorization_code`,
          method: 'GET',
          success(res) {
            console.log(res)
            let session_key = res.data.session_key
            wx.getWeRunData({
              success: async (res) => {
                console.log(res)
                console.log(res.encryptedData)
                console.log(res.iv)
                wx.request({
                  url: 'http://localhost:7337/api/o2o/wxrun',
                  data: {
                    app_id: 'wxe6ecc0193c09696c',
                    session_key: session_key,
                    encrypted_data: res.encryptedData,
                    iv: res.iv
                  },
                  method: 'POST',
                  success(res) {
                    console.log(res)
                  },
                })
              },
              fail: (err) => {
                console.log(err)
              }
            })
          },
        })
      },
    })

  },


  toRadians(degrees) {
    return degrees * (Math.PI / 180);
  },
  /**
   * 两点距离-米
   * @param {*} lat1 纬1
   * @param {*} lon1 经1
   * @param {*} lat2 纬2
   * @param {*} lon2 经2
   */
  haversine(lat1, lon1, lat2, lon2) {
    const R = 6371000;
    const φ1 = this.toRadians(parseFloat(lat1));
    const φ2 = this.toRadians(parseFloat(lat2));
    const Δφ = this.toRadians(parseFloat(lat2) - parseFloat(lat1));
    const Δλ = this.toRadians(parseFloat(lon2) - parseFloat(lon1));
    const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
      Math.cos(φ1) * Math.cos(φ2) *
      Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    const distance = R * c;
    return distance;
  },
  /**
   * 计算卡路里-千卡
   * @param {*} weight 体重kg
   * @param {*} distance 距离m
   */
  getCalorie(weight, distance) {
    const caloriesBurned = weight * distance * 0.75;
    return (caloriesBurned / 1000).toFixed(2);
  },

  /**记录运动过程-每5秒保存一次 */
  async setActivityRunLog() {
    let {
      actData,
      stage,
      longitude, //经度
      latitude, //纬度
      journey, //运动的路程-米
      step,
      calorie, //卡路里-千卡
      pace, //配速-min/km
      timer, //已记的时长-秒
      type, //步行/跑步
    } = this.data
    let ActivityRunLog = Parse.Object.extend('ActivityRunLog')
    let log = new ActivityRunLog()

    log.set('company', {
      __type: 'Pointer',
      className: 'Company',
      objectId: company
    })
    log.set('user', {
      __type: 'Pointer',
      className: '_User',
      objectId: uid
    })
    log.set('actData', {
      __type: 'Pointer',
      className: 'ActivityData',
      objectId: actData?.id
    })
    log.set('stage', stage)
    log.set('type', type)
    log.set('sportDate', parseInt(timer) || 0)
    log.set('burnCalories', parseFloat(calorie || '0'))
    log.set('matchSpeed', parseFloat(pace || '0'))
    log.set('distance', parseFloat(journey || '0'))
    log.set('steps', step)
    let location = new Parse.GeoPoint({
      latitude: latitude,
      longitude: longitude
    });
    log.set('location', location)
    await log.save()
  },

  /**时间格式显示 */
  formatTime: function (seconds) {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;

    // 格式化为两位数
    const formattedHours = String(hours).padStart(2, '0');
    const formattedMinutes = String(minutes).padStart(2, '0');
    const formattedSeconds = String(secs).padStart(2, '0');

    return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
  },



  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    this.examineAuthorization()
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {},

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {},

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
})