<template>
	<view class="default_page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
		<cus-header title='填写所在团队信息'></cus-header>
		<cus-team-info-fill ref="teamRef" :submitting="creationState.submitting || creationState.completed" @handleConfirm="handleConfirm" :confirmText="confirmText" :qtype="qtype"></cus-team-info-fill>
	</view>
</template>

<script>
	import CusTeamInfoFill from '@/components/CusTeamInfoFill/index.vue'
	import teamBackgroundRules from '@/utils/teamBackgroundFile.js'
	import backgroundSurveyRules from '@/utils/backgroundSurvey.js'
	const {
		beginTeamSubmission,
		createTeamCreationState,
		createTeamPayloadSnapshot,
		createTeamSubmitPayload,
		finishTeamSubmission,
		rememberCreatedTeam,
		setTeamSubmissionStage
	} = teamBackgroundRules
	const { backgroundIntroUrl } = backgroundSurveyRules
	export default {
		components:{ CusTeamInfoFill },
		data(){
			return {
				title:'',
				type:'',
				next:'',
				questionnaireId:'',
				confirmText:'下一步',
				qtype:'',
				creationState:createTeamCreationState(),
				navigationTimer:null,
				navigationReject:null,
				pageUnloaded:false,
				resumeAfterSurveyPending:false
			}
		},
		onLoad(options) {
			this.pageUnloaded = false;
			this.title = options.title||'';
			this.type = options.type;
			this.qtype = options.qtype||'';
			this.questionnaireId = options.questionnaireId||'';
			this.confirmText = options.type?'确定':'下一步';
			this.next = options.next;
			if(this.next) this.confirmText = '下一步';
		},
		onShow() {
			if(!this.resumeAfterSurveyPending || this.pageUnloaded) return
			this.resumeAfterSurveyPending = false
			this.resumeAfterCoachSurvey()
		},
		onUnload() {
			this.pageUnloaded = true
			this.cancelPendingNavigation(new Error('页面已离开'))
		},
		methods:{
			async handleConfirm(team){
				if(!beginTeamSubmission(this.creationState)) return
				const payload = createTeamSubmitPayload(Object.assign({}, team, {
					questionnaireId:this.questionnaireId
				}))
				const payloadSnapshot = createTeamPayloadSnapshot(payload)
				try {
					let teamId = this.creationState.createdTeamId
					const resumeStage = this.creationState.stage === 'update'
						? this.creationState.resumeStage
						: this.creationState.stage
					const resumeNavigation = resumeStage === 'navigate'
					if(!teamId){
						setTeamSubmissionStage(this.creationState, 'save')
						const { data:res } = await this.$api.post('/core/user/team',payload)
						if(res.code!==0){
							this.$showToast(res.msg || '团队保存失败，请重试')
							return
						}
						teamId = res.data && res.data.teamId
						if(!teamId){
							this.$showToast('团队保存未返回团队ID，请重试')
							return
						}
						rememberCreatedTeam(this.creationState, teamId)
						this.creationState.teamPayloadSnapshot = payloadSnapshot
					} else if(this.creationState.teamPayloadSnapshot !== payloadSnapshot) {
						this.creationState.resumeStage = resumeStage
						setTeamSubmissionStage(this.creationState, 'update')
						const response = await this.$api.put('/core/user/team', Object.assign({}, payload, {
							id:teamId
						}))
						const res = response.data
						if(res.code!==0) throw new Error(res.msg || '团队更新请求失败')
						this.creationState.teamPayloadSnapshot = payloadSnapshot
						setTeamSubmissionStage(this.creationState, resumeStage)
						this.creationState.resumeStage = ''
					} else if(this.creationState.stage === 'update') {
						setTeamSubmissionStage(this.creationState, resumeStage)
						this.creationState.resumeStage = ''
					}

					if(resumeNavigation) {
						setTeamSubmissionStage(this.creationState, 'navigate')
						await this.continueAfterTeamCreated(teamId)
						finishTeamSubmission(this.creationState, true)
						return
					}

					setTeamSubmissionStage(this.creationState, 'upload')
					const uploadResult = await this.$refs.teamRef.flushBackgroundFiles(teamId)
					if(uploadResult.failed > 0 || this.$refs.teamRef.hasUnresolvedBackgroundFiles()){
						await this.$showModal('仍有背景资料未上传成功，请重试后继续；团队已保存，无需再次创建')
						return
					}
					if(this.$refs.teamRef.hasDeferredPcUpload()){
						setTeamSubmissionStage(this.creationState, 'pcSession')
						await this.$refs.teamRef.waitForDeferredPcUpload(teamId)
					}
					if(this.next && this.creationState.backgroundSurveyStatus !== 'COMPLETED'){
						setTeamSubmissionStage(this.creationState, 'coachSurvey')
						this.openCoachBackgroundSurvey(teamId)
						return
					}
					if(this.next && !this.creationState.teamQuestionnaireId) {
						setTeamSubmissionStage(this.creationState, 'publish')
						const publishResult = await this.publishQuestionnaire(teamId)
						this.creationState.publishResult = publishResult
						this.creationState.teamQuestionnaireId = publishResult.data
					}
					setTeamSubmissionStage(this.creationState, 'navigate')
					await this.continueAfterTeamCreated(teamId)
					finishTeamSubmission(this.creationState, true)
				} catch(error) {
					this.showStageError(error)
				} finally {
					finishTeamSubmission(this.creationState)
				}
			},
			showStageError(error) {
				if(this.pageUnloaded) return
				const prefix = {
					save:'团队保存失败',
					update:'团队更新失败',
					upload:'背景资料处理失败',
					pcSession:'电脑上传流程失败',
					coachSurvey:'团队背景调研失败',
					publish:'问卷发布失败',
					navigate:'页面跳转失败'
				}[this.creationState.stage] || '操作失败'
				const message = error && (error.message || error.msg)
				this.$showToast(message ? `${prefix}：${message}` : `${prefix}，请重试`)
			},
			openCoachBackgroundSurvey(teamId) {
				const surveyId = this.creationState.backgroundSurveyId || ''
				uni.navigateTo({
					url:`/pagesPublish/backgroundSurvey?mode=coach&teamId=${encodeURIComponent(teamId)}&surveyId=${encodeURIComponent(surveyId)}`,
					events:{
						backgroundSurveyReady:data=>{
							this.creationState.backgroundSurveyId = data.surveyId
							this.creationState.backgroundSurveyStatus = data.status
						},
						backgroundSurveyCompleted:data=>{
							this.creationState.backgroundSurveyId = data.surveyId
							this.creationState.backgroundSurveyStatus = data.status
							this.resumeAfterSurveyPending = data.status === 'COMPLETED'
						}
					},
					fail:error=>{
						this.showStageError(new Error(error && error.errMsg || '背景调研页面打开失败'))
					}
				})
			},
			async resumeAfterCoachSurvey() {
				if(this.creationState.backgroundSurveyStatus !== 'COMPLETED'
					|| this.creationState.teamQuestionnaireId
					|| !beginTeamSubmission(this.creationState)) return
				const teamId = this.creationState.createdTeamId
				try {
					setTeamSubmissionStage(this.creationState, 'publish')
					const publishResult = await this.publishQuestionnaire(teamId)
					this.creationState.publishResult = publishResult
					this.creationState.teamQuestionnaireId = publishResult.data
					setTeamSubmissionStage(this.creationState, 'navigate')
					await this.continueAfterTeamCreated(teamId)
					finishTeamSubmission(this.creationState, true)
				} catch(error) {
					this.showStageError(error)
				} finally {
					finishTeamSubmission(this.creationState)
				}
			},
			async publishQuestionnaire(teamId) {
				const response = await this.$api.post('/core/team/questionnaire/publish',{
						answerSetting:1,
						coachId:JSON.parse(uni.getStorageSync('userInfo')).id,
						startTime:new Date().Format('yyyy-MM-dd hh:mm:ss'),
						endTime:new Date(new Date().setDate(new Date().getDate()+30)).Format('yyyy-MM-dd hh:mm:ss'),
						questionnaireId:this.questionnaireId,
						backgroundSurveyId:this.creationState.backgroundSurveyId,
						teamId,
						type:1
					})
				const result = response.data
				if(result.code!==0) throw new Error(result.msg || '发布请求失败')
				return result
			},
			async continueAfterTeamCreated(teamId) {
				if(this.next){
					this.$showToast('保存成功，即将填写问卷')
					await this.runDelayedNavigation(({ success, fail }) => {
						uni.navigateTo({
							url:backgroundIntroUrl({
								teamQuestionnaireId:this.creationState.teamQuestionnaireId,
								teamId,
								type:this.type,
								title:this.title
							}),
							success,
							fail
						})
					})
					uni.removeStorageSync('newUser')
					return
				}
				this.$showToast('团队新增成功')
				const eventChannel = this.getOpenerEventChannel()
				if(eventChannel) eventChannel.emit('saveTeamInfo',{
					teamId,
					teamName:this.$refs.teamRef && this.$refs.teamRef.teamInfo
						? this.$refs.teamRef.teamInfo.teamName
						: ''
				})
				await this.runDelayedNavigation(({ success, fail }) => {
					uni.navigateBack({ success, fail })
				})
			},
			runDelayedNavigation(invokeNavigation) {
				return new Promise((resolve, reject) => {
					if(this.pageUnloaded) {
						reject(new Error('页面已离开'))
						return
					}
					let settled = false
					const settle = (callback, value) => {
						if(settled) return
						settled = true
						this.navigationTimer = null
						this.navigationReject = null
						callback(value)
					}
					this.navigationReject = error => settle(reject, error)
					this.navigationTimer = setTimeout(() => {
						this.navigationTimer = null
						if(this.pageUnloaded) {
							settle(reject, new Error('页面已离开'))
							return
						}
						try {
							invokeNavigation({
								success: result => {
									if(this.pageUnloaded) settle(reject, new Error('页面已离开'))
									else settle(resolve, result)
								},
								fail: error => settle(reject, new Error(error && (error.errMsg || error.message) || '跳转失败'))
							})
						} catch(error) {
							settle(reject, error)
						}
					},1500)
				})
			},
			cancelPendingNavigation(error) {
				if(this.navigationTimer) clearTimeout(this.navigationTimer)
				this.navigationTimer = null
				const reject = this.navigationReject
				this.navigationReject = null
				if(reject) reject(error || new Error('跳转已取消'))
			}
		}
	}
</script>

<style scoped lang="scss">
	.default_page{
		box-sizing: border-box;
	}
</style>
