/**
 * @class UserSessionLog 用户会话日志模型
 */
const BaseMod = require('./base')
const Platform = require('./platform')
const Channel = require('./channel')
const {
	DateTime
} = require('../lib')
module.exports = class UserSessionLog extends BaseMod {
	constructor() {
		super()
		this.tableName = 'user-session-logs'
	}

	/**
	 * 用户会话日志数据填充
	 * @param {Object} params 上报参数
	 */
	async fill(params) {

		if (!params.sid) {
			return {
				code: 200,
				msg: 'Not found session log'
			}
		}

		if (!params.uid) {
			return {
				code: 200,
				msg: 'Parameter "uid" not found'
			}
		}

		const dateTime = new DateTime()
		const platform = new Platform()
		const channel = new Channel()

		//获取当前页面信息
		if (!params.page_id) {
			const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj)
			if (!pageInfo || pageInfo.length === 0) {
				return {
					code: 300,
					msg: 'Not found this entry page'
				}
			}
			params.page_id = pageInfo._id
		}

		const nowTime = dateTime.getTime()

		const fillParams = {
			appid: params.ak,
			version: params.v ? params.v : '',
			platform: platform.getPlatformCode(params.ut, params.p),
			channel: channel.getChannelCode(params),
			session_id: params.sid,
			uid: params.uid,
			last_visit_time: nowTime,
			entry_page_id: params.page_id,
			exit_page_id: params.page_id,
			page_count: 0,
			event_count: 0,
			duration: 1,
			is_finish: 0,
			create_time: nowTime,
		}

		const res = await this.insert(this.tableName, fillParams)

		if (res && res.id) {
			return {
				code: 0,
				msg: 'success'
			}
		} else {
			return {
				code: 500,
				msg: 'User session log filled error'
			}
		}
	}

	/**
	 * 检测用户会话是否有变化，并更新
	 * @param {Object} params 校验参数 - sid:基础会话编号 uid:用户编号 last_visit_user_id:基础会话中最近一个访问用户的编号
	 */
	async checkUserSession(params) {
		if (!params.sid) {
			return {
				code: 200,
				msg: 'Not found session log'
			}
		}

		if (!params.uid) {
			//用户已退出会话
			if (params.last_visit_user_id) {
				if (this.debug) {
					console.log('user "' + params.last_visit_user_id + '" is exit session :', params.sid)
				}
				await this.closeUserSession(params.sid)
			}
		} else {
			//添加用户日志
			if (!params.last_visit_user_id) {
				await this.fill(params)
			}
			//用户已切换
			else if (params.uid != params.last_visit_user_id) {
				if (this.debug) {
					console.log('user "' + params.last_visit_user_id + '" change to "' + params.uid +
						'" in the session :', params.sid)
				}
				//关闭原会话生成新用户对话
				await this.closeUserSession(params.sid)
				await this.fill(params)
			}
		}
		return {
			code: 0,
			msg: 'success'
		}
	}



	/**
	 * 关闭用户会话
	 * @param {String} sid 基础会话编号
	 */
	async closeUserSession(sid) {
		if (this.debug) {
			console.log('close user session log by sid:', sid)
		}
		return await this.update(this.tableName, {
			is_finish: 1
		}, {
			session_id: sid,
			is_finish: 0
		})
	}


	/**
	 * 更新会话信息
	 * @param {String} sid 基础会话编号
	 * @param {Object} data 更新数据
	 */
	async updateUserSession(sid, data) {

		const userSession = await this.getCollection(this.tableName).where({
			session_id: sid,
			uid: data.uid,
			is_finish: 0
		}).orderBy('create_time', 'desc').limit(1).get()

		if (userSession.data.length === 0) {
			console.log('Not found the user session', {
				session_id: sid,
				uid: data.uid,
				is_finish: 0
			})
			return {
				code: 300,
				msg: 'Not found the user session'
			}
		}

		let nowTime = data.nowTime ? data.nowTime : new DateTime().getTime()
		const accessTime = nowTime - userSession.data[0].createTime
		const accessSenconds = accessTime > 1000 ? parseInt(accessTime / 1000) : 1

		const updateData = {
			last_visit_time: nowTime,
			duration: accessSenconds,
		}

		//访问页面数量
		if (data.addPageCount) {
			updateData.page_count = userSession.data[0].page_count + data.addPageCount
		}
		//最终访问的页面编号
		if (data.pageId) {
			updateData.exit_page_id = data.pageId
		}
		//产生事件次数
		if (data.eventCount) {
			updateData.event_count = userSession.data[0].event_count + data.addEventCount
		}

		if (this.debug) {
			console.log('update user session log by sid-' + sid, updateData)
		}

		await this.update(this.tableName, updateData, {
			_id: userSession.data[0]._id
		})

		return {
			code: 0,
			msg: 'success'
		}
	}

	/**
	 * 清理用户会话日志数据
	 * @param {Object} days 保留天数, 留存统计需要计算30天后留存率，因此至少应保留31天的日志数据
	 */
	async clean(days = 31) {
		days = Math.max(parseInt(days), 1)
		console.log('clean user session logs - day:', days)

		const dateTime = new DateTime()
		const res = await this.delete(this.tableName, {
			create_time: {
				$lt: dateTime.getTimeBySetDays(0 - days)
			}
		})

		if (!res.code) {
			console.log('clean user session log:', res)
		}
		return res
	}

}
