import ArrowRightAltIcon from "@mui/icons-material/ArrowRightAlt";
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
import GraphicEqIcon from "@mui/icons-material/GraphicEq";
import PersonIcon from "@mui/icons-material/Person";
import { Box, IconButton, InputBase, Menu, MenuItem } from "@mui/material";
import React, { useState, useContext, useEffect, useCallback } from "react";
import ReactMarkdown from "react-markdown";
import { useNavigate } from "react-router-dom";
import remarkGfm from "remark-gfm";

import { AuthContext } from "../../../context/AuthContext";
import useWebSocket from "../../../hooks/useTextWebhook";
import { ICreateConversationResponse } from "../../../interfaces/conversation";
import { logout } from "../../../services/api/authService";
import { createConversation } from "../../../services/api/chatService";

interface ChatScreenProps {
  isOpen: boolean;
  toggleSidebar: () => void;
}

const ChatScreen: React.FC<ChatScreenProps> = ({ isOpen, toggleSidebar }) => {
  const [input, setInput] = useState<string>("");
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);

  const { messages, sendMessage, connectWebSocket } = useWebSocket();
  const authContext = useContext(AuthContext);
  const navigate = useNavigate();

  useEffect(() => {
    const initializeConversation = async () => {
      try {
        const conv = await createConversation({ modality: "text" });
        const sessionData: ICreateConversationResponse = await conv.data;
        const conversationId = sessionData.conversation_id;
        connectWebSocket(conversationId);
      } catch (error) {
        console.error("Failed to initialize conversation:", error);
      }
    };
    initializeConversation();
  }, [connectWebSocket]);

  const handleSendMessage = useCallback(() => {
    if (input.trim()) {
      try {
        sendMessage(input.trim());
        setInput("");
      } catch (error) {
        console.error("Failed to send message:", error);
      }
    }
  }, [input, sendMessage]);

  const handleVoiceInput = useCallback(() => {
    navigate("/voice-to-voice");
  }, [navigate]);

  const handleBotIconClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(event.currentTarget);
  }, []);

  const handleMenuClose = useCallback(() => {
    setAnchorEl(null);
  }, []);

  const handleLogout = useCallback(async () => {
    try {
      await logout();
    } finally {
      authContext?.logout();
    }
  }, [authContext]);

  return (
    <Box
      sx={{
        display: "flex",
        flexDirection: "column",
        height: "100%",
        bgcolor: "#f9f9f9",
        color: "#333",
      }}
    >
      <Box
        sx={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          px: 2,
          py: 1,
          borderBottom: "1px solid #e0e0e0",
          bgcolor: "#ffffff",
          zIndex: 10,
        }}
      >
        <Box sx={{ display: "flex", alignItems: "center" }}>
          {!isOpen && (
            <IconButton onClick={toggleSidebar} size="large">
              <ArrowRightAltIcon />
            </IconButton>
          )}
          <Box
            sx={{
              fontSize: "34px",
              fontWeight: "bold",
              ml: 1,
            }}
          >
            Chat Bot
          </Box>
        </Box>
        <Box>
          <IconButton size="large" onClick={handleBotIconClick}>
            <PersonIcon sx={{ fontSize: 34, color: "black" }} />
          </IconButton>
          <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
            <MenuItem onClick={handleLogout}>Logout</MenuItem>
          </Menu>
        </Box>
      </Box>

      <Box
        sx={{
          flexGrow: 1,
          overflowY: "auto",
          p: 2,
        }}
      >
        {messages.map((msg, index) => (
          <Box
            key={index}
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: msg.sender === "user" ? "flex-end" : "flex-start",
              my: 1,
            }}
          >
            {msg.sender === "bot" && (
              <Box sx={{ mr: 1 }}>
                <PersonIcon sx={{ fontSize: 30, color: "#ccc" }} />
              </Box>
            )}
            <Box
              sx={{
                maxWidth: "70%",
                p: "10px 15px",
                borderRadius: "20px",
                bgcolor: msg.sender === "user" ? "#e0e0e0" : "#f5f5f5",
                color: msg.sender === "user" ? "#333" : "#555",
              }}
            >
              {msg.sender === "bot" ? (
                <ReactMarkdown remarkPlugins={[remarkGfm]}>
                  {`${msg.text}${!msg.isComplete ? "▊" : ""}`}
                </ReactMarkdown>
              ) : (
                msg.text
              )}
            </Box>
          </Box>
        ))}
      </Box>

      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          p: 2,
          borderTop: "1px solid #e0e0e0",
          bgcolor: "#ffffff",
          position: "sticky",
          bottom: 0,
          zIndex: 10,
        }}
      >
        <InputBase
          fullWidth
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && handleSendMessage()}
          placeholder="Type a message..."
          sx={{
            flex: 1,
            px: 2,
            py: 1,
            border: "1px solid #ddd",
            borderRadius: "20px",
            bgcolor: "#f9f9f9",
            "& input::placeholder": {
              color: "#aaa",
            },
          }}
        />
        <IconButton
          onClick={input.length === 0 ? handleVoiceInput : handleSendMessage}
          sx={{
            ml: 1,
            bgcolor: "text.primary",
            color: "white",
            "&:hover": {
              bgcolor: "darkgray",
            },
            padding: "5px",
            borderRadius: "8px",
          }}
        >
          {input.length === 0 ? <GraphicEqIcon /> : <ArrowUpwardIcon />}
        </IconButton>
      </Box>
    </Box>
  );
};

export default ChatScreen;
