<template>
	<div class="chat" :class="{active:!openChat}" @click.stop="">
		<div v-show="!openChat" class="left" @click="()=>{openChat = !openChat;isChattingRecords=false}">
			<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 in chatList" :class="{user:item.role == 'user'}">
						<div class="textBox">
							<div class="icon">ICON</div>
							<div class="text" v-show="item.content.message || item.content.img || item.content.color">
								<span>{{item.content.message}}</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">
									<img v-if="item.content?.img?.length > 0" v-for="imgItem in item.content?.img" :src="imgItem.minioUrl" alt="">
								</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.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="Write your 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-br-upload">
							<input type="file" @change="handleFileUpload($event)">
						</i>
					</div>
					<div class="sendBox">
						<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div>
						<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="()=>{openChat = !openChat;isChattingRecords=false}">
			<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 { useStore } from "vuex";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
export default defineComponent({
	components:{
	},
	props:{
	},
	emits:['chatChange'],
	setup(props,{emit}) {
		const store = useStore();
		const data = reactive({
			chatContent:'',
			openChat:true,
			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){
				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 = JSON.parse(JSON.stringify(data.filList))
			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},role:'user',fileList:fileList})
			data.chatList.push({content:{message:''},role:'system'})
			const eventSource = new EventSource(`${process.env.VUE_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;
      			container.scrollTop = container.scrollHeight;
				if(JSON.parse(event.data).status == "[RUNNING]"){
					data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
				}else{
					if(JSON.parse(event.data).status == "[DESIGN_SIGNAL]"){

					}else if(JSON.parse(event.data).status == "[COLOR_SIGNAL]"){
						data.chatList.push({content:{message:''},role:'system'})
						data.chatList[data.chatList.length-1].content.color = JSON.parse(JSON.parse(event.data).tools_data).receiveCollectionElementList
						data.chatList.push({content:{message:''},role:'system'})
					}else{
						data.chatList.push({content:{message:''},role:'system'})
						data.chatList[data.chatList.length-1].content.img = JSON.parse(JSON.parse(event.data).tools_data).receiveCollectionElementList
						data.chatList.push({content:{message:''},role:'system'})
					}
					console.log(data.chatList[data.chatList.length-1].content)
					emit('chatChange',{type:JSON.parse(event.data).status})
				}
				
			};
			eventSource.onerror = function(error) {
				console.log(error,EventSource.CLOSED,eventSource.readyState)
				if (eventSource.readyState === EventSource.CLOSED) {
					data.chatList[data.chatList.length-1].content.message='服务器繁忙，请稍后再试。'

				} else {
					eventSource.close()
					data.isFinish = true
				}
			};
		}
		const getChatHistory = (objectId:number)=>{
			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 == 1){
								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==2){
								rv.content[rv.content.length - index -1].content={
									color : JSON.parse(rv.content[rv.content.length - index -1].content)
								}
							}else{
								rv.content[rv.content.length - index -1].content = {
									message:text
								}
							}
						}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)
		}
		return{
			...toRefs(dataDom),
			...toRefs(data),
			inputText,
			sendChat,
			openChattingRecords,
			handleFileUpload,
			deleteFile,
		}
	},
	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: #f5f5f5;
								max-width: 60%;
								> .text{
									> .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;

							> .text{
								// display: inline-block;
								// width: min-content;
								max-width: 100%;
								width: 100%;
								// width: min-content;
								// word-wrap: break-word;
								> .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: #f5f5f5;
				// border-radius: 2.4rem;
				> textarea{
					padding: 1.6rem 2rem 0;
					background: #f5f5f5;
					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;
								}
							}
						}
					}
					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;
						> .enableThinking{
							width: 10rem;
							padding: .2rem .4rem;
							text-align: center;
							font-size: 1.4rem;
							border: 1px solid #000;
							border-radius: .4rem;
							cursor: pointer;
							margin-right: 1rem;
							&.active{
								background: #000;
								color: #fff;

							}
						}
						> .maxNum{
							font-size: 1.2rem;
							margin-right: .8rem;
							font-weight: 400;
						}
						> .send{
							opacity: .5;
							cursor: no-drop;
							&.active{
								opacity: 1;
								cursor: pointer;
							}
						}
					}
				}
			}
		}
		> .right,> .left{
			display: flex;
			align-items: center;
			cursor: pointer;
			width: 3rem;
			justify-content: center;
			> i{
				display: flex;
				font-size: 2rem;
				transition: all .3s;
			}
		}
		> .right{
			border-left: 1px solid #e5e5e5;
			> i{
				transform: rotate(270deg);
			}
		}
		> .left{
			border-right: 1px solid #e5e5e5;
			> i{
				transform: rotate(90deg);
			}
		}
	}
</style>