package localserver

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/pion/webrtc/v3"
)

const (
	ZONE_CHAT_WEBRTC_OFFER                 ReqType = "zone_chat_offer"
	ZONE_CHAT_WEBRTC_ANSWER                ReqType = "zone_chat_answer"
	ZONE_CHAT_WEBRTC_RENNEGOTIATION_OFFER  ReqType = "zone_chat_rennegotiation_offer"
	ZONE_CHAT_WEBRTC_RENNEGOTIATION_ANSWER ReqType = "zone_chat_rennegotiation_answer"
	ZONE_CHAT_WEBRTC_COUNTER_OFFER         ReqType = "zone_chat_webrtc_counter_offer"
	ZONE_CHAT_WEBRTC_CANDIDATE             ReqType = "zone_chat_webrtc_candidate"
)

type ZippytalFSInstance interface {
	SetupFileUpload(path, filename, userId string, dc *webrtc.DataChannel) (writePipe chan []byte, err error)
	FileUploadFailed(path, filename, userId string) (err error)
	SetupFileDownload(path, filename, userId string, dc *webrtc.DataChannel) (err error)
	FileDownloadFailed(path, filename, userId string) (err error)
}

type ChatFSInstance struct {
	ZoneID           string              `json:"id"`
	Owner            string              `json:"owner"`
	Members          []string            `json:"members"`
	OpenFiles        map[string]*os.File `json:"-"`
	OpenFilesForUser map[string][]string `json:"-"`
	// localSD                  map[string]*webrtc.SessionDescription `json:"-"`
	// rtcPeerConnections       map[string]*ZoneRTCPeerConnection     `json:"-"`
	// zoneFSDataChannels       map[string]map[string]*DataChannel    `json:"-"`
	// pendingCandidates        map[string][]*webrtc.ICECandidate     `json:"-"`
	// middlewares              []interface{}                         `json:"-"`
	// candidateFlag            *uint32                               `json:"-"`
	filesFlag *uint32 `json:"-"`
	// rtcPeerConnectionMapFlag *uint32                               `json:"-"`
	// dataChannelMapFlag       *uint32                               `json:"-"`
	// localSDMapFlag           *uint32                               `json:"-"`
}

type ChatFSInstanceOnICECandidateFunc = func(string, string, *webrtc.ICECandidate) error

func NewChatFSInstance(id, owner string, members []string) (chatFSInstance *ChatFSInstance) {
	// candidateFlag := uint32(0)
	// rtcPeerConnectionMapFlag := uint32(0)
	// dataChannelMapFlag := uint32(0)
	filesFlag := uint32(0)
	// localSDMapFlag := uint32(0)
	chatFSInstance = &ChatFSInstance{
		ZoneID:           id,
		Owner:            owner,
		Members:          members,
		OpenFiles:        make(map[string]*os.File),
		OpenFilesForUser: make(map[string][]string),
		// localSD:                  make(map[string]*webrtc.SessionDescription),
		// rtcPeerConnections:       make(map[string]*ZoneRTCPeerConnection),
		// zoneFSDataChannels:       make(map[string]map[string]*DataChannel),
		// pendingCandidates:        make(map[string][]*webrtc.ICECandidate),
		// middlewares:              make([]interface{}, 0),
		// candidateFlag:            &candidateFlag,
		filesFlag: &filesFlag,
		// rtcPeerConnectionMapFlag: &rtcPeerConnectionMapFlag,
		// dataChannelMapFlag:       &dataChannelMapFlag,
		// localSDMapFlag:           &localSDMapFlag,
	}
	return
}

func (fs *ChatFSInstance) SetupFileUpload(chatId, filename, userId string, dc *webrtc.DataChannel) (writePipe chan []byte, err error) {
	concretePath := filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename)
	if _, err = os.ReadDir(filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId)); err != nil {
		return
	}
	if _, rErr := os.ReadDir(filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId, "__files__")); os.IsNotExist(rErr) {
		if err = os.MkdirAll(filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId, "__files__"), 0700); err != nil {
			return
		}
	} else if rErr != nil {
		return nil, rErr
	}
	if err = os.Remove(concretePath); err != nil {
		logger.Println(err)
	}
	file, err := os.OpenFile(concretePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0755)
	if err != nil {
		return
	}
	// _ = atomicallyExecute(fs.filesFlag, func() (err error) {
	// 	fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)] = file
	// 	if _, ok := fs.OpenFilesForUser[userId]; !ok {
	// 		fs.OpenFilesForUser[userId] = []string{}
	// 	}
	// 	fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId], fmt.Sprintf("%s/%s", filename, userId))
	// 	return
	// })
	writePipe = make(chan []byte)
	go func(f *os.File) {
		defer func() {
			_ = f.Close()
			// _ = atomicallyExecute(fs.filesFlag, func() (err error) {
			// 	if f, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok {
			// 		err = f.Close()
			// 	}
			// 	delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId))
			// 	if _, ok := fs.OpenFilesForUser[userId]; ok {
			// 		var index int
			// 		for i, v := range fs.OpenFilesForUser[userId] {
			// 			if v == fmt.Sprintf("%s/%s", filename, userId) {
			// 				index = i
			// 				break
			// 			}
			// 		}
			// 		if len(fs.OpenFilesForUser[userId]) > 1 {
			// 			fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...)
			// 		} else {
			// 			delete(fs.OpenFilesForUser, userId)
			// 		}
			// 	}
			// 	return
			// })
		}()
		for chunk := range writePipe {
			if _, err = file.Write(chunk); err != nil {
				return
			}
		}
	}(file)
	return
}

func (fs *ChatFSInstance) FileUploadFailed(chatId, filename, userId string) (err error) {
	concretePath := filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename)
	err = os.Remove(concretePath)
	return
}

func (fs *ChatFSInstance) SetupFileDownload(chatId, filename, userId string, dc *webrtc.DataChannel) (err error) {
	concretePath := filepath.Join(dataPath, "data", "zones", fs.ZoneID, "chats", chatId, "__files__", filename)
	file, err := os.OpenFile(concretePath, os.O_RDONLY, 0755)
	if err != nil {
		return
	}
	// _ = atomicallyExecute(fs.filesFlag, func() (err error) {
	// 	fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)] = file
	// 	if _, ok := fs.OpenFilesForUser[userId]; !ok {
	// 		fs.OpenFilesForUser[userId] = []string{}
	// 	}
	// 	fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId], fmt.Sprintf("%s/%s", filename, userId))
	// 	return
	// })
	if dc != nil {
		dc.SetBufferedAmountLowThreshold(12000000)
		bufferedAmountLock := make(chan struct{})
		go func(f *os.File) {
			defer func() {
				close(bufferedAmountLock)
				bufferedAmountLock = nil
				_ = f.Close()
				// _ = atomicallyExecute(fs.filesFlag, func() (err error) {
				// 	if f, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok {
				// 		err = f.Close()
				// 	}
				// 	delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId))
				// 	if _, ok := fs.OpenFilesForUser[userId]; ok {
				// 		var index int
				// 		for i, v := range fs.OpenFilesForUser[userId] {
				// 			if v == fmt.Sprintf("%s/%s", filename, userId) {
				// 				index = i
				// 				break
				// 			}
				// 		}
				// 		if len(fs.OpenFilesForUser[userId]) > 1 {
				// 			fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...)
				// 		} else {
				// 			delete(fs.OpenFilesForUser, userId)
				// 		}
				// 	}
				// 	return
				// })
			}()
			r := bufio.NewReader(file)
			buf := make([]byte, 0, 50000)
		sendingLoop:
			for {
				n, readErr := r.Read(buf[:cap(buf)])
				buf = buf[:n]
				if n == 0 {
					if err == nil {
						logger.Println("n is 0 weird")
						break sendingLoop
					}
					if err == io.EOF {
						break sendingLoop
					}
					logger.Println(readErr)
					return
				}
				if err = dc.Send(buf); err != nil {
					dc.Close()
					logger.Println(err)
					break sendingLoop
				}
				if dc.BufferedAmount() > dc.
					BufferedAmountLowThreshold() {
					<-bufferedAmountLock
				}
			}
			logger.Println("done")
			if err = dc.SendText("download_done"); err != nil {
				logger.Println(err)
			}
		}(file)
		dc.OnBufferedAmountLow(func() {
			if bufferedAmountLock != nil {
				bufferedAmountLock <- struct{}{}
			}
		})
	} else {
		err = fmt.Errorf("datachannel not created")
		_ = atomicallyExecute(fs.filesFlag, func() (err error) {
			if file, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok {
				file.Close()
			}
			delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId))
			return
		})
	}
	return
}

func (fs *ChatFSInstance) FileDownloadFailed(chatId, filename, userId string) (err error) {
	err = atomicallyExecute(fs.filesFlag, func() (err error) {
		if file, ok := fs.OpenFiles[fmt.Sprintf("%s/%s", filename, userId)]; ok {
			file.Close()
		}
		delete(fs.OpenFiles, fmt.Sprintf("%s/%s", filename, userId))
		if _, ok := fs.OpenFilesForUser[userId]; ok {
			var index int
			for i, v := range fs.OpenFilesForUser[userId] {
				if v == fmt.Sprintf("%s/%s", filename, userId) {
					index = i
					break
				}
			}
			if len(fs.OpenFilesForUser[userId]) > 1 {
				fs.OpenFilesForUser[userId] = append(fs.OpenFilesForUser[userId][:index], fs.OpenFilesForUser[userId][:index+1]...)
			} else {
				delete(fs.OpenFilesForUser, userId)
			}
		}
		return
	})
	return
}

// func (fs *ChatFSInstance) HandleOffer(ctx context.Context, channelId, userId, sdp, hostId string, sendDCMessage SendDCMessageFunc, cb ChatFSInstanceOnICECandidateFunc) (done chan struct{}, errCh chan error) {
// 	done, errCh = make(chan struct{}), make(chan error)
// 	go func() {
// 		peerConnection, err := fs.createPeerConnection(userId, fs.ZoneID, webrtc.SDPTypeAnswer, cb, sendDCMessage)
// 		if err != nil {
// 			errCh <- err
// 			return
// 		}
// 		_ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 			fs.rtcPeerConnections[userId] = &ZoneRTCPeerConnection{
// 				PeerConnection:  peerConnection,
// 				makingOffer:     false,
// 				makingOfferLock: &sync.Mutex{},
// 			}
// 			return
// 		})
// 		offer := webrtc.SessionDescription{
// 			Type: webrtc.SDPTypeOffer,
// 			SDP:  sdp,
// 		}
// 		if err = peerConnection.SetRemoteDescription(offer); err != nil {
// 			errCh <- err
// 			return
// 		}
// 		rawAnswer, err := peerConnection.CreateAnswer(nil)
// 		if err != nil {
// 			errCh <- err
// 			return
// 		}
// 		if err = peerConnection.SetLocalDescription(rawAnswer); err != nil {
// 			errCh <- err
// 			return
// 		}
// 		_, _ = sendDCMessage(string(ZONE_CHAT_WEBRTC_ANSWER), hostId, userId, map[string]interface{}{
// 			"to":        userId,
// 			"from":      fs.ZoneID,
// 			"channelId": channelId,
// 			"sdp":       rawAnswer.SDP,
// 		})
// 		done <- struct{}{}
// 		logger.Println("handle offer done")
// 	}()
// 	return
// }

// func (fs *ChatFSInstance) HandleCounterOffer(ctx context.Context, userId string, sendDCMessage SendDCMessageFunc) (err error) {
// 	// if err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 	// 	if _, ok := fs.rtcPeerConnections[userId]; !ok {
// 	// 		err = fmt.Errorf("no field corresponding peer connection for id %s", userId)
// 	// 		return
// 	// 	}
// 	// 	logger.Println("handling counter offer")
// 	// connection := fs.rtcPeerConnections[userId]
// 	// err = atomicallyExecute(fs.localSDMapFlag, func() (err error) {
// 	// err = connection.SetLocalDescription(*fs.localSD[userId])
// 	// 	return
// 	// })
// 	// 	return
// 	// }); err != nil {
// 	// 	return
// 	// }
// 	// _ = atomicallyExecute(fs.localSDMapFlag, func() (err error) {
// 	// 	delete(fs.localSD, userId)
// 	// 	return
// 	// })
// 	if err = atomicallyExecute(fs.candidateFlag, func() (err error) {
// 		for _, candidate := range fs.pendingCandidates[userId] {
// 			logger.Println("sending candidate to", userId, candidate)
// 			d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_CANDIDATE), "", userId, map[string]interface{}{
// 				"from":          fs.ZoneID,
// 				"to":            userId,
// 				"candidate":     candidate.ToJSON().Candidate,
// 				"sdpMid":        *candidate.ToJSON().SDPMid,
// 				"sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)),
// 			})
// 			select {
// 			case <-d:
// 			case err = <-e:
// 				return
// 			}
// 		}
// 		delete(fs.pendingCandidates, userId)
// 		return
// 	}); err != nil {
// 		return
// 	}
// 	return
// }

// func (fs *ChatFSInstance) HandleRennegotiationOffer(from, sdp string, sendDCMessage SendDCMessageFunc) (err error) {
// 	err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 		if _, ok := fs.rtcPeerConnections[from]; !ok {
// 			err = fmt.Errorf("no corresponding peer connection for id %s", from)
// 			return
// 		}
// 		//fs.rtcPeerConnections[from].makingOfferLock.Lock()
// 		if fs.rtcPeerConnections[from].makingOffer {
// 			//fs.rtcPeerConnections[from].makingOfferLock.Unlock()
// 			return fmt.Errorf("already making an offer or state is stable")
// 		}
// 		//fs.rtcPeerConnections[from].makingOfferLock.Unlock()
// 		if err = fs.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeOffer}); err != nil {
// 			return
// 		}
// 		localSd, err := fs.rtcPeerConnections[from].CreateAnswer(nil)
// 		if err != nil {
// 			return
// 		}
// 		if err = fs.rtcPeerConnections[from].SetLocalDescription(localSd); err != nil {
// 			return
// 		}
// 		d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_ANSWER), fs.ZoneID, from, map[string]interface{}{
// 			"from": fs.ZoneID,
// 			"to":   from,
// 			"sdp":  localSd.SDP,
// 		})
// 		select {
// 		case <-d:
// 		case err = <-e:
// 		}
// 		return
// 	})
// 	return
// }

// func (fs *ChatFSInstance) HandleRennegotiationAnswer(from, sdp string) (err error) {
// 	logger.Println("---------------------handling rennego answer")
// 	err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 		err = fs.rtcPeerConnections[from].SetRemoteDescription(webrtc.SessionDescription{SDP: sdp, Type: webrtc.SDPTypeAnswer})
// 		return
// 	})
// 	return
// }

// func (fs *ChatFSInstance) AddCandidate(candidate *webrtc.ICECandidateInit, from string) (err error) {
// 	logger.Println("adding ice candidate", candidate)
// 	err = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 		if _, ok := fs.rtcPeerConnections[from]; ok && candidate != nil {
// 			err = fs.rtcPeerConnections[from].AddICECandidate(*candidate)
// 		}
// 		return
// 	})
// 	return
// }

// func (fs *ChatFSInstance) createPeerConnection(target, from string, peerType webrtc.SDPType, cb ChatFSInstanceOnICECandidateFunc, sendDCMessage SendDCMessageFunc) (peerConnection *webrtc.PeerConnection, err error) {
// 	defer func() {
// 		if r := recover(); err != nil {
// 			logger.Printf("recover from panic : %v\n", r)
// 		}
// 	}()
// 	config := webrtc.Configuration{
// 		ICEServers: []webrtc.ICEServer{
// 			{
// 				URLs: []string{"stun:stun.l.google.com:19302", "stun:stunserver.org:3478"},
// 			},
// 		},
// 	}

// 	peerConnection, err = webrtc.NewPeerConnection(config)
// 	if err != nil {
// 		return
// 	}
// 	logger.Println("---------------------------------------------------")
// 	if peerType == webrtc.SDPTypeAnswer {
// 		maxRetransmits := uint16(1)
// 		channel, err := peerConnection.CreateDataChannel("data", &webrtc.DataChannelInit{
// 			MaxRetransmits: &maxRetransmits,
// 		})
// 		if err != nil {
// 			return nil, err
// 		}
// 		channel.OnOpen(func() {
// 			logger.Println("channel opened")
// 			if chanErr := channel.SendText("yooo man this is open"); chanErr != nil {
// 				logger.Println(chanErr)
// 			}
// 		})
// 		channel.OnMessage(func(msg webrtc.DataChannelMessage) {
// 			var event CallEvent
// 			if err := json.Unmarshal(msg.Data, &event); err != nil {
// 				logger.Println(err)
// 				return
// 			}
// 			if e := fs.HandleDataChannelEvents(event.From, event.EventId, event.Payload); e != nil {
// 				logger.Println("*-------------- datachannel error: ", e)
// 			}
// 		})
// 		logger.Println("new channel for target : ", target)
// 		channel.SetBufferedAmountLowThreshold(bufferedAmountLowThreshold)
// 		channel.OnBufferedAmountLow(func() {

// 		})
// 		channel.OnClose(func() {

// 		})
// 		_ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) {
// 			logger.Println(target)
// 			l := uint32(0)
// 			if _, ok := fs.zoneFSDataChannels[target]; !ok {
// 				fs.zoneFSDataChannels[target] = make(map[string]*DataChannel)
// 			}
// 			fs.zoneFSDataChannels[target][channel.Label()] = &DataChannel{
// 				DataChannel: channel,
// 				l:           &l,
// 			}
// 			return
// 		})
// 	} else {
// 		peerConnection.OnDataChannel(func(dc *webrtc.DataChannel) {
// 			_ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) {
// 				l := uint32(0)
// 				if _, ok := fs.zoneFSDataChannels[target]; !ok {
// 					fs.zoneFSDataChannels[target] = make(map[string]*DataChannel)
// 				}
// 				fs.zoneFSDataChannels[target][dc.Label()] = &DataChannel{
// 					DataChannel: dc,
// 					l:           &l,
// 				}
// 				return
// 			})
// 			dc.OnOpen(func() {
// 				logger.Printf("got a new open datachannel %s\n", dc.Label())
// 			})
// 			dc.OnMessage(func(msg webrtc.DataChannelMessage) {
// 				var event CallEvent
// 				if err := json.Unmarshal(msg.Data, &event); err != nil {
// 					logger.Println(err)
// 					return
// 				}
// 				if e := fs.HandleDataChannelEvents(event.From, event.EventId, event.Payload); e != nil {
// 					logger.Println("*-------------- datachannel error: ", e)
// 				}
// 			})
// 			dc.OnClose(func() {
// 				_ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) {
// 					if _, ok := fs.zoneFSDataChannels[target]; ok {
// 						delete(fs.zoneFSDataChannels[target], dc.Label())
// 						fs.HandleLeavingMember(target)
// 					}
// 					return
// 				})
// 			})
// 			_ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) {
// 				logger.Println(target)
// 				l := uint32(0)
// 				if _, ok := fs.zoneFSDataChannels[target]; !ok {
// 					fs.zoneFSDataChannels[target] = make(map[string]*DataChannel)
// 				}
// 				fs.zoneFSDataChannels[target][dc.Label()] = &DataChannel{
// 					DataChannel: dc,
// 					l:           &l,
// 				}
// 				return
// 			})
// 		})
// 	}
// 	peerConnection.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) {
// 		if pcs == webrtc.PeerConnectionStateClosed || pcs == webrtc.PeerConnectionStateDisconnected || pcs == webrtc.PeerConnectionStateFailed {
// 			logger.Println(pcs)
// 			fs.HandleLeavingMember(target)
// 		}
// 	})
// 	peerConnection.OnICEConnectionStateChange(func(is webrtc.ICEConnectionState) {
// 		logger.Printf("ICE connection state has changed %s\n", is.String())
// 		if is == webrtc.ICEConnectionStateDisconnected || is == webrtc.ICEConnectionStateFailed {
// 			logger.Println(is)
// 			fs.HandleLeavingMember(target)
// 		}
// 	})
// 	peerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
// 		if i == nil {
// 			return
// 		}
// 		_ = atomicallyExecute(fs.candidateFlag, func() (err error) {
// 			desc := peerConnection.RemoteDescription()
// 			if desc == nil {
// 				logger.Println("generated candidate appended to list : ", i)
// 				fs.pendingCandidates[target] = append(fs.pendingCandidates[target], i)
// 			} else {
// 				logger.Println("generated candidate : ", i)
// 				if iceCandidateErr := cb(from, target, i); iceCandidateErr != nil {
// 					logger.Println(iceCandidateErr)
// 				}
// 			}
// 			return
// 		})
// 	})
// 	// peerConnection.OnNegotiationNeeded(func() {
// 	// 	logger.Println("---------------- rennego is needed -----------")
// 	// 	_ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 	// 		logger.Println("----------------- sending renego to peer with id", target)
// 	// 		if peerConnection.SignalingState() == webrtc.SignalingStateStable {
// 	// 			localSd, localSdErr := peerConnection.CreateOffer(nil)
// 	// 			if localSdErr != nil {
// 	// 				logger.Println(localSdErr)
// 	// 				return localSdErr
// 	// 			}
// 	// 			if err = peerConnection.SetLocalDescription(localSd); err != nil {
// 	// 				logger.Println(err)
// 	// 				return
// 	// 			}
// 	// 			d, e := sendDCMessage(string(ZONE_CHAT_WEBRTC_RENNEGOTIATION_OFFER), fs.ZoneID, target, map[string]interface{}{
// 	// 				"from": fs.ZoneID,
// 	// 				"to":   target,
// 	// 				"sdp":  localSd.SDP,
// 	// 			})
// 	// 			select {
// 	// 			case <-d:
// 	// 			case err = <-e:
// 	// 				logger.Println(err)
// 	// 			}
// 	// 		}
// 	// 		return
// 	// 	})
// 	// })
// 	return
// }

// func (fs *ChatFSInstance) HandleLeavingMember(id string) {
// 	_ = atomicallyExecute(fs.dataChannelMapFlag, func() (err error) {
// 		if _, ok := fs.zoneFSDataChannels[id]; ok {
// 			for _, dc := range fs.zoneFSDataChannels[id] {
// 				dc.DataChannel.Close()
// 			}
// 		}
// 		delete(fs.zoneFSDataChannels, id)
// 		return
// 	})
// 	logger.Println("chatfs datachannels cleaned")
// 	_ = atomicallyExecute(fs.rtcPeerConnectionMapFlag, func() (err error) {
// 		if pc, ok := fs.rtcPeerConnections[id]; ok {
// 			if closeErr := pc.Close(); closeErr != nil {
// 				err = closeErr
// 				logger.Println("peer connection close error", closeErr)
// 			}
// 		}
// 		delete(fs.rtcPeerConnections, id)
// 		return
// 	})
// 	logger.Println("chats perrconnections cleaned")
// 	_ = atomicallyExecute(fs.candidateFlag, func() (err error) {
// 		delete(fs.pendingCandidates, id)
// 		return
// 	})
// 	_ = atomicallyExecute(fs.filesFlag, func() (err error) {
// 		for _, openFile := range fs.OpenFilesForUser[id] {
// 			if f, ok := fs.OpenFiles[openFile]; ok {
// 				_ = f.Close()
// 			}
// 			delete(fs.OpenFiles, openFile)
// 		}
// 		delete(fs.OpenFilesForUser, id)
// 		return
// 	})
// }

func (fs *ChatFSInstance) HandleDataChannelEvents(from, eventId string, payload map[string]interface{}) (err error) {
	switch eventId {
	}
	return
}
