<template>
	<page-meta :root-font-size="fontsize+'px'" style="display: block;">
	<view style="position: relative;">
		<Headers></Headers>
		<view class="project">
			<view style="width: 12rem;margin: auto;">{{paper.title}}</view>
		</view>
		
		<view class="video-box" id="video-box" v-show="showVideo">
			<video id="video" style="width: 100%;height: 100%;" :autoplay="true" :controls="false" :show-center-play-btn="false"></video>
			<canvas id="canvas" style="width: 100%;height: 100%;position: absolute;top:100000px;"  canvas-id="canvas"></canvas>
		</view>
		<!-- <img  :src="imgUrl" ></img> -->
		<view class="project-content ddflex">
			<!-- 考试区域 -->
			<view class="test-box">
				<view class="test-box-title">
					<text style="font-weight: bold;margin-right: 0.10rem;">考试题目</text>
					<text>{{ cIndex + 1 }}</text><text style="color: #999999;">/{{questTotal}}</text>
				</view>
				
				<view class="test-question-box">
					<view class="test-question ddflex">
						<view>{{ cIndex + 1 }}</view>
						<view>【{{getQuestType()}}】</view>
						<view>
							<rich-text class="hh" :nodes="addTitleType(quest.title,quest.qtype)"></rich-text>
						</view>
					</view>
					<!-- 简答题 -->
					<view class="short" v-if="quest.qtype == 4 || quest.qtype == 5">
						<textarea
								v-model="quest.answerTxt"
								maxlength="-1"
								ref="inputText"
								placeholder="在此输入答案"
								placeholder-class="placeholder"
								class="text-ans"
								@click="intAnswer(qitem, idx)"
							></textarea>
					</view>
					<view class="test-question-answer" v-else-if="quest.qtype == 1 || quest.qtype == 2 || quest.qtype == 3">
						<view class="answer-item ddflex" v-for="(qitem, idx) in quest.questJson" :key="idx" @click="setAnswer(qitem, idx)">
							<!-- answer-checked -->
							<view :class="qitem.cssStr ? 'answer-checked' : 'answer-unchecked'"></view>
							<view class="answer-text ddflex">
								<view style="margin-right: 0.1rem;">{{ qitem.num }} </view>
								<rich-text class="hh" :nodes="qitem.title"></rich-text>
							</view>
						</view>
					</view>
				</view>
				
				<view style="height: 0.82rem;width: 100%;"> </view>
				<view class="test-btn-group ddflex">
					<view v-if="cIndex != 0" class="test-btn" @click="prev()">上一题</view>
					<view v-if="cIndex + 1 != questTotal" class="test-btn" @click="next()">下一题</view>
				</view>
			</view>
			<!-- 答题卡区域 -->
			<view class="test-info ddflex">
				<view class="test-people ddflex">
					<image :src="userInfo.avatar"></image>
					<view class="test-people-info ddflex">
						<view class="ddflex">
							<view class="test-people-label">考生姓名</view>
							<view class="fflex">{{userInfo.userName}}</view>
						</view>
						<view class="ddflex">
							<view class="test-people-label">身份证号</view>
							<view class="fflex" style="word-break: break-all;">{{userInfo.idNumber}}</view>
						</view>
						<view class="ddflex">
							<view class="test-people-label">考试科目</view>
							<view class="fflex">{{paper.title}}</view>
						</view>
					</view>
				</view>
				<view class="test-date">
					<view class="test-date-title">距考试结束还有</view>
					<view class="test-date-group ddflex">
						<view class="test-date-item">{{times.hour}}</view>
						<text class="test-date-symbol">:</text>
						<view class="test-date-item">{{times.minutes}}</view>
						<text class="test-date-symbol">:</text>
						<view class="test-date-item">{{times.seconds}}</view>
					</view>
				</view>
				<view class="test-answer fflex">
					<view class="test-answer-title">答题卡</view>
					<view class="test-answer-info ddflex">
						<view class="">共 {{quests.length}} 题</view>
						<view class="test-answer-info-symbol"></view>
						<view class="">总计 100 分</view>
					</view>
					<view class="test-answer-box ddflex">
						<view :class="'test-answer-item '+(cIndex == index?'test-answer-item-curActive':item.isSubmit?'test-answer-item-active':'')" v-for="item,index in quests"
							@click="toQuestTip(index)">
							{{index+1}}
						</view>
					</view>
					<view class="test-answer-number ddflex">
						<view class="ddflex">
							<view class="test-isanswer"></view>
							<view>已做 {{quests.filter(item=>{return item.isSubmit}).length}}</view>
						</view>
						<view class="ddflex">
							<view class="test-unanswer"></view>
							<view>未做 {{quests.filter(item=>{return !item.isSubmit}).length}}</view>
						</view>
					</view>
					
					<view style="height: 0.82rem;"></view>
					<view class="submit-btn" @click="open">交  卷</view>
				</view>
			</view>
		</view>
		
		<uni-popup ref="popup" type="bottom" :is-mask-click='false'>
			<view class="popup-box" v-if="state==1">
				<view class="popup-top ddflex">
					<view>您正在结束作答</view>
					<image src="/static/images/close.png" v-if="time > 0" @click="close()"></image>
				</view>
				<!-- {{(quests.filter(item=>{return item.isSubmit}).length<quests.length)?'您还有未完成的考题，是否确定交卷？':'您已完成全部考题，是否确定交卷？'}} -->
				<view class="popup-content">{{(quests.filter(item=>{return item.isSubmit}).length < quests.length ? '您还有未完成的考题，是否确定交卷？':'您已完成全部考题，是否确定交卷？')}}</view>
				<view class="popup-bottom ddflex">
					<view class="popup-btn1" @click="close()" v-if="time > 0">继续考试</view>
					<view class="popup-btn2" @click="submit">确定交卷</view>
				</view>
			</view>
			<view class="popup-box" v-if="state==2">
				<view class="popup-top ddflex">
					<view>考试结果</view>
					<image src="/static/images/close.png" @click="close(true)"></image>
				</view>
				<view class="popup-content" style="margin-top: 0.23rem;">
					<view class="chufen-title">{{result.title}}</view>
					<view class="chufen-number" :style="result.score>=paper.passScore?'color:green;':''">
						{{result.score}}<text style="font-size: 0.18rem;margin-left: 0.1rem;">分</text>
						<view style="font-size: 0.16rem;">{{result.score>=paper.passScore?'考试合格':'考试不合格'}}</view>
					</view>
				</view>
				<view class="popup-bottom ddflex" style="margin-top: 0.3rem;margin-bottom: 0.6rem;padding-left: 0.3rem">
					<view>
						<view class="popup-bottom-label">总题数</view>
						<view class="popup-bottom-value">{{result.questToal}}</view>
					</view>
					<view class="line"></view>
					<view>
						<view class="popup-bottom-label">考试用时</view>
						<view class="popup-bottom-value">
							{{timeChangeHMS(result.duration)}}
						</view>
					</view>
				</view>
			</view>
		</uni-popup>
		
		<Foot></Foot>
	</view>
	</page-meta>
</template>

<script>
	const app = getApp();
	const req = require('../../utils/request.js');
	const utils = require('../../utils/util.js');
	const api = require('../../utils/api.js')
	import html2canvas from "../../utils/html2canvas.min.js";
	export default {
		data() {
			return {
				state:1,
				
				userInfo:{},
				testId:null,//考试项目ID
				
				paperId: '', //考试题目
				paperTitle: '', //考试标题
				paperType: '', //1每日一练 2模拟试题 3大厂真题 5企业真题
				
				type: '', //标识类型 1试卷 2章节 3热门考点 4错题集 5高频错题
				systems: {},
				isMockExam: true, //是否是模拟考试
				isShowTip: false, //是否展示温馨提示
				isShowSheet: false, //
				
				paper: '', //试卷详情
				time: 0, //允许做题的时间
				times: 0, //做题时分秒倒计时
				quest: '', //当前选中的题目
				quests: [], //题目数据
				questTotal: 0, //题目条数
				cIndex: 0, //当前做题下标
				
				answerTxt: '', //填空题、简答题答案
				isGoBack: false,
				isShowView: false,
				
				
				result:null,//考试结果
				
				buffer:null,
				video:{src:null},
				canvas:null,
				ctx:null,
				imgUrl:null,
				showVideo:false,
				
				takePhotoTime:10*60,//抓拍时间间隔，单位s
				
				fontsize:'100px'
			}
		},
		onReady() {},
		async onLoad(options) {
			let srceenNunber = 19.2; //因设计图是1920所有把设计图分为19.2份，所以html字体大小为100px
			    let that = this;
			
			    //窗体改变大小触发事件
			    uni.onWindowResize((res) => {
			        console.log('变化后的窗口宽度=', res.size.windowWidth);
			        that.fontsize = parseFloat(res.size.windowWidth) / srceenNunber;
			    })
			
			    //打开获取屏幕大小
			    uni.getSystemInfo({
			        success(res) {
			            console.log('设备信息：', res);
			            that.fontsize = res.screenWidth / srceenNunber;
			            console.log('字体大小：', that.fontsize);
			        }
			    })
			
			this.paperId = options.paperId;
			this.testId = options.testId
			
			// 摄像头
			const query = uni.createSelectorQuery().in(this);
			this.video = query.select('#video')
			this.canvas = query.select('#canvas');
			await this.test()

			console.log(this.userInfo)
			// 需要先判断用户是否还能考试
			await this.getQuests();
			
			
			
			// 考生信息
			this.getUserInfo()
			// 考试数据
			this.getPaper();
			// this.getQuests();
		},
		onUnload() {
				// uni.clearStorageSync();
				clearTimeout(this.ptime);
		},
		methods: {
			// 考试信息
			getUserInfo(){
				req.getRequest('/api/v3/exam/user/manager/info',{},res=>{
					this.userInfo = res
				})
			},
			getQuestType() {
				// <!-- 1单选 2多选 3 判断 4 填空 5 简答', -->
				var text = '';
				switch (this.quest.qtype) {
					case 1:
						text = '单选题';
						break;
					case 2:
						text = '多选题';
						break;
					case 3:
						text = '判断题';
						break;
					case 4:
						text = '填空题';
						break;
					case 5:
						text = '简答题';
						break;
					default:
						break;
				}
				return text;
			},
					
			stylesText(text){
				return utils.preText(text);
			},
			
			addTitleType(title, qtype) {
				var stitle=this.stylesText(title);
				return stitle;
			},
						
			//获取考试对象
			getPaper() {
				var _ts = this;
				req.getRequest(api.paper_detail + _ts.paperId, {}, res => {
					if (res) {
						if (res.time > 0 && _ts.paperType != 3 && _ts.paperType != 5) {
							_ts.time = res.time * 60;
							_ts.setTime();
						}
						_ts.paperType = res.paperType * 1;
						_ts.paper = res;
					}
				});
			},

			getQuests(){
				let _ts = this
				return new Promise((r,j)=>{
					req.getRequest(api.get_exam_question + _ts.paperId,{},quests=>{
						console.log(quests)
						if (quests && quests.length > 0) {
							_ts.questTotal = quests.length;
							for (var k = 0; k < quests.length; k++) {
								var quest = quests[k];
								quest.eitype = _ts.etype;
								quest.title = quest.title.replace(/<code class="(.*?)"/gi, '<code class="Java" ');
							}
							if (_ts.questTotal > 0) {
								_ts.quest = _ts.setQuest(quests[0]);
							}
							_ts.quests = quests;
							r()
						}else{
							uni.showModal({
								title:'提示',
								content:'您已参加过该考试',
								showCancel:false,
								success:(res)=> {
									if(res.confirm){
										uni.redirectTo({
											url:'/pages/selectTest/selectTest?paperId='+this.testId,
											success() {
												console.log('您已参加过该考试')
											}
										})
									}
								}
							})
						}
					})
				})
			},
			
			//考试时间倒计时
			setTime() {
				var _ts = this;
				var time = _ts.time;
				if (time <= 0) {
					//考试时间到，交卷
					if (_ts.ptime) {
						clearTimeout(_ts.ptime);
					}
					_ts.open()
					// _ts.submitTest();
					return;
				}
				var times = {};
				times.hour = _ts.cut22(Math.floor(time / 3600));
				var leave2 = time % 3600;
				times.minutes = _ts.cut22(Math.floor(leave2 / 60));
				var leave3 = leave2 % 60;
				times.seconds = _ts.cut22(Math.round(leave3));
				_ts.times = times;
				_ts.ptime = setTimeout(function() {
					_ts.time = time - 1;
					
					
					if(((_ts.paper.time*60)-(_ts.time))%(_ts.takePhotoTime)==0){
						_ts.takePhoto()
					}
					_ts.setTime();
				}, 1000);
				
				// if(((_ts.paper.time*60) -(_ts.time*60)%(10))%(10)==0){
				// 	let a = (_ts.paper.time*60) -(_ts.time*60)%(10)
				// 	console.log((_ts.paper.time*60) -(_ts.time*60),'拍照')
				// }
			}, //下次继续
			// 秒转换时分秒
			timeChangeHMS(time){
				let _ts = this
				var times = {};
				times.hour = _ts.cut22(Math.floor(time / 3600));
				var leave2 = time % 3600;
				times.minutes = _ts.cut22(Math.floor(leave2 / 60));
				var leave3 = leave2 % 60;
				times.seconds = _ts.cut22(Math.round(leave3));
				return times.hour+":"+times.minutes+":"+times.seconds
			},
			cut22(n) {
				n = n.toString();
				return n[1] ? n : '0' + n;
			},
						
			//将答案和问题转成数组或对象
			setQuest(quest) {
				console.log('quest.iscv==', quest.iscv);
				if (quest.iscv) {
					return quest;
				}
				quest.iscv = true;
				var answers = [];
				var qjs = [];
				try {
					var qJsons = JSON.parse(quest.questJson);
					if (quest.qtype == 1 || quest.qtype == 3) {
						//'单选题'
						answers = quest.answerJson ? [quest.answerJson] : [];
					} else if (quest.qtype == 2) {
						if (quest.answerJson) {
							answers = JSON.parse(quest.answerJson);
						}
					}
					for (var m = 0; m < qJsons.length; m++) {
						var num = this.getNum(m);
						qjs.push({
							num: num,
							title: qJsons[m],
							cssStr: ''
						});
					}
				} catch (e) {}
				quest.answerJson = answers;
				quest.questJson = qjs;
				console.log('下一题中');
				quest.answerTxt = '';
				this.answerTxt = '';
				return quest;
			},
						
			getNum: function(ix) {
				var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'];
				return keys[ix];
			},
			intAnswer(item, idx) {
				var _ts = this;
				var qes = this.quest;
				qes.isSubmit = true;
				_ts.quest = qes;
			},
			setAnswer(item, idx) {
				// <!-- 1单选 2多选 3 判断 4 填空 5 简答', -->
				var _ts = this;
				idx = idx + 1;
				var qes = this.quest;
				/*修改答案选中项*/
				var sItems = qes.sItems;
				if (qes.qtype == 2) {
					var isflg = false;
					if (sItems && sItems.length > 0) {
						var cidx = sItems.indexOf(idx);
						if (cidx > -1) {
							sItems.splice(cidx, 1);
							isflg = true;
						}
					} else {
						sItems = [];
					}
					if (!isflg) {
						sItems.push(idx);
					}
				} else if (qes.qtype == 1 || qes.qtype == 3) {
					sItems = [idx];
				}
				qes.sItems = sItems.sort();
				qes.isSubmit = true;
				//修改Css
				qes = _ts.setCss(qes);
				_ts.quest = qes;
				_ts.quests[_ts.cIndex] = qes;
			},
						
			//设置页面选中样式
			setCss(qes) {
				var qjson = qes.questJson;
				var answers = qes.answerJson; //答案
				var sItems = qes.sItems;
				if (!sItems) {
					sItems = [];
				}
				for (var m = 0; m < qjson.length; m++) {
					var qitem = qjson[m];
					var cidx = sItems.indexOf(m + 1);
					if (cidx > -1) {
						qitem.cssStr = ' active';
					} else {
						qitem.cssStr = '';
					}
				}
				qes.questJson = qjson;
				qes.cssStr = ' active';
				return qes;
			},
						
			//上一题
			prev() {
				var _ts = this;
				var cIndex = _ts.cIndex;
				if (cIndex <= 0) {
					return;
				}
				_ts.cIndex = cIndex - 1;
				_ts.quest = _ts.setQuest(_ts.quests[_ts.cIndex]);
			}, //下一题
			next() {
				var _ts = this;
				var cIndex = _ts.cIndex;
				if (cIndex >= _ts.questTotal - 1) {
					return;
				}
				_ts.cIndex = cIndex + 1;
				console.log('下一题');
				_ts.quest = _ts.setQuest(_ts.quests[_ts.cIndex]);
				console.log('下一题后');
				console.log('_ts.quest==', _ts.quest);
				console.log('_ts.quest.answerTxt==', _ts.quest.answerTxt);
				_ts.$forceUpdate();
				console.log('quests==', _ts.quests);
			},
						
			toQuestTip(index) {
				var _ts = this;
				_ts.cIndex = index;
				_ts.quest = _ts.setQuest(_ts.quests[_ts.cIndex]);
				// _ts.closeCeng();
				// });
			},
						
			//提交
			submitQuest() {
				var msg = '';
				if (this.paperType == 2) {
					if (this.times.hour > 0) {
						msg = '距离考试结束还剩' + this.times.hour + '小时' + this.times.minutes + '分钟，确定要结束考试吗？';
					} else {
						if (this.times.minutes > 0) {
							msg = '距离考试结束还剩' + this.times.minutes + '分钟，确定要结束考试吗？';
						} else {
							msg = '确定要交卷结束考试吗？';
						}
					}
				} else {
					msg = '确定要交卷结束做题吗？';
				}
						
				this.$showModal({ title: '温馨提示', content: msg, cancelText: '继续作答', confirmText: '交卷' })
					.then(res => {
						this.submitTest();
					})
					.catch(err => {
						// 点击取消按钮的操作
					});
			},
						
			async submitTest(){
				if (!this.paper.isScore) {//手动阅卷
				//订阅成绩通知
					await requsetmessage.resultsTest().then(res => {});
				}
				this.submit();
			},
						
						
			//提交考试+答案
			submit() {
				var _ts = this;
				if (_ts.ptime) {
					clearTimeout(_ts.ptime);
				}
				var dataP = {
					uniqueId: _ts.paperId,
					uniqueType: 1
				};
				//组装考试题目
				dataP.questionList = this.quests.map(it => {
					// <!-- 1单选 2多选 3 判断 4 填空 5 简答', -->
					var data = {
						id: it.id, //记录ID
						paperQuestionId: it.pqId, //试卷题目ID
						questionId: it.questId //题目ID
					};
					var answerJson = '';
					if (it.qtype == 1 || it.qtype == 3) {
						answerJson = it.sItems ? it.sItems.join('') : '';
					} else if (it.qtype == 2) {
						answerJson = it.sItems ? JSON.stringify(it.sItems) : '';
					} else if (it.qtype == 4) {
						var list = [];
						list.push(it.answerTxt ? it.answerTxt : '');
						answerJson = JSON.stringify(list);
					} else if (it.qtype == 5) {
						answerJson = it.answerTxt ? it.answerTxt : '';
					}
					data.answerJson = answerJson;
					return data;
				});
				console.log(dataP);
				req.postRequest(
					api.complete_exam,
					dataP,
					res => {
						if (!_ts.paper.isScore) {//手动阅卷
							uni.redirectTo({
								url:'/pages/scoreQuery/scoreQuery?paperId='+ _ts.paperId+'&admissionNo='+_ts.userInfo.admissionNo
							})
							return
						} else {//自动阅卷
							// uni.redirectTo({
							// 	url: '/learn/result/index?id=' + res.id
							// });
							this.state=2
							this.result = res
						}
					},
					true
				);
			},
			
			open() {
				this.$refs.popup.open('center')
			},
			close(back) {
				let _ts = this
				this.$refs.popup.close()
				if(back){
					uni.redirectTo({
						url:'/pages/selectTest/selectTest?paperId='+this.testId,
					})
				}
			},
			
			
			takePhoto() {
				let _this = this
			    //获得Canvas对象
				const query = uni.createSelectorQuery().in(this);
			    let video = document.querySelector('video');
				let canvas = document.querySelector('canvas')
			    let ctx = canvas.getContext('2d');
				let videoInfo = {}
				query.select('video').boundingClientRect(result => {
					console.log('videoInfo',result)
					videoInfo={
						width:result.width,
						height:result.height
					}
				}).exec();
			    ctx.drawImage(video, 0, 0, videoInfo.width, videoInfo.height);
				// console.log(this.dataURLtoBlob(canvas.toDataURL(),'11'))
				req.uploadFile('/api/upload', canvas.toDataURL(), res => {
					let userPhotoData = {examId:this.testId,image:res.src,paperId:this.paperId}
					req.postRequest('/api/v3/exam/user/manager/image',userPhotoData,res=>{
						
					})
				},false);
			},
			dataURLtoBlob(dataurl) {
			                            var arr = dataurl.split(','),
			                                mime = arr[0].match(/:(.*?);/)[1],
			                                bstr = atob(arr[1]),
			                                n = bstr.length,
			                                u8arr = new Uint8Array(n);//8位无符号整数，长度1个字节
			                            console.log(mime)
			                            while (n--) {
			                                u8arr[n] = bstr.charCodeAt(n);
			                            }
			                            // console.log(JSON.stringify(u8arr));
			                            return new Blob([u8arr], {
			                                type: mime
			                            });
			                        },
			base64toFile (dataurl, filename){
				var arr = dataurl.split(','),
				    mime = arr[0].match(/:(.*?);/)[1],
				    bstr = atob(arr[1]),
				    n = bstr.length,
				    u8arr = new Uint8Array(n);
				while (n--) {
				    u8arr[n] = bstr.charCodeAt(n);
				}
				return new File([u8arr], filename, {
				    type: mime
				});
			},
			test(){
				return new Promise((r,j)=>{
					// var video = document.querySelector('video');
					const query = uni.createSelectorQuery().in(this);
					var video = query.select('#video')
					console.log('video',video)	
					// 兼容代码
					window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);
					// 获取媒体属性，旧版本浏览器可能不支持mediaDevices，我们首先设置一个空对象
					if (navigator.mediaDevices === undefined) {
					    navigator.mediaDevices = {};
					}
					console.log('navigator.mediaDevices',navigator.mediaDevices)
					// 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
					// 使用getUserMedia，因为它会覆盖现有的属性。
					// 这里，如果缺少getUserMedia属性，就添加它。
					if (navigator.mediaDevices.getUserMedia === undefined) {
						navigator.mediaDevices.getUserMedia = function(constraints) {
							// 首先获取现存的getUserMedia(如果存在)
						    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
							// 有些浏览器不支持，会返回错误信息
							// 保持接口一致
						    if (!getUserMedia) { //不存在则报错
						        return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
						    }
							// 否则，使用Promise将调用包装到旧的navigator.getUserMedia
						    return new Promise(function(resolve, reject) {
						        getUserMedia.call(navigator, constraints, resolve, reject);
						    });
						}
					}
					//摄像头调用配置
					var mediaOpts = {
					    audio: false,
					    video: { facingMode: "user"} 
					    
					}
								 
					let that=this;
					navigator.mediaDevices.getUserMedia(mediaOpts).then(function(stream) {
					    that.mediaStreamTrack = stream;
					    video = document.querySelector('video');
						console.log('video = document.querySelector(video);',video)
							// 旧的浏览器可能没有srcObject
					    if ("srcObject" in video) {
					        video.srcObject = stream
							that.video.srcObject = stream
					    } else {
							// 避免在新的浏览器中使用它，因为它正在被弃用。
					        video.src = window.URL && window.URL.createObjectURL(stream) || stream
							that.video.src = window.URL && window.URL.createObjectURL(stream) || stream
					    }
					    video.play();
						that.showVideo = true
						r()
					}).catch(function (err) {
					    console.log(err)
						uni.showModal({
							title:'提示',
							content:'未找到摄像头',
							showCancel:false,
							success() {
								uni.navigateBack({
									
								})
							}
						})
					});
				})
			},
		},
	}

</script>

<style>
	@import url('./test.css');
</style>