import Domain from '@core/util/domain'
import Message from '../message/index'
import PicEditor from "../picEditor"
 
 const H5Upload = (($) => {
 
	 let DefaultConfig = {
		 startIndex: 0,
		 triggerUpload: false,           
		 fileChooseNode: null,           
		 dragDropNode: null,             
		 submitFileNode: null,           
		 categoryNode: null,             
		 cateId: null,  
		 userId: -1,                     
		 urlOnly: `${Domain.material}/shopImg/upload`,    
		 url: `${Domain.material}/shopImg/upload`,  
		 checkTokenUrl: `${Domain.material}/token/getToken`,
		 postName: 'filedata',           
		 multiple: false,                
		 fileSizeLimit: window.page_config? window.page_config.chooseSizeLimit * 1024: 800 * 1024,  
		 gifFileSizeLimit: null,         
		 typeLimit: '.jpg,.png',   
		 file_filter: [],                 
		 minWidth: 0,                   
		 maxWidth: 9999,                
		 minHeight: 0,                  
		 maxHeight: 9999,               
		 uploadUnCompleted: 0,          
		 overflowMaxSizeRunEditor: true,  
		 zxDesignerPicture: window.page_data.isSDKM, 
		 zxDesingerUrl: `${Domain.zxDesigner}/sdk/imgspace/uploadImage.html`, 
		 onSelect: function () {
		 },        
		 onSelectBefore: null,  
		 onFileCheckFail: null, 
		 onDragOver: function () {
		 },      
		 onDragLeave: function () {
		 },     
		 onProgress: function () {
		 },      
		 onSubmitBefore: function () {
		 },  
		 onPicEditorSuccess: null,     
		 onSuccess: function () {
		 },       
		 onFailure: function () {
		 },       
		 onComplete: function () {
		 }      
	 };
	 let uploadNode = $(`<a class="cd-upload-btn-fixed"><input type="file" class="cd-file J_fixedFileBtn" enctype="multipart/form-data" accept=".jpg,.jpeg,.gif,.png"></a>`)
 
	 class Html5Upload {
		 constructor(options) {
			 this._getConfig(options);
			 this._chooseFileControl();
			 this._init();
		 }
 
		 _getConfig(options) {
 
			 if(options){
				 for(let attr in options){
					 let attrVal = options[attr];
					 if(attrVal === undefined || attrVal === '' || attrVal === null){
						 delete options[attr];
					 }
				 }
			 }
 
			 if(options.typeLimit && options.typeLimit.match(/^\w/)){
				 options.typeLimit = '.' + options.typeLimit.replace(/,(\w+)/g, ',.$1');
			 }
 
			 $.extend(true, this, DefaultConfig, options || {});
			 this.minWidth = parseInt(this.minWidth);
			 this.maxWidth = parseInt(this.maxWidth);
			 this.minHeight = parseInt(this.minHeight);
			 this.maxHeight = parseInt(this.maxHeight);
			 let arr = this.typeLimit.split(',').filter((item) => {
					 return item !== '.jpeg';
				 }),
				 newTypeLimit = arr.join(',');
			 this.typeLimitName = newTypeLimit;  
			 if (arr.indexOf('.jpg') > -1) {
				 newTypeLimit = newTypeLimit.replace('.jpg', '.jpg,.jpeg');
			 }
			 this.typeLimit = newTypeLimit;
		 };
 
		 
		 static upload(opt) {
			 let newUploadNode = uploadNode.clone(),
				 newOpt = $.extend(true, {}, DefaultConfig, {
					 triggerUpload: true,
					 fileChooseNode: newUploadNode.find(".J_fixedFileBtn")
				 }, opt || {});
			 $("body").append(newUploadNode);
			 new Html5Upload(newOpt);
		 }
 
		 
		 _init() {
			 let self = this;
			 self.fileTypeReg = new RegExp(self.typeLimit.replace(/\./g, '').replace(/,/g, '|'));
			 if (!self.fileChooseNode && !self.dragDropNode) {
				 console.error('New h5Upload param\'s [fileChooseNode] is illegal');
				 return;
			 }
			 self.fileChooseNode && self.fileChooseNode.attr('accept', self.typeLimit);
			 self.dragDropNode && self.dragDropNode.attr('accept', self.typeLimit);
			 self.file_filter = [];
			 if (this.dragDropNode) {
				 this.dragDropNode.on('dragover.upload', function (e) {
					 self._funDragHover(e);
				 });
				 this.dragDropNode.on('dragleave.upload', function (e) {
					 self._funDragHover(e);
				 });
				 this.dragDropNode.on('drop.upload', function (e) {
					 self._funGetFiles(e, function () {
						 if (self.onSelectBefore) {
							 if (self.onSelectBefore(e) === false) {
								 e.preventDefault();
							 } else {
								 if (self.file_filter.length) {
									 self._funUploadFile();
								 }
							 }
						 }
					 });
				 });
			 }
			 if (this.fileChooseNode) {
				 this.fileChooseNode.off().on('click.upload', function (e) {
					 if (self.onSelectBefore) {
						 if (self.onSelectBefore(e) === false) {
							 e.preventDefault();
						 }
					 }
				 });
				 this.fileChooseNode.off().on('change.upload', function (e) {
					 self._funGetFiles(e, function () {
						 !self.submitFileNode && self._funUploadFile();
					 });
				 });
				 this.triggerUpload && this.fileChooseNode.trigger('click.upload');
			 }
			 if (this.submitFileNode) {
				 this.submitFileNode.on('click.upload', function (e) {
					 self._funUploadFile();
				 });
			 }
		 };
 
		 
		 _chooseFileControl(){
			 if(this.fileChooseNode){
				 this.fileChooseNode.attr('accept', this.typeLimit);
 
				 if(this.multiple){
					 this.fileChooseNode.attr('multiple', '');
				 }else{
					 this.fileChooseNode.removeAttr('multiple');
				 }
			 }
		 }
 
		 
		 _funDragHover(e) {
			 e.stopPropagation();
			 e.preventDefault();
			 this[e.type === "dragover" ? "onDragOver" : "onDragLeave"].call(e.target);
			 return this;
		 };
 
		 
		 _funGetFiles(e, callback) {
			 let that = this;
			 this._funDragHover(e);
			 let files = e.originalEvent ? (e.originalEvent.target.files || e.originalEvent.dataTransfer.files) : (e.target.files || e.dataTransfer.files);
			 this.chooseFiles = files;   
			 this._filter(files, function (arr) {
				 that.file_filter = arr;
				 that._funDealFiles();
				 callback();
			 });
		 };
 
		 
		 _funDealFiles() {
			 this.startIndex = 0;
			 for (let i = 0, file; file = this.file_filter[i]; i++) {
				 file.index = this.startIndex;
				 this.startIndex++;
			 }
			 this.file_filter.length && this.onSelect(this.file_filter);
			 return this;
		 };
 
		 
		 _filter(files, callback) {
			 let arrFiles = [],
				 needCheckTotal = files.length,
				 failTotal = 0,
				 checkedTotal = 0,   
				 arrFailInfo = {
					 gifLimit: [],
					 otherLimit: [],
					 typeLimit: [],
					 widthHeightLimit: [],
					 widthHeightLowerFiles: [],
					 needRunPicEditorFiles: []
				 },  
				 self = this,
				 maxSize = self.fileSizeLimit;
			 this.selectFile = {
				 files: files,
				 length: needCheckTotal
			 };
			 for (let i = 0, file; file = files[i]; i++) {
				 if (file.type.replace('jpeg', 'jpg').match(self.fileTypeReg)) {
					 if (self.gifFileSizeLimit && file.type.indexOf('gif') !== -1 && self.gifFileSizeLimit < file.size) {
						 arrFailInfo.gifLimit.push({
							 name: file.name + ' [' + (file.size / 1024).toFixed(2) + 'kb]',
							 limit: (self.gifFileSizeLimit / 1024).toFixed(2),
							 file: file
						 });
						 file.sizeCheck = false;
						 failTotal++;
					 } else if (file.size >= maxSize) {
						 arrFailInfo.otherLimit.push({
							 name: file.name + ' [' + (file.size / 1024).toFixed(2) + 'kb]',
							 limit: (maxSize / 1024).toFixed(2),
							 file: file
						 });
						 file.sizeCheck = false;
						 failTotal++;
					 }
					 (function (file) {
						 self._createReader(file, function (width, height) {
 
							 if (width < self.minWidth || height < self.minHeight || width > self.maxWidth || height > self.maxHeight) {
								 if (!file.type.match(/gif/i) && (width >= self.maxWidth || height >= self.maxHeight)) {
									 arrFailInfo.needRunPicEditorFiles.push(file);
								 } else if (!file.type.match(/gif/i) && width >= self.minWidth && height >= self.minHeight && file.sizeCheck === false) {
									 arrFailInfo.needRunPicEditorFiles.push(file);
								 } else if (width < self.minWidth || height < self.minHeight) {
									 arrFailInfo.widthHeightLowerFiles.push(file);
								 }
 
 
 
								 let widthErrorMsg = '',
									 heightErrorMsg = '';
								 if (self.minWidth === self.maxWidth) {
									 widthErrorMsg = '宽' + self.minWidth + 'px';
								 } else {
									 widthErrorMsg = self.maxWidth === 9999 ? '宽大于' + self.minWidth + 'px' : '宽' + self.minWidth + '~' + self.maxWidth + 'px';
								 }
								 if (self.minHeight === self.maxHeight) {
									 heightErrorMsg = '高' + self.minHeight + 'px';
								 } else {
									 heightErrorMsg = self.maxHeight === 9999 ? '高大于' + self.minHeight + 'px' : '高' + self.minHeight + '~' + self.maxHeight + 'px';
								 }
								 arrFailInfo.widthHeightLimit.push({
									 name: file.name + ' [' + (file.size / 1024).toFixed(2) + 'kb]',
									 limit: widthErrorMsg + '、' + heightErrorMsg,
									 file: file
								 });
								 failTotal++;
							 } else {
								 if (file.sizeCheck === false) {
									 if (!file.type.match(/gif/i)) {
										 arrFailInfo.needRunPicEditorFiles.push(file);
									 }
								 } else {
									 arrFiles.push(file);
								 }
							 }
							 checkedTotal++;
							 _checkedHandle();
						 });
					 })(file);
				 } else {
					 checkedTotal++;
					 failTotal++;
					 arrFailInfo.typeLimit.push({
						 name: file.name,
						 limit: self.typeLimit.replace(/\./g, '').split(',').map(function (val) {
							 return val.charAt(0).toUpperCase() + val.substring(1)
						 }).join('，'),
						 file: file
					 });
					 _checkedHandle();
				 }
			 }
			 function _checkedHandle() {
				 let maxSize = self.fileSizeLimit,
					 unitM = maxSize / 1024 / 1024,
					 unitKB = maxSize / 1024,
					 strMaxSize = '';
				 if (unitM > 1) {
					 strMaxSize = Number(unitM.toFixed(2)) + 'M';
				 } else {
					 strMaxSize = Number(unitKB.toFixed(2)) + 'KB';
				 }
 
				 if (checkedTotal === needCheckTotal) {
					 if (failTotal > 0) {
						 let arrTip = [],
							 tipCount = 0;
						 for (let attr in arrFailInfo) {
							 if (attr.match(/needRunPicEditorFiles|widthHeightLowerFiles/)) {
								 continue;
							 }
							 let item = arrFailInfo[attr],
								 subInfo = "",
								 arrName = [];
							 for (let j = 0; j < item.length; j++) {
								 arrName.push('　　' + item[j].name);
							 }
							 if (item.length) {
								 tipCount++;
								 switch (attr) {
									 case 'gifLimit':
										 subInfo = 'Gif类型图片最大限制' + (this.gifFileSizeLimit / 1024) + 'Kb：<br>' + arrName.join('<br>');
										 break;
									 case 'otherLimit':
										 subInfo = '图片上传最大限制' + strMaxSize + '：<br>' + arrName.join('<br>');
										 break;
									 case 'widthHeightLimit':
										 subInfo = '图片宽高不符合要求(' + item[0].limit + ')：<br>' + arrName.join('<br>');
										 break;
									 case 'typeLimit':
										 subInfo = '图片类型支持' + item[0].limit.replace(/,/g, '、') + '：<br>' + arrName.join('<br>');
								 }
								 arrTip.push(subInfo);
							 }
						 }
						 for (let n = 0; n < arrTip.length; n++) {
							 if (arrTip.length !== 1) {
								 arrTip[n] = (n + 1) + '、' + arrTip[n];
							 }
						 }
 
 
						 let arrErrorTip = [];
 
						 let sizeFilesLen = arrFailInfo.otherLimit.filter((item, index) => {
							 return item.file.name.match(/gif/i);
						 }).length;
						 if (sizeFilesLen) {
							 let tipMsg = '';
							 arrFailInfo.otherLimit.forEach((item, index) => {
								 if (index === 0) {
									 if (sizeFilesLen > 1) {
										 tipMsg = item.file.name + '等' + sizeFilesLen + '张图片上传失败。请上传';
									 } else {
										 tipMsg = item.file.name + '上传失败。请上传';
									 }
								 }
							 });
							 arrErrorTip.push(tipMsg + '不大于' + strMaxSize + '的图片。');
						 }
 
						 let whGifFilesLen = arrFailInfo.widthHeightLimit.filter((item, index) => {
							 return item.file.name.match(/gif/i);
						 }).length;
						 if (whGifFilesLen) {
							 let tipMsg = '';
							 arrFailInfo.widthHeightLimit.forEach((item, index) => {
								 if (index === 0) {
									 if (whGifFilesLen > 1) {
										 tipMsg = item.file.name + '等' + whGifFilesLen + '张图片上传失败。请上传';
									 } else {
										 tipMsg = item.file.name + '上传失败。请上传';
									 }
								 }
							 });
							 let ruleText = '';
							 if (self.minWidth === self.maxWidth && self.minHeight === self.maxHeight) {
								 ruleText = '宽度等于' + self.minWidth + '，高度等于' + self.minHeight;
							 } else if (self.minWidth !== self.maxWidth && self.minHeight !== self.maxHeight) {
								 ruleText = '宽度' + self.minWidth + '~' + self.maxWidth + '，高度' + self.minHeight + '~' + self.maxHeight;
							 } else if (self.minWidth === self.maxWidth && self.minHeight !== self.maxHeight) {
								 ruleText = '宽度等于' + self.minWidth + '，高度' + self.minHeight + '~' + self.maxHeight;
							 } else if (self.minWidth !== self.maxWidth && self.minHeight === self.maxHeight) {
								 ruleText = '宽度' + self.minWidth + '~' + self.maxWidth + '，高度等于' + self.minHeight;
							 }
							 arrErrorTip.push(tipMsg + ruleText + '的图片。');
						 }
 
						 let typeFilesLen = arrFailInfo.typeLimit.length;
						 if (typeFilesLen) {
							 let tipMsg = '';
							 arrFailInfo.typeLimit.forEach((item, index) => {
								 if (index === 0) {
									 if (typeFilesLen > 1) {
										 tipMsg = item.name + '等' + typeFilesLen + '张图片上传失败。请上传';
									 } else {
										 tipMsg = item.name + '上传失败。请上传';
									 }
								 }
							 });
							 arrErrorTip.push(tipMsg + self.typeLimitName.replace(/\./g, '').replace(/,/g, '、').toLowerCase() + '格式的图片。');
						 }
 
						 let LowerFilesLen = arrFailInfo.widthHeightLowerFiles.length;
						 if (LowerFilesLen) {
							 let tipMsg = '';
							 arrFailInfo.widthHeightLowerFiles.forEach((item, index) => {
								 if (index === 0) {
									 if (LowerFilesLen > 1) {
										 tipMsg = item.name + '等' + LowerFilesLen + '张图片上传失败。请上传宽度不小于';
									 } else {
										 tipMsg = item.name + '上传失败。请上传宽度不小于';
									 }
								 }
							 });
							 arrErrorTip.push(tipMsg + self.minWidth + '，高度不小于' + self.minHeight + '的图片。');
						 }
 
						 if (arrErrorTip.length) {
							 if(self.chooseFiles.length === 1 && arrErrorTip.length > 1){
								 let arrErrorMsg = [];
								 arrErrorTip.forEach((item) => {
									 let match = item.match(/请上传(.*?)的图片/);
									 if(match){
										 arrErrorMsg.push(match[1]);
									 }
								 });
								 let connatMsg = self.chooseFiles[0].name + '上传失败。请上传' + arrErrorMsg.join('，') + '的图片。';
								 arrErrorTip = [connatMsg];
							 }
 
							 let tipContent = arrErrorTip.join('<br>');
							 Message.warn(tipContent, tipContent.length / 8 * 1000);
						 }
 
						 if (self.overflowMaxSizeRunEditor && arrFailInfo.needRunPicEditorFiles.length) {
 
							 let _maxSizeFiles = arrFailInfo.needRunPicEditorFiles;
							 new PicEditor({
								 editMode: arrFailInfo.needRunPicEditorFiles.length > 1? 'multiple': 'single',
								 dataSource: _maxSizeFiles,
								 sizeLimit: {
									 minWidth: self.minWidth,
									 maxWidth: self.maxWidth,
									 minHeight: self.minHeight,
									 maxHeight: self.maxHeight
								 },
								 perPicSize: maxSize,
								 cateId: self.cateId,
								 uploadCallback: self.onPicEditorSuccess || ((file) => {
									 self.onSuccess(file, {
										 code: 0,
										 data: {
											 imgId: file.imgId,
											 width: file.width,
											 height: file.height,
											 size: file.size,
											 url: file.src
										 },
										 message: "上传成功!"
									 });
								 })
							 });
						 }
 
 
						 if (failTotal === files.length) {
							 typeof self.onFileCheckFail === 'function' && self.onFileCheckFail(arrFailInfo);
						 }
					 }
					 callback(arrFiles);
				 }
			 }
		 };
 
		 
		 _funUploadFile() {
			 let self = this;
			 typeof self.onSubmitBefore === "function" && self.onSubmitBefore();
			 if (this.selectFile.length <= 0 || this.file_filter.length <= 0) {
				 this.selectFile.length <= 0 && Message.warn('请先选择图片!');
				 return;
			 }
 
			 this.fileChooseNode.val('');
 
			 self.uploadUnCompleted = self.file_filter.length;
			 for (let i = 0, file; file = this.file_filter[i]; i++) {
				 (function (file) {
					 if (self.zxDesignerPicture) {
						 self._createReader(file, function (width, height) {
							 let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
							 if (xhr.upload) {
								 xhr.upload.addEventListener("progress", function (e) {
									 self.onProgress(file, e.loaded, e.total);
								 }, false);
								 xhr.onerror = function (e) {
									 console.log('文件上传失败', e);
									 self.onFailure(file);
									 if (self.triggerUpload) {
										 self.dispose();
										 self.fileChooseNode.parent().remove();
									 }
								 };
								 xhr.onreadystatechange = function (e) {
									 if (xhr.readyState == 4) {
										 if (xhr.status == 200) {
											 let data = xhr.responseText,
												 paseSuccess = true;
											 try {
												 data = JSON.parse(xhr.responseText);
											 } catch (e) {
												 paseSuccess = false;
												 self.onFailure(file, data);
												 Message.warn('上传失败，请稍后重试！');
												 if (self.triggerUpload) {
													 self.dispose();
													 self.fileChooseNode.parent().remove();
												 }
											 }
 
											 if (paseSuccess) {
												 if (data.success) {
													 self.uploadUnCompleted--;
													 self.onSuccess(file, data, width, height);
													 if (self.uploadUnCompleted === 0) {
														 self.onComplete();
														 self.startIndex = 0;
														 self.file_filter = [];
														 if (self.triggerUpload) {
															 self.dispose();
															 self.fileChooseNode.parent().remove();
														 }
													 }
												 } else {
													 self.onFailure(file, data);
													 Message.warn(data['message'] || '上传失败，请稍后重试！');
													 if (self.triggerUpload) {
														 self.dispose();
														 self.fileChooseNode.parent().remove();
													 }
												 }
											 }
										 } else {
											 Message.warn('上传失败，请稍后重试！');
											 self.onFailure(file);
										 }
									 }
								 };
								 xhr.open("POST", self.zxDesingerUrl, true);
								 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
								 xhr.withCredentials = true; 
								 let fd = new FormData();
  
								 fd.append('fileData', file);
								 fd.append('format', '-1,-1');
								 if (self.categoryNode) {
									 fd.append('cateId', $(self.categoryNode).val() || "0");
								 } else {
									 fd.append('cateId', 0);
								 }
								 xhr.send(fd);
							 }
						 });
					 } else {
						 $.ajax({
							 url: self.checkTokenUrl,
							 type: 'post',
							 dataType: 'json',
							 contentType: "application/json;charset=utf-8",
							 xhrFields: {
								 withCredentials: true
							 }
						 }).done(function (result) {
							 if (result.code == 0) {
								 self._createReader(file, function (width, height) {
									 let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
									 if (xhr.upload) {
										 xhr.upload.addEventListener("progress", function (e) {
											 self.onProgress(file, e.loaded, e.total);
										 }, false);
										 xhr.onerror = function (e) {
											 console.log('文件上传失败', e);
											 self.onFailure(file, data);
											 if (self.triggerUpload) {
												 self.dispose();
												 self.fileChooseNode.parent().remove();
											 }
										 };
										 xhr.onreadystatechange = function (e) {
											 if (xhr.readyState == 4) {
												 if (xhr.status == 200) {
													 let data = xhr.responseText,
														 paseSuccess = true;
													 try {
														 data = JSON.parse(xhr.responseText);
													 } catch (e) {
														 paseSuccess = false;
														 self.onFailure(file, data);
														 Message.warn('上传失败，请稍后重试！');
														 if (self.triggerUpload) {
															 self.dispose();
															 self.fileChooseNode.parent().remove();
														 }
													 }
 
													 if (paseSuccess) {
														 if (data.code === 0) {
															 self.uploadUnCompleted--;
															 self.onSuccess(file, data, width, height);
															 if (self.uploadUnCompleted === 0) {
																 self.onComplete();
																 self.startIndex = 0;
																 self.file_filter = [];
																 if (self.triggerUpload) {
																	 self.dispose();
																	 self.fileChooseNode.parent().remove();
																 }
															 }
														 } else {
															 self.onFailure(file, data);
															 Message.warn(data['message'] || '上传失败，请稍后重试！');
															 if (self.triggerUpload) {
																 self.dispose();
																 self.fileChooseNode.parent().remove();
															 }
														 }
													 }
 
												 } else {
													 Message.warn('上传失败，请稍后重试！');
												 }
											 }
										 };
										 xhr.open("POST", self.categoryNode ? self.url : self.urlOnly, true);
										 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
										 xhr.withCredentials = true; 
										 xhr.setRequestHeader("materialtoken", result.data);
										 let fd = new FormData();
										 fd.append('fileData', file);
										 if (self.categoryNode) {
											 fd.append('cateId', $(self.categoryNode).val() || "0");
										 } else {
											 fd.append('cateId', 0);
										 }
										 xhr.send(fd);
									 }
								 });
							 } else {
								 self.onFailure(file, result);
								 Message.warn(result['message'] || '上传失败，请稍后重试！');
								 console.log(result);
							 }
						 }).fail(function (result) {
							 self.onFailure(file, result);
							 Message.warn('上传失败，请稍后重试！');
							 console.log(result);
						 });
					 }
				 })(file);
			 }
		 };
 
		 
		 _createReader(file, whenReady) {
			 let reader = new FileReader();
			 reader.onload = function (evt) {
				 let image = new Image();
				 image.onload = function (evt) {
					 let width = this.width;
					 let height = this.height;
					 if (whenReady) whenReady(width, height);
				 };
				 image.src = evt.target.result;
			 };
			 reader.readAsDataURL(file);
		 };
 
		 
		 dispose() {
			 if (this.dragDropNode) {
				 this.dragDropNode.off("dragover.upload");
				 this.dragDropNode.off("dragleave.upload");
				 this.dragDropNode.off("drop.upload");
			 }
			 if (this.fileChooseNode) {
				 this.fileChooseNode.off("click.upload");
				 this.fileChooseNode.off("change.upload");
			 }
			 if (this.submitFileNode) {
				 this.submitFileNode.off("click.upload");
			 }
		 }
	 }
 
	 return Html5Upload;
 })($);
 export default H5Upload;
 