<template>
	<div class="chat" :class="{active:!openChat}" @click.stop="">
		<div class="top" :class="{active:!isChattingRecords}" @click="()=>{isChattingRecords=!isChattingRecords}">
			<i class="fi fi-br-angle-small-down"></i>
		</div>
		<div v-show="!openChat" class="left" @click="leftOpenChat('left')">
			<i class="fi fi-br-angle-small-down"></i>
		</div>
		<div class="chatBox">
			<div class="chattingRecords" v-show="chatList.length > 0 && isChattingRecords">
				<div class="itemBox" ref="chatBox">
					<div class="item" v-for="item,index in chatList" :class="{user:item.role == 'user'}">
						<div class="textBox">
							<div class="icon">
								<img src="@/assets/images/icon/favicon.png" alt="">
							</div>
							<div class="text" v-show="item.content.think || item.content.message || item.content.img || item.content.color">
								<span class="content">
									<div class="showThink" :class="{active:item.content?.isThink}" v-show="item.content.think" @click="()=>item.content?.isThink?(item.content.isThink = false):(item.content.isThink = true)">
										<div>{{ $t('chat.DeepThinking') }}</div>
										<i class="fi fi-br-angle-small-down"></i>
									</div>
									<div class="think" v-show="item.content?.isThink">{{item.content.think}}</div>
									<div class="txt">{{item.content.message}}</div>
								</span>
								<div class="fileBox">
									<div v-if="item?.fileList?.length > 0" class="item" v-for="fileItem in item.fileList">
										<div>{{fileItem.name}}</div>
									</div>
								</div>
								<div class="imgBox">
									<!-- <span v-show="item.content?.img?.length > 0">
										{{ item.content?.img }}
									</span> -->
									
									<img v-if="item.content?.img?.length > 0" v-for="imgItem,imgIndex in item.content?.img" :src="imgItem.minioUrl" alt="" @error="imgError(imgItem,index,imgIndex,$event)">
								</div>
								<div class="colorBox">
									<div v-if="item.content?.color?.length > 0" class="item" v-for="colorItem in item.content?.color">
										<div class="color" :style="{'background-color':`rgba(${colorItem.rgb.replace(/\s+/g, ',')})`}"></div>
										<div class="text">{{ colorItem.rgb.replace(/\s+/g, ',') }}</div>
									</div>
								</div>
							</div>
							<i class="fi fi-br-loading" v-if="!item.content.think && !item.content.message && !item.content.img && !item.content.color"></i>
						</div>
					</div>
				</div>
			</div>
			<div class="content" @click="openChattingRecords">
				<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" :placeholder="$t('chat.message')"></textarea>
				<div class="btn">
					<div class="uploadBox">
						<div class="filList">
							<div class="item" v-for="item,index in filList">
								<div>{{item.name}}</div>
								<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
							</div>
						</div>
						<i class="fi fi-rs-paperclip-vertical">
							<input type="file" @change="handleFileUpload($event)">
						</i>
						<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">{{ $t('chat.DeepThinking') }}</div>
					</div>
					<div class="sendBox">
						<div class="maxNum">{{ chatContent?.length }}/10000</div>
						<div class="send" :class="{active:chatContent?.length>0}" @click="sendChat">
							<i class="fi fi-ss-paper-plane-top"></i>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div v-show="openChat" class="right" @click="leftOpenChat('right')">
			<i class="fi fi-br-angle-small-down"></i>
		</div>
	</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,inject,nextTick,createVNode,toRefs, reactive, watch} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import {getMinioUrl} from '@/tool/util'
import { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useRouter,useRoute } from 'vue-router'
export default defineComponent({
	components:{
	},
	props:{
	},
	emits:['chatChange'],
	setup(props,{emit}) {
		const store = useStore();
		const route = useRoute()
		const data = reactive({
			chatContent:'',
			openChat:computed(()=>store.state.Workspace.openChat),
			chatList:[
			] as any,
			isChattingRecords:false,
			selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
			filList:[] as any,
			setIsShowMark:inject('setIsShowMark') as any,
			isFinish:true,
			enableThinking:false,//深度思考
		})
		const dataDom = reactive({
			textarea:null as any,
			chatBox:null as any,
		})
		watch(()=>data.selectObject.id,(newValue,oldValue)=>{
			if(newValue && (data.selectObject.httpType == 'SERIES_DESIGN' || data.selectObject.httpType == 'SINGLE_DESIGN')){
				data.chatList = []
				if(route.query?.chatMode == 'true')store.commit('setOpenChatStatus',true)

				if(route.query?.create)return
				nextTick(()=>{
					getChatHistory(newValue)
				})
			}
		})
		const inputText = (e:any)=>{
			if(e.target.value.length <= 1000){
				data.chatContent = e.target.value
			}else{
				e.target.value = data.chatContent 
			}
			e.target.style.height = `${e.target.scrollHeight}px`;
		}
		const sendChat = ()=>{
			if(!data.isFinish)return
			if(!data.chatContent)return
			let fileList
			if(data.filList){
				fileList = JSON.parse(JSON.stringify(data.filList))
			}else{
				fileList = []
			}
			let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : ''
			let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : ''
			data.chatList.push({content:{message:data.chatContent,think:''},role:'user',fileList:fileList})
			data.chatList.push({content:{message:'',think:''},role:'system'})
			const eventSource = new EventSource(`${import.meta.env.VITE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=${data.selectObject.id}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}`);
			data.chatContent = ''
			dataDom.textarea.value = ''
			data.filList = []
			eventSource.onmessage = function(event) {
				data.isFinish = false
				console.log('收到数据:', JSON.parse(event.data));
				// if(event.data.status == 'DESIGN_SIGNAL'){
				// 	emit('chatChange',{type:'design'})
				// }else if(event.data.status == 'RUNNING'){
				// 	data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
				// }
				const container = dataDom.chatBox;
      			if(container?.scrollHeight)container.scrollTop = container.scrollHeight;

				const eventData = JSON.parse(event.data)
				if(eventData.type == 'text'){
					data.chatList[data.chatList.length-1].content.message+=eventData.content
				}else if(eventData.type == 'think'){
					data.chatList[data.chatList.length-1].content.think+=eventData.content
				}else if(eventData.type == "tools_response"){
					let nameList = ['moodboard','printboard','sketchboard','colorboard','search_sketch_img']
					let nameData = {
						moodboard:'moodBoard',
						printboard:'printBoard',
						sketchboard:'sketchBoard',
					} as any
					let getData = ''
					if(nameList.indexOf(eventData.tools_name) > -1){
						if(data.chatList[data.chatList.length - 1].content.message)data.chatList.push({content:{message:''},role:'system'})
						if(eventData.tools_name == 'colorboard'){
							data.chatList[data.chatList.length-1].content.color = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList
							getData = 'colorBoard'
						}else{
							data.chatList[data.chatList.length-1].content.img = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList
							if(eventData.tools_name == 'search_sketch_img'){
								getData = 'sketchBoard'
							}else{
								getData = nameData[eventData.tools_name]
							}
						}
						data.chatList.push({content:{message:''},role:'system'})
					}else if(eventData.tools_name == 'design_control_signal'){
						emit('chatChange',{type:eventData.tools_name,design:true})
					}
					emit('chatChange',{type:eventData.type,module:getData})
				}
					//emit('chatChange',{type:JSON.parse(event.data).status})
			};
			eventSource.onerror = function(error) {
				if (eventSource.readyState === EventSource.CLOSED) {
					data.chatList[data.chatList.length-1].content.message='服务器繁忙，请稍后再试。'

				} else {
					eventSource.close()
					data.isFinish = true
				}
			};
		}
		const getChatHistory = (objectId:number)=>{
			if(!data.isFinish)return
			let value = {
				projectId:objectId,
				page:1,
				pageSize:100,
			}
			Https.axiosPost(Https.httpUrls.getChatHistory,value).then((rv)=>{
				if(rv){
					rv.content.forEach((item:any,index:number) => {
						if(rv.content[rv.content.length - index -1].role == 'system'){
							let text = rv.content[rv.content.length - index -1].content
							if(rv.content[rv.content.length - index -1].isImage == 2){
								rv.content[rv.content.length - index -1].content={
									img : JSON.parse(rv.content[rv.content.length - index -1].content)
								}
							}else if(rv.content[rv.content.length - index -1].isImage==1){
								rv.content[rv.content.length - index -1].content={
									color : JSON.parse(rv.content[rv.content.length - index -1].content)
								}
							}else{
								let think = ''
								let message = ''
								if(text.split('[TEXT]').length > 1 && text.split('[THINK]').length > 1){
									think = text.split('[TEXT]')[0]
									text.split('[TEXT]').forEach((text:any,index:number) => {
										if(index == 0)return
										message += ('[TEXT]'+text)
									});
								}else{
									message = text
								}
								rv.content[rv.content.length - index -1].content = {
									message:message,
									think:think,
								}
							}
						}else{
							let content = JSON.parse(rv.content[rv.content.length - index -1].content) 
							content.fileList = []
							if(content.file || content.image){
								let getName = (url:any)=>{
									let minio = url.splice('?')[0]
									return minio.splice('/')[minio.splice('/').length-1]
								}
								if(content.file){
									content.file.forEach((item:any)=>{
										content.fileList.push({name:getName(item),type:'file',url:item})
									})
								}							
								if(content.image){
									content.image.forEach((item:any)=>{
										content.fileList.push({name:getName(item),type:'image',url:item})
									})
								}	
							}
							rv.content[rv.content.length - index -1].content = content
						}
						data.chatList.push(rv.content[rv.content.length - index -1])	
					});
				}
			})
		}
		const openChattingRecords = ()=>{
			data.isChattingRecords = true
			// let setRecords = ()=>{
			// 	data.isChattingRecords = false	
			// 	document.removeEventListener('click',setRecords)
			// }
			// document.addEventListener('click',setRecords)
		}
		const handleFileUpload = (event:any)=>{
			if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
				message.info('The file size cannot exceed 5MB.');
				return
			}
			let type = event.target.files[0].type.startsWith('image/')
			if(type){
				if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
					message.info('You can only upload five pictures.');
					return	
				}
			}else{
				if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
					message.info('You can only upload one file.');
					return	
				}
			}
			data.setIsShowMark(true)
			const formData = new FormData();
			formData.append('file', event.target.files[0]);
			let config:any = {
				headers:{'Content-Type':'multipart/form-data','Accept':'*/*'  },
				params:formData,
			}
			Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
			.then((rv: any) => {
				let obj = {
					name:event.target.files[0].name,
					type:type?'image':'file',
					minioPath:rv[0],
					url:rv[1],
				}
				data.filList.push(obj)
				// data.filList.unshift(rv)
				data.setIsShowMark(false)
			}
			).catch(rv=>{
				data.setIsShowMark(false)
			})
		}
		const deleteFile = (item:any,index:number)=>{
			data.filList.splice(index,1)
		}
		const imgError = (item:any,index:number,imgIndex:number,event:any)=>{
			if(!item?.loadNum) item.loadNum = 0
			if(item?.loadNum >= 1)return
			let value = {
				path:getMinioUrl(item.minioUrl)
			}
			Https.axiosGet(Https.httpUrls.refreshMinioUrl,{params:value}).then((rv:any)=>{
				event.target.src = rv
				item.loadNum += 1
				data.chatList[index].content.img[imgIndex].monioUrl = rv
			})
			
		}
		const leftOpenChat = (str:string)=>{
			if(str == 'left'){
				data.isChattingRecords=true
				store.commit('setOpenChatStatus',true)
			}else{
				data.isChattingRecords=false
				store.commit('setOpenChatStatus',false)
			}
		}
		return{
			...toRefs(dataDom),
			...toRefs(data),
			inputText,
			sendChat,
			openChattingRecords,
			handleFileUpload,
			deleteFile,
			imgError,
			leftOpenChat,
		}
	},
	provide() {
		return {
		}
	},
})
</script>
<style lang="less" scoped>
	.chat{
		position: absolute;
		left: 50%;
		transform: translateX(-50%);
		z-index: 999;
		bottom: 3.2rem;
		top: auto;
		width: 50%;
		transition: all .3s;
		border-radius: 2.4rem;
		display: flex;
		border: 1px solid #e5e5e5;
		background: #fff;
		overflow: hidden;
		&.active{
			left: auto;
			right: 0;
			transform: translateX(calc(100% - 3rem));
		}
		> .chatBox{
			flex: 1;
			overflow: hidden;
			> .chattingRecords{
				> .itemBox{
					width: 100%;
					padding: 1.6rem 2rem;
					max-height: 75vh;
					overflow-y: auto;
					> .item{
						display: flex;
						line-height: 1.75;
						// width: min-content;
						&.user{
							> .textBox{
								margin-left: auto;
								background: #F9FAFA;
								max-width: 60%;
								> .text{
									> .content{
										> .txt{

										}
										> .showThink{
											display: none;
										}
									}
									> .fileBox{
										> .item{
											height: 3rem;
											padding: .5rem 1rem;
											background: #efeff1;
											border-radius: .5rem;
											margin-right: 1rem;
											font-size: 1.4rem;
											line-height: 2rem;
											display: flex;
											> div{
												white-space: nowrap;
												overflow: hidden;
												max-width: 10rem;
												text-overflow: ellipsis;
											}
										}
									}
								}
								> .icon{
									display: none;
								}
								
							}
						}
						 
						> .textBox{
							display: flex;
							padding: 1.2rem 2rem;
							border-radius: 2.4rem;
							// -webkit-user-select: none;
							> .icon{
								> img{
									width: 2.5rem;
									height: 2.5rem;
								}
							}
							> .text{
								// display: inline-block;
								// width: min-content;
								max-width: 100%;
								width: 100%;
								// width: min-content;
								// word-wrap: break-word;
								> .content{
									> .txt{

									}
									> .showThink{
										cursor: pointer;
										display: flex;
										padding: .7rem 1.4rem;
										margin-bottom: 1.2rem;
										background: rgb(237 237 237);
										border-radius: 1rem;
										align-items: center;
										
										&.active{
											>i{
												transform: rotate(180deg);
											}
										}
										> i{
											display: flex;
											transition: all .3s;
										}
									}
									> .think{
										margin-bottom: 2rem;
										padding-left: 2rem;
										color: #8b8b8b;
										white-space: pre-wrap;
										border-left: 2px solid #e5e5e5;
										 -moz-user-select: none;
										-ms-user-select: none;
										user-select: none;
									}
								}
								> .imgBox{
									display: flex;
									flex-wrap: wrap;
									img{
										width: 10rem;
										height: 10rem;
										cursor: pointer;
										margin: .5rem;
									}
								}
								> .colorBox{
									display: flex;
									flex-wrap: wrap;
									>.item{
										margin: .5rem;
										border-radius: 1rem;
										overflow: hidden;
										border: 1px solid;
										width: 10rem;
										> .color{
											width: 10rem;
											height: 7rem;
										}
										> .text{
											font-size: 1.4rem;
											text-align: center;
										}
									}
								}
							}
							> .icon{
								margin-right: 1.2rem;
							}
							
							> i{
								display: flex;
								align-items: center;
								justify-content: center;
								animation: loading 1s linear infinite;
								@keyframes loading {
									from{
										transform: rotate(0deg);
									}
									to{
										transform: rotate(360deg);
									}
								}
							}
						}
						
					}
				}
			}
			> .content{
				background: #F9FAFA;
				// border-radius: 2.4rem;
				> textarea{
					padding: 1.6rem 2rem 0;
					background: #F9FAFA;
					width: 100%;
					min-height: 7.2rem;
					// border-radius: 2.4rem;
					font-weight: 400;
					line-height: 2rem;
					font-size: 1.4rem;
					resize: none;
					border: none;
					overflow-y: hidden;
				}
				> .btn{
					padding: 0 1.2rem 1.2rem;
					display: flex;
					justify-content: space-between;
					> .uploadBox{
						display: flex;
						align-items: center;
						> .filList{
							display: flex;
							> .item{
								height: 3rem;
								padding: .5rem 1rem;
								background: #efeff1;
								border-radius: .5rem;
								margin-right: 1rem;
								font-size: 1.4rem;
								line-height: 2rem;
								display: flex;
								> div{
									white-space: nowrap;
									overflow: hidden;
									max-width: 10rem;
									text-overflow: ellipsis;
								}
								> span{
									cursor: pointer;
								}
							}
						}
						> .enableThinking{
							width: 10rem;
							padding: .2rem .4rem;
							text-align: center;
							font-size: 1.4rem;
							border: 1px solid #000;
							border-radius: .4rem;
							cursor: pointer;
							margin-left: 1rem;
							&.active{
								background: #000;
								color: #fff;

							}
						}
					}
					i{
						font-size: 2rem;
						display: flex;
						cursor: pointer;
						position: relative;
						> input{
							width: 100%;
							height: 100%;
							position: absolute;
							top: 0;
							left: 0;
							opacity: 0;
							cursor: pointer;
							&::-webkit-file-upload-button {
								cursor: pointer;
							}
						}
					}
					> .sendBox{
						display: flex;
						align-items: center;
						
						> .maxNum{
							font-size: 1.2rem;
							margin-right: .8rem;
							font-weight: 400;
						}
						> .send{
							opacity: .5;
							cursor: no-drop;
							&.active{
								opacity: 1;
								cursor: pointer;
							}
						}
					}
				}
			}
		}
		> .right,> .left,>.top{
			display: flex;
			align-items: center;
			cursor: pointer;
			width: 3rem;
			justify-content: center;
			> i{
				display: flex;
				font-size: 2rem;
				transition: all .3s;
			}
		}
		> .top{
			width: 100%;
			margin: 0 3rem;
			height: 3rem;
			&.active{
				> i{
					transform: rotate(180deg);
				}
			}
			> i{
			}
		}
		> .right{
			border-left: 1px solid #e5e5e5;
			> i{
				transform: rotate(270deg);
			}
		}
		> .left{
			border-right: 1px solid #e5e5e5;
			> i{
				transform: rotate(90deg);
			}
		}
		flex-wrap: wrap;
	}
</style>