import React from 'react'
import axios from 'axios'
import { notification } from 'antd'
import update from 'immutability-helper'

import ImageLayer from '../page/layers/ImageLayer'

const $ = window.$
/* 需要的props:  
	shixun
		id
	myshixun 
		id
	challenge
		id
	user
		"image_url": user.image_url,
		"username": user.username,
	showSnackbar

	*/
/*
	这里提供props给WrappedComponent，用于封装特定的state和功能（评论列表）
	不要直接使用this.xxx调用WrappedComponent内的方法，尽量避免互相依赖，封装好后供不同场景使用（tpi、tpm）
*/
export function commentHOC(WrappedComponent) {
	// 这里如果extends WrappedComponent 会出现 WrappedComponent mount twice的问题
	return class II extends React.Component {
		constructor(props) {
			super(props)

			// ------------------------------------
			this.createNewComment = this.createNewComment.bind(this)
			this.fetchCommentIfNotFetched = this.fetchCommentIfNotFetched.bind(this)
			this.replyComment = this.replyComment.bind(this)
			this.deleteComment = this.deleteComment.bind(this)
			this.commentPraise = this.commentPraise.bind(this)
			this.hiddenComment = this.hiddenComment.bind(this)
			this.rewardCode = this.rewardCode.bind(this)
			this.showNewReply = this.showNewReply.bind(this)
			// ------------------------------------

			this.onPaginationChange = this.onPaginationChange.bind(this)

			this.state = {
				// 评论
				comments: [],
				comment_count_without_reply: 0,
				// 默认pageSize为10
				currentPage: 1,
				loadingComments: true,

				// 图片最大化
				showImage: false,
				imageSrc: '',
			}
		}

		// ----------------------------------------------------------------------------------------------评论 Start

		// ----------------------------------------------------------------------------------------------评论 Start
		onPaginationChange(page) {
			this.fetchComment(page)
			this.setState({
				currentPage: page,
			});
		}
		/*
		email: "1843820944@qq.com"
		grade: 2138
		image_url: "avatar/User/36497"
		login: "p24891375"
		name: "杨俊男"
		user_url: "/users/p24891375"
	*/
		handleComments(comments, responseData) {
			comments.forEach(element => {
				if (element.children) {
					this.handleComments(element.children, responseData)
				}
				element.admin = responseData.all
				element.manager = element.manage

				element.username = element.author.name
				element.user_login = element.author.login
				element.image_url = element.author.image_url
				element.user_id = element.author.user_id

			});
		}
		responseDataParse(response) {
			const comments = response.data.comments
			this.handleComments(comments, response.data)
		}
		fetchComment(page = 1) {
			const { challenge, shixun, match } = this.props;
			// const url = `/api/v1/shixuns/${shixun.id}/shixun_discusses?page=${page-1}&container_type=Shixun`
			const url =
				`/discusses.json?page=${page - 1}&container_identifier=${shixun && shixun.identifier ?
					shixun.identifier : match.params.shixunId}&container_type=Shixun`

			this.setState({
				loadingComments: true,
			});


			axios.get(url,
				{}
			).then((response) => {
				// test

				if (response.data) {
					this.responseDataParse(response)
					this.setState({
						comments: response.data.comments,
						comment_count_without_reply: response.data.disscuss_count,

						currentPage: page,
						loadingComments: false,
					}, () => {
						// keditor代码美化
						window.prettyPrint()
					})
				}
				// console.log(response)
			}).catch((error) => {
				console.log(error)
			})
		}
		// 切换关卡时，清空state
		clearCommentsInState = () => {
			this.setState({ comments: [] })
		}
		fetchCommentIfNotFetched() {
			if (this.state.comments && this.state.comments.length) {
				return;
			}
			// http://localhost:3000/api/v1/shixuns/cz7yw3en/shixun_discusses?page=0	
			this.fetchComment();
		}
		// 新增父级评论
		createNewComment(content) {

			const { challenge, shixun, showSnackbar } = this.props;
			if (!content || content.length === 0) {
				showSnackbar('必须填写内容！')
				return;
			}
			const url = `/discusses.json`

			if (content != undefined) {
				var beforeImage = content.split("<img");
				var afterImage = content.split("/>");
				if (beforeImage[0] == "" && afterImage[1] == "") {
					window.notice_box('不支持纯图片评论<br/>请在评论中增加文字信息');
					return;
				}
			}

			let res = axios.post(url, {
				container_type: "Shixun",
				container_id: shixun.id,
				challenge_id: challenge.id,
				content,
				position: challenge.position
			}
			).then((response) => {
				if (response.data.discuss) {
					this.fetchComment()
				}
			}).catch((error) => {
				console.log(error)
			})
			return res;
		}
		_findCommentById(id, arg_comments) {
			let comments;
			if (!arg_comments) {
				comments = this.state.comments;
			} else {
				comments = arg_comments;
			}
			for (let i = 0; i < comments.length; i++) {
				if (id === comments[i].id) {
					return i;
				}
			}
		}
		replyComment(commentContent, id) {
			const { challenge, shixun, user, showSnackbar, match } = this.props;

			if (!commentContent || commentContent.length === 0) {
				showSnackbar('必须填写内容！')
				return;
			}
			const url = `/discusses/${id}/reply.json`
			if (commentContent) {
				commentContent = commentContent.replace(/(\n<p>\n\t<br \/>\n<\/p>)*$/g, '');
			}
			if (!user.login && user.user_url) {
				const loginAr = user.user_url.split('/')
				user.login = loginAr[loginAr.length - 1]
			}
			let res = axios.post(url, { content: commentContent, "container_id": match.params.shixunId, "container_type": "Shixun", }).then((response) => {
				if (response.data.discuss) {
					let newDiscuss = response.data.discuss;
					let { comments } = this.state;
					var commentIndex = this._findCommentById(id);
					let comment = comments[commentIndex]
					comment = Object.assign({}, comment)
					if (!comment.children) {
						comment.children = []
					} else {
						comment.children = comment.children.slice(0);
					}
					comment.children.push({
						"can_delete": true,
						"content": commentContent,

						"image_url": user.image_url,
						"username": user.username,
						"user_login": user.login,
						"id": newDiscuss.id,
						"position": newDiscuss.position,
						"time": "1分钟前",
						"praise_count": newDiscuss.praise_count,

						"user_id": newDiscuss.user_id,

					})

					comments = comments.slice(0)
					comments[commentIndex] = comment

					this.setState({
						comments: comments
					})
				}
			}).catch((error) => {
				console.log(error)
			})
			return res
		}
		hiddenComment(item, childCommentId) {
			const id = item.id
			const { challenge, shixun, user, showSnackbar, match } = this.props;
			const url = `/discusses/${id}/hidden.json`

			const commentIndex = this._findCommentById(id);
			const { comments } = this.state;
			const comment = Object.assign({}, comments[commentIndex]);
			axios.post(url, {
				hidden: !comment.hidden ? "1" : "0",
				container_identifier: match.params.shixunId || shixun.identifier
			}).then((response) => {
				if (response.data.status === -1) {
					showSnackbar(response.data.message)
					return;
				}
				if (response.data.status === 1) {

					if (!childCommentId) {
						comment.hidden = !comment.hidden;
						const commentsCopy = this.state.comments.slice(0)
						commentsCopy[commentIndex] = comment
						this.setState({
							comments: commentsCopy
						})
					} else {	// TODO 目前子回复没hidden字段
						let childCommentIndex = this._findCommentById(childCommentId, comments[commentIndex].children);
						const childComment = comments[commentIndex].children[childCommentIndex]
						childComment.hidden = !childComment.hidden;
						this.setState({ comments })
					}

				}
			}).catch((error) => {
				console.log(error)
			})
		}
		deleteComment(parrentComment, childCommentId) {
			const { challenge, shixun } = this.props;
			let deleteCommentId = parrentComment.id
			if (childCommentId) {
				deleteCommentId = childCommentId;
			}
			const url = `/discusses/${deleteCommentId}.json`

			axios.delete(url).then((response) => {
				if (response.data && response.data.status === 1) {
					const commentIndex = this._findCommentById(parrentComment.id);

					// https://stackoverflow.com/questions/29527385/removing-element-from-array-in-component-state
					if (!childCommentId) {
						this.setState((prevState) => ({
							comments: update(prevState.comments, { $splice: [[commentIndex, 1]] })
						}))

						if (this.state.comments.length <= 5) {
							this.fetchComment()
						}
					} else {
						let comments = this.state.comments;
						let newComments = Object.assign({}, comments)
						let childCommentIndex = this._findCommentById(childCommentId, newComments[commentIndex].children);
						newComments[commentIndex].children = update(newComments[commentIndex].children, { $splice: [[childCommentIndex, 1]] })
						this.setState({ newComments })
					}
				}
			}).catch((error) => {
				console.log(error)
			})
		}

		rewardCode(parrentComment, childComment, amount) {
			const { showSnackbar } = this.props;
			let handleComment = parrentComment
			if (childComment) {
				handleComment = childComment;
			}
			let handleCommentId = handleComment.id;
			const url = `/discusses/${handleCommentId}/reward_code.json`

			axios.post(url, {
				container_type: 'Discusses',
				score: amount,
				user_id: handleComment.user_id
			}).then((response) => {
				if (response.data && response.data.code) {
					const commentIndex = this._findCommentById(parrentComment.id);
					let { comments } = this.state;
					const newComments = comments.slice(0)

					if (childComment) {
						const childCommentIndex = this._findCommentById(handleComment.id, parrentComment.children);
						const newChildComment = Object.assign({}, childComment);
						newChildComment.reward = response.data.code
						parrentComment = Object.assign({}, parrentComment)
						parrentComment.children = parrentComment.children.slice(0)
						parrentComment.children[childCommentIndex] = newChildComment

						newComments[commentIndex] = parrentComment;


					} else {
						const newComment = Object.assign({}, newComments[commentIndex]);
						newComment.reward = response.data.code;
						newComments[commentIndex] = newComment;
					}
					this.setState({
						comments: newComments
					})
				}
			}).catch((error) => {
				console.log(error)
				showSnackbar('奖励失败，请联系系统管理员！')
			})
		}

		// 评论点赞
		commentPraise(discussId) {
			const commentIndex = this._findCommentById(discussId);
			const { comments } = this.state;

			const { challenge } = this.props;
			const url = `/discusses/${discussId}/plus.json`
			axios.post(url, {
				container_type: 'Discuss',	//Discuss
				type: comments[commentIndex].user_praise === true ? 0 : 1,   //  "踩0；赞1"
			}).then((response) => {
				if (response.data.praise_count === 0 || response.data.praise_count) {
					const newComments = comments.slice(0)
					const comment = Object.assign({}, newComments[commentIndex])
					comment.user_praise = !comment.user_praise;
					comment.praise_count = response.data.praise_count;
					newComments[commentIndex] = comment;
					this.setState({
						comments: newComments
					})
				}
			}).catch((error) => {
				console.log(error)
			})
		}


		showNewReply() {
			const { shixun, myshixun } = this.props;
			const commentId = 929 // TODO
			const url = `/api/v1/shixuns/${shixun.id}/anchor?container_type=Shixun&myshixun_id=${myshixun.id}&discuss_id=${commentId}`

			this.setState({
				loadingComments: true,
				gotNewReply: false,

			});
			axios.get(url,
				{
					// withCredentials: true
				}
			).then((response) => {
				const data = response.data;
				const new_message = data.new_message;

				this.setState({
					comments: data.children_list,
					comment_count_without_reply: data.disscuss_count,

					currentPage: data.page,
					loadingComments: false,

				}, () => {
					if (response.data.find_status) { // 没找到评论的话，默认会返回第一页的评论
						const comment_J = window.$(`#reply_content_${commentId}`);
						if (comment_J.length) {
							comment_J[0].scrollIntoView()
							comment_J.parents('.comment_item_cont').css('border', '1px solid #4CACFF')
						}
					}
				})
			}).catch((error) => {
				console.log(error)
			})
		}

		componentDidMount() {
			$(".commentsDelegateParent")
				.delegate(".J_Comment_Reply .comment_content img, .J_Comment_Reply .childrenCommentsView img", "click", (event) => {

					const imageSrc = event.target.src
					// 非回复里的头像图片; 非emoticons
					if (imageSrc.indexOf('/images/avatars/User') === -1 &&
						imageSrc.indexOf('kindeditor/plugins/emoticons') === -1) {
						this.setState({
							showImage: true,
							imageSrc,
						})
					}
				});
		}
		onImageLayerClose = () => {
			this.setState({
				showImage: false,
				imageSrc: '',
			})
		}

		showNotification = (description, message = "提示", icon) => {
			const data = {
				message,
				description
			}
			if (icon) {
				data.icon = icon;
			}
			notification.open(data);
		}
		render() {
			return (
				<React.Fragment>
					<ImageLayer {...this.state} onImageLayerClose={this.onImageLayerClose}></ImageLayer>

					<WrappedComponent {...this.props} {...this.state}
						createNewComment={this.createNewComment}
						fetchCommentIfNotFetched={this.fetchCommentIfNotFetched}
						clearCommentsInState={this.clearCommentsInState}
						replyComment={this.replyComment}
						deleteComment={this.deleteComment}
						commentPraise={this.commentPraise}
						hiddenComment={this.hiddenComment}
						rewardCode={this.rewardCode}
						onPaginationChange={this.onPaginationChange}
						showNotification={this.showNotification}
						newMessage={this.newMessage}
						showNewReply={this.showNewReply}
					></WrappedComponent>
				</React.Fragment>

			)
		}
	}
}