import React, { useState, useEffect, useRef } from "react";
import io, { Socket } from 'socket.io-client';
import '../../styles/Messages.css'
import styled from "styled-components";
import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi.tsx';
import { motion , AnimatePresence} from "framer-motion";
import Modal from "./Modal.tsx";
import GameModal from "./GameModal.tsx";

import Message from "./Message.tsx"
// import Input from "./Input";

//react icons
import { TbSend } from 'react-icons/tb';
import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md';
import { GrAdd } from 'react-icons/gr';
import { RiListSettingsLine } from 'react-icons/ri'

// import { Rank } from "../../DataBase/DataRank";
import GreenAlert from "../Alert/GreenAlert.tsx";
import RedAlert from "../Alert/RedAlert.tsx";
import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting.tsx";
import PartyInvite from "./PartyInvite.tsx";

// import {User, Conv, Message} from "../../../interfaces.tsx"
import {User, Conv} from "../../../interfaces.tsx"

const TouchDiv = styled.div`
	margin-left: 10px;
	margin-right: 4px;
	margin-bottom: 21px;
	margin-top: 21px;
	cursor: pointer;
	justify-content: space-around;
	
	&:hover {
		color: #F4F3EF;
	}
`

const UserChat = styled.div `
	padding: 5px;
	display: flex;
	align-items: center;
	gap: 5px;
	color: white;
	cursor: pointer;

	&:hover{
		background-color: #3e3c61;
	}
	&:active {
		filter: black;
	}
`

// const SideSpan = styled.span`
// 	font-size: 18px;
// 	font-weight: 500;
// `

const SideP = styled.p`
	font-size: 14px;
	color: lightgray;
	margin-left: 15px;
`

//========================================================================================================
//========================================================================================================
//                                              Logical part			                                  
//========================================================================================================
//========================================================================================================

interface MessageProps {
	id: number;
	convId: number;
 	sender: string;
 	text: string;
 	createdAt?: Date;
  }

function Chats(){
	
	const [isLoading, setIsLoading] = useState<boolean>(true);
	const [conversations, setConversation] = useState([]);
	const [partyInvite, setPartyInvite] = useState([]);
	const [user, setUser] = useState<User>();
	const [currentChat, setCurrentChat] = useState<Conv>(); // false is good?
	const [isAdmin, setIsAdmin] = useState<boolean>(false); // false is good?
	// const [currentChat, setCurrentChat] = useState(false); // false is good?
	const [messages, setMessage] = useState<MessageProps[]>([]);
	const [newMessages, setNewMessage] = useState("");
	const [incomingMessage, setIncomingMessage] = useState<MessageProps>();

	// let socket: Socket;
	const socket = useRef<Socket | null>(null);
	// const socket = Socket<DefaultEventsMap, DefaultEventsMap> | null
	// socket = useRef( useRef<SocketIOClient.Socket | null>(null));
	

	useEffect(()=> {

		const getConv = async ()=>{
			try{
				const convs = await api.get("/conv")
				const tmpInvite = await api.get("/partyInvite")
				const tmpUser = await api.get("/profile")
				const tmpUsers = await api.get("/users");

				console.log(convs);

				// console.log("invite data use effect= ", tmpInvite.data);
				setPartyInvite(tmpInvite.data);
				setUser(tmpUser.data);
				setConversation(convs.data);
				setUsers(tmpUsers.data);

				// console.log(`connection....`);
				socket.current = io('http://' + process.env.REACT_APP_SOCKET_URL + ':4001', { transports: ['polling'] });
				// console.log(`connection done`);
				socket.current.emit('connection', {username: tmpUser.data.username})
				socket.current.on('message', (data) => { //data should be a message ?)
					setIncomingMessage(data);
				});

				socket.current.on('ban', (data) => {
					// setIncomingMessage(data);
					console.log("banned hehe");
					window.location.reload()
				});

				socket.current.on('mute', (data) => {
					console.log("muted hehe");
					//set mute var to true and do nothing
				});
				
				setIsLoading(false)

			}
			catch(err){
				console.log("ERRORRRRR")
				console.log(err);
			}
		};
		getConv();

		return () => {
			console.log("Cleanup");
			if (socket.current)
				socket.current.disconnect();
		  //   cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
				// cleanup();
		  };

	}, [])

	useEffect(()=> {
		
		const updateChat = async ()=> {
			// if (currentChat)
			// 	console.log(currentChat.id)
			if (currentChat)
			{

				try {
					const res = await api.post("/isAdmin", {convId: currentChat.id})
					console.log("isadmin= ", res.data)
					setIsAdmin(res.data);
				} catch (err) {
					console.log(err);
				}
			}
			// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
			if (currentChat && incomingMessage && currentChat.id === incomingMessage.convId)
			{
				console.log("incoming meaasge=",incomingMessage)
				// if (user && !user.blocked.find(incomingMessage.sender))
					// setMessage((prev) => [...prev, incomingMessage, key: incomingMessage.id]);
					// setMessage((prev) => [...prev, { ...incomingMessage, key: incomingMessage.id }]);
					setMessage((prev) => [...prev, incomingMessage]);
			}
		}
		updateChat();

	}, [incomingMessage, currentChat])

	useEffect(()=> { 
		const getMessage = async ()=>
		{
			if (!currentChat)
				return ;
			const data = {convId: currentChat.id};

			try {
				const res = await api.post('/getMessage', data);
				console.log("message of conv=", res.data)
				setMessage(res.data);
			} catch(err) {

			}
		}
		getMessage();
	}, [currentChat]);

	const handleSubmit = async (e: { key?: any; preventDefault: any; })=>{
		e.preventDefault();
		// console.log(`e= ${e.key}`)
		// console.log(`name= ${user.username}`)
		// let message;
		console.log("in handle");
		if (!user || !currentChat)
			return ;
		const message = {
			sender: user.username,
			text: newMessages,
			convId: currentChat.id,
			members: null,
			id: null,
		};
		try{
			const allowed = await api.post('/allowed', {convId: currentChat.id});
			console.log("convid:", currentChat.id);
			if (!allowed.data)
			{
				console.log("muted or banned");
				return ;
			}
			console.log("not muted or banned");
			const res = await api.post('/message', message);
			const convMember = await api.post('/member', message);
			message.members = convMember.data.members;
			message.id = res.data.id
			setMessage([...messages, res.data]);
			setNewMessage("");
			if (socket.current)
				socket.current.emit('sendMessage', message);
		} 
		catch(err){
			 console.log(err)
		}
	}

	const handleKeyPress = async (e: { key?: any; preventDefault: () => void; })=> {
		// console.log(`e in press= ${e.key}`)
		if (e.key !== "Enter")
			return ;
		handleSubmit(e);
	}


	
	const [friend, setFriend] = useState("");
	// const [modalOpen, setModalOpen] = useState(false);
	const [addFriend, setAddFriend] = useState(false);
	const [block, setBlock] = useState(false);

	const [showAddFriendAlert, setShowAddFriendAlert] = useState(false);
	const [showBlockAlert, setShowBlockAlert] = useState(false);

	const [setting, setSetting] = useState(false);

	const [newGameModalOpen, setNewGameModalOpen] = useState(false);
	const [newConversationModalOpen, setNewConversationModalOpen] = useState(false);

    const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
	const [users, setUsers] = useState<User[]>([]);

  
	const openNewGameModal = () => {
	  setNewGameModalOpen(true);
	};
  
	const closeNewGameModal = () => {
	  setNewGameModalOpen(false);
	};
  
	const openNewConversationModal = () => {
	  setNewConversationModalOpen(true);
	};
  
	const closeNewConversationModal = () => {
	  setNewConversationModalOpen(false);
	};

	// const close = () => setModalOpen(false);
	// const open = () => setModalOpen(true);
	// const closeAddFriend = () => setAddFriend(false);
	// const closeBlock = () => setBlock(false);
	const closeSetting = () => setSetting(false);


	// const closeAddFriend = () => setAddFriend(false);
	// const closeBlock = () => setBlock(false);


	const handleFriend = (event: { target: { value: React.SetStateAction<string>; }; }) => {
		setFriend(event.target.value);
	  };
	
	  const handleAddFriend = async () => {
		try{
			console.log("friend= ", friend);
			const res = await api.post("/invite", {username: friend})
			// if (res.data === 1)
			// console.log("res in friend= ", res)
			console.log("res in friend= ", res.data)
			if(res.data === 1)
			{
			  setAddFriend(true);
			  setBlock(false); // Reset block state
			  setShowBlockAlert(false);
			}
			else
				setAddFriend(false);
			setShowAddFriendAlert(true);
		} catch(err) {
			console.log(err)
		}
	  };
	
	  const handleBlockFriend = async () => {
		try{
			const res = await api.post("/block", {username: friend})
			// if(1)
			if (res.data === 1)
			{
				setBlock(true);
				setAddFriend(false); // Reset addFriend state
				setShowAddFriendAlert(false);
			}
			else
				setBlock(false);
			setShowBlockAlert(true);
		} catch(err) {
			console.log(err)
		}
	  };
	
	  const closeAddFriend = () => {
		setAddFriend(false);
		setShowAddFriendAlert(false);
	  };
	
	  const closeBlock = () => {
		setBlock(false);
		setShowBlockAlert(false);
	  };

	  const handleOptionChange = (selectId: number, selectedOption: string) => {
		console.log("selected Option=", selectedOption)
		setFriend(selectedOption);
        setSelectTag((prevTags) => 
            prevTags.map((tag) =>
                tag.id === selectId ? { ...tag, selectedOption } : tag
            )
        );
    };

//========================================================================================================
//========================================================================================================
//                                              HTML			                                  
//========================================================================================================
//========================================================================================================


	return (
		<div className="chat">
		
			<div className='navbar'>
				<img src={DefaultPic} alt="profile" className="pic"/>
				<span>
					{isLoading || !user ? (
        				<h4>Loading...</h4>
      				) : (
        				<h4>{user.nickname}</h4>
      				)}
	  			</span>
				{/* <div className="end">
					<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
					<TouchDiv>
						<motion.div
						onClick={() => (addFriend ? setAddFriend(false) : setAddFriend(true))}>
							<MdOutlineGroupAdd/>
						</motion.div>
						<AnimatePresence
							initial={false}
							onExitComplete={() => null}
						>
							{addFriend && <GreenAlert handleClose={closeAddFriend} text={friend + " was successfuly added"}/>}
						</AnimatePresence>
					</TouchDiv>
					<TouchDiv>
						<motion.div 
						onClick={() => (block ? setBlock(false) : setBlock(true))}
						>
						<ImBlocked/>
						<AnimatePresence
							initial={false}
							onExitComplete={() => null}
							>
							{block && <RedAlert handleClose={closeBlock} text={friend + " was successfuly blocked"}/>}
						</AnimatePresence>
						</motion.div>
					</TouchDiv>
					{currentChat ? (

						<TouchDiv>
						<motion.div 
						onClick={() => (setting ? setSetting(false) : setSetting(true))}
						>
						<RiListSettingsLine/>
						<AnimatePresence
							initial={false}
							onExitComplete={() => null}
							>
							{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
						</AnimatePresence>
						</motion.div>
					</TouchDiv>
					):("")}
				</div> */}

				<div className="end">
					{selectTags.map((selectTag) => (
				  <div key={selectTag.id}>
				    <select
				      value={selectTag.selectedOption}
					  className="lookForFriends"
				      onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
				    >
				      <option value="">{
					selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
					}</option>
				      {users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.username)).map((item, index) => (
				        <option key={index} value={item.username}>
				          {item.username}
				        </option>
				      ))}
				    </select>
				  </div>
				))}
      	<TouchDiv>
        <motion.div onClick={handleAddFriend}>
          <MdOutlineGroupAdd />
        </motion.div>
        <AnimatePresence initial={false} onExitComplete={() => null}>
			{showAddFriendAlert && addFriend && (
				<GreenAlert handleClose={closeAddFriend} text={ 'invitation sent to ' + friend} />
			)}
          {showAddFriendAlert && !addFriend && (
			  <RedAlert handleClose={closeAddFriend} text={friend + ' was not found'} />
			  )}
        </AnimatePresence>
      </TouchDiv>
      <TouchDiv>
        <motion.div onClick={handleBlockFriend}>
          <ImBlocked />
        </motion.div>
        <AnimatePresence initial={false} onExitComplete={() => null}>
          {showBlockAlert && block && (
            <GreenAlert handleClose={closeBlock} text={friend + ' was successfully blocked'} />
          )}
          {showBlockAlert && !block && (
            <RedAlert handleClose={closeBlock} text={friend + ' was not found'} />
          )}
        </AnimatePresence>
      </TouchDiv>
	  {currentChat && isAdmin ? (
		<TouchDiv>
		<motion.div 
		onClick={() => (setting ? setSetting(false) : setSetting(true))}
		>
		<RiListSettingsLine/>
		<AnimatePresence
			initial={false}
			onExitComplete={() => null}
			>
			{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id.toString()} socket={socket.current}/>}
		</AnimatePresence>
		</motion.div>
		</TouchDiv>
	  ):("")}
    </div>


			</div>
			<div className="messages_box">
				<div className="contact">

	  				<UserChat>
      				  <motion.div className="newMessage" onClick={openNewGameModal}>
      				    <GrAdd />
      				    <span>New Game</span>
      				  </motion.div>
      				  {newGameModalOpen && <GameModal handleClose={closeNewGameModal} />}
      				</UserChat>

      				<UserChat>
      				  <motion.div className="newMessage" onClick={openNewConversationModal}>
      				    <GrAdd />
      				    <span>New Conversation</span>
      				  </motion.div>
      				  {newConversationModalOpen && (
      				    <Modal handleClose={closeNewConversationModal} />
      				  )}
      				</UserChat>


					{/* {partyInvite.map((c) => {
						return (

						)})
					} */}

					{partyInvite.map( i =>(
						<PartyInvite currentInvite={i}/>
					))}

					{conversations.map((c: Conv, index ) => {
						return (
						<div key={index}
							onClick={() => setCurrentChat(c)}>
							<UserChat>
							<img className="pic-user" src={DefaultPic} alt="User" />
							<div className="infoSideBar">
								<span>{c.name}</span>
								{/* <SideP>Desc?</SideP> */}
							</div>
							</UserChat>
						</div>
				
						)})}
				</div>

				{
					currentChat && user ? (
						<>
					<div className="messages">
						<div className="scroll">
							{messages.map(m=>(
								<Message key={m.id} message= {m} own={m.sender === user.username}/>
								))}
						</div>
						{/* <Input/> */}
						<div className="input">
							<input
								onKeyDown={handleKeyPress}
								type="text"
								placeholder="What do you want to say"
								onChange={(e) => setNewMessage(e.target.value)}
								value={newMessages}
							/>
							<div className="send">
								<TbSend onClick={handleSubmit}></TbSend>
							</div>
						</div>
					</div>
				</>
				) : (
					<div className="messages">
						<span className="noConv">Open a conversation</span>
					</div>
				)}
			</div>
		</div>
		// </div>
	);	
}

export default Chats