import { ReactElement, useContext, useEffect, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { drawerWidth } from 'layouts/main-layout';

import {
  ConverationAPI,
  ConversationItem,
  GenericCategory,
  MessagesAPI,
  VendorCategory,
  VendorItem,
} from 'types';
import DashboardTemplate from 'components/DasboardTemplate';
import CategoryGridTemplate from 'components/CategoryGridTemplate';
import VendorCategoryCard from 'components/sections/dashboard/Home/Vendor/VendorCategoryCard';
import ItemListDetailTemplate from 'components/ItemListDetailTemplate';
import VendorListItem from 'components/sections/dashboard/Home/Vendor/VendorListItem';
import VendorDetail from 'components/sections/dashboard/Home/Vendor/VendorDetail';
import { axiosInstance } from '../../axiosApi';
import {
  Box,
  Container,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Autocomplete,
  List,
  Grid,
  ListItem,
  ListItemText,
  Typography,
  Paper,
  TextField,
  Button,
  Avatar,
  Stack,
} from '@mui/material';
import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline';
import SendIcon from '@mui/icons-material/Send';
import { AxiosResponse } from 'axios';
import { AccountContext } from 'contexts/AccountContext';
import { DefaultDataProvider } from 'echarts/types/src/data/helper/dataProvider.js';
import { formatTimestamp } from 'utils';
import CreateConversationDialogContent from 'components/sections/dashboard/Home/Messages/CreateConversationDialogContent';

interface Message {
  id: number;
  senderId: 'owner' | 'vendor'; // 'owner' represents the property owner, 'vendor' is the other party
  content: string;
  timestamp: string; // ISO string for date/time
}

interface Conversation {
  id: number;
  withName: string; // Name of the vendor or property owner
  lastMessageSnippet: string;
  lastMessageTimestamp: string;
  messages: Message[];
}

const Messages = (): ReactElement => {
  const [searchParams] = useSearchParams();
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [selectedConversationId, setSelectedConversationId] = useState<number | null>(null);
  const [newMessageContent, setNewMessageContent] = useState<string>('');
  const { account } = useContext(AccountContext);
  const [openCreateConversationDialog, setOpenCreateConversationDialog] = useState(false);
  const [vendors, setVendors] = useState<VendorItem[]>([]);
  const [selectedVendor, setSelectedVendor] = useState<VendorItem | null>(null);

  // Auto-scroll to the bottom of the messages when they update
  const messagesEndRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const selectedConversation = searchParams.get('selectedConversation');
    if (selectedConversation) {
      console.log(selectedConversation);
      setSelectedConversationId(parseInt(selectedConversation, 10));
    }
  }, [searchParams]);

  useEffect(() => {
    const fetchVendors = async () => {
      try {
        const { data }: AxiosResponse<VendorItem[]> = await axiosInstance.get('/vendors/');
        setVendors(data);
      } catch (error) {
        console.error('Failed to fetch vendors', error);
      }
    };
    fetchVendors();
  }, []);

  useEffect(() => {
    const fetchConversations = async () => {
      try {
        const { data }: AxiosResponse<ConverationAPI[]> =
          await axiosInstance.get('/conversations/');
        console.log(data);
        if (data.length > 0) {
          console.log(data);
          const fetchedConversations: Conversation[] = data.map((item) => {
            const lastMessageSnippet: string =
              item.messages.length > 0 ? item.messages[item.messages.length - 1].text : '';
            const messages: Message[] = item.messages.map((message) => {
              return {
                id: message.id,
                content: message.text,
                timestamp: message.timestamp,
                senderId: message.sender === item.property_owner.user.id ? 'owner' : 'vendor',
              };
            });
            console.log(messages);
            return {
              id: item.id,
              withName: item.vendor.business_name,
              lastMessageTimestamp: item.updated_at,
              lastMessageSnippet: lastMessageSnippet,
              messages: messages,
            };
          });
          console.log(fetchedConversations);
          setConversations(fetchedConversations);
        }
      } catch (error) {}
    };
    fetchConversations();
  }, []);

  useEffect(() => {
    if (messagesEndRef.current) {
      messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  }, [selectedConversationId, conversations]); // Re-run when conversation changes or messages update

  const handleOpenCreateConversationDialog = () => {
    setOpenCreateConversationDialog(true);
  };

  const handleCloseCreateConversationDialog = () => {
    setOpenCreateConversationDialog(false);
    setSelectedVendor(null);
  };

  const handleCreateConversation = async () => {
    if (!selectedVendor) {
      return;
    }
    try {
      console.log(selectedVendor);

      // first make sure that there isn't already a conversation
      const { data }: AxiosResponse<ConverationAPI[]> = await axiosInstance.get(
        `/conversations/?vendor=${selectedVendor.user.id}`,
      );

      if (data.length === 0) {
        const { data }: AxiosResponse<ConverationAPI> = await axiosInstance.post(
          `/conversations/`,
          {
            property_owner: account?.id,
            vendor: selectedVendor.user.id,
          },
        );
        console.log(data);
        const newConversationData = data;
        console.log(newConversationData);

        const lastMessageSnippet: string =
          newConversationData.messages.length > 0
            ? newConversationData.messages[newConversationData.messages.length - 1].text
            : '';
        const messages: Message[] = newConversationData.messages.map((message: any) => {
          return {
            id: message.id,
            content: message.text,
            timestamp: message.timestamp,
            senderId:
              message.sender === newConversationData.property_owner.user.id ? 'owner' : 'vendor',
          };
        });
        const newConversation: Conversation = {
          id: newConversationData.id,
          withName: selectedVendor.business_name,
          lastMessageTimestamp: newConversationData.updated_at,
          lastMessageSnippet: lastMessageSnippet,
          messages: messages,
        };

        setConversations((prev) => [newConversation, ...prev]);
        setSelectedConversationId(newConversation.id);
      } else {
        setSelectedConversationId(data[0].id);
      }

      handleCloseCreateConversationDialog();
    } catch (error) {
      console.error('Failed to create conversation', error);
    }
  };

  const selectedConversation = conversations.find((conv) => conv.id === selectedConversationId);

  // Handle sending a new message
  const handleSendMessage = async () => {
    if (!newMessageContent.trim() || !selectedConversationId) {
      return; // Don't send empty messages or if no conversation is selected
    }

    // send the message to the backend
    try {
      const { data }: AxiosResponse<MessagesAPI> = await axiosInstance.post(
        `/conversations/${selectedConversationId}/messages/`,
        {
          sender: account?.id,
          text: newMessageContent.trim(),
          conversation: selectedConversationId,
        },
      );
      console.log(data);
      const newMessage: Message = {
        id: data.id,
        senderId: 'owner', // Assuming the current user is the 'owner'
        content: newMessageContent.trim(),
        timestamp: data.timestamp,
      };

      setConversations((prevConversations) =>
        prevConversations.map((conv) =>
          conv.id === selectedConversationId
            ? {
                ...conv,
                messages: [...conv.messages, newMessage],
                lastMessageSnippet: newMessage.content,
                lastMessageTimestamp: newMessage.timestamp,
              }
            : conv,
        ),
      );
      setNewMessageContent(''); // Clear the input field
    } catch (error) {}
  };

  return (
    <Container
      sx={{ py: 4, height: '90vh', width: 'fill', display: 'flex', flexDirection: 'column' }}
    >
      <Paper
        elevation={3}
        sx={{ flexGrow: 1, display: 'flex', borderRadius: 3, overflow: 'hidden' }}
      >
        <Grid container sx={{ height: '100%', width: '100%' }}>
          {/* Left Panel: Conversation List */}
          <Grid
            size={{ xs: 12, md: 4 }}
            sx={{
              borderRight: { md: '1px solid', borderColor: 'grey.200' },
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            <Box sx={{ p: 3, borderBottom: '1px solid', borderColor: 'grey.200', display: 'flex' }}>
              <Stack direction="row" sx={{ width: '100%' }}>
                <Typography variant="h5" component="h2" sx={{ fontWeight: 'bold' }}>
                  Conversations
                </Typography>
                {account?.user_type === 'property_owner' && (
                  <Button
                    variant="contained"
                    color="primary"
                    sx={{ ml: 'auto' }}
                    onClick={handleOpenCreateConversationDialog}
                  >
                    Create
                  </Button>
                )}
              </Stack>
            </Box>
            <List sx={{ flexGrow: 1, overflowY: 'auto', p: 1 }}>
              {conversations.length === 0 ? (
                <Box sx={{ p: 2, textAlign: 'center', color: 'grey.500' }}>
                  <ChatBubbleOutlineIcon sx={{ fontSize: 40, mb: 1 }} />
                  <Typography>No conversations yet.</Typography>
                </Box>
              ) : (
                conversations
                  .sort(
                    (a, b) =>
                      new Date(b.lastMessageTimestamp).getTime() -
                      new Date(a.lastMessageTimestamp).getTime(),
                  )
                  .map((conv) => (
                    <ListItem
                      key={conv.id}
                      button
                      selected={selectedConversationId === conv.id}
                      onClick={() => setSelectedConversationId(conv.id)}
                      sx={{ py: 1.5, px: 2 }}
                    >
                      <ListItemText
                        primary={
                          <Typography variant="subtitle1" sx={{ fontWeight: 'medium' }}>
                            {conv.withName}
                          </Typography>
                        }
                        secondary={
                          <Box
                            sx={{
                              display: 'flex',
                              justifyContent: 'space-between',
                              alignItems: 'center',
                            }}
                          >
                            <Typography
                              variant="body2"
                              color="text.secondary"
                              noWrap
                              sx={{ flexGrow: 1, pr: 1 }}
                            >
                              {conv.lastMessageSnippet}
                            </Typography>
                            <Typography variant="caption" color="text.disabled">
                              {formatTimestamp(conv.lastMessageTimestamp)}
                            </Typography>
                          </Box>
                        }
                      />
                    </ListItem>
                  ))
              )}
            </List>
          </Grid>

          {/* Right Panel: Conversation Detail */}
          <Grid size={{ xs: 12, md: 8 }} sx={{ display: 'flex', flexDirection: 'column' }}>
            {selectedConversation ? (
              <>
                {/* Conversation Header */}
                <Box
                  sx={{
                    p: 3,
                    borderBottom: '1px solid',
                    borderColor: 'grey.200',
                    display: 'flex',
                    alignItems: 'center',
                    gap: 2,
                  }}
                >
                  <Avatar sx={{ bgcolor: 'purple.200' }}>
                    {selectedConversation.withName
                      .split(' ')
                      .map((n) => n[0])
                      .join('')}
                  </Avatar>
                  <Typography variant="h6" component="h3" sx={{ fontWeight: 'bold' }}>
                    {selectedConversation.withName}
                  </Typography>
                </Box>

                {/* Messages Area */}
                <Box sx={{ flexGrow: 1, overflowY: 'auto', p: 3, bgcolor: 'grey.50' }}>
                  {selectedConversation.messages.map((message) => (
                    <Box
                      key={message.id}
                      sx={{
                        display: 'flex',
                        justifyContent: message.senderId === 'owner' ? 'flex-end' : 'flex-start',
                        mb: 2,
                      }}
                    >
                      <Box
                        sx={{
                          maxWidth: '75%',
                          p: 1.5,
                          borderRadius: 2,
                          bgcolor: message.senderId === 'owner' ? 'purple.200' : 'lightblue.50',
                          color: 'grey.800',
                          boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
                        }}
                      >
                        <Typography variant="body2" sx={{ fontWeight: 'medium', mb: 0.5 }}>
                          {message.senderId === 'owner' ? 'You' : selectedConversation.withName}
                        </Typography>
                        <Typography variant="body1">{message.content}</Typography>
                        <Typography
                          variant="caption"
                          color="text.secondary"
                          sx={{ display: 'block', textAlign: 'right', mt: 0.5 }}
                        >
                          {formatTimestamp(message.timestamp)}
                        </Typography>
                      </Box>
                    </Box>
                  ))}
                  <div ref={messagesEndRef} /> {/* Scroll target */}
                </Box>

                {/* Message Input */}
                <Box
                  sx={{
                    p: 2,
                    borderTop: '1px solid',
                    borderColor: 'grey.200',
                    display: 'flex',
                    alignItems: 'center',
                    gap: 2,
                  }}
                >
                  <TextField
                    fullWidth
                    variant="outlined"
                    placeholder="Type your message..."
                    value={newMessageContent}
                    onChange={(e) => setNewMessageContent(e.target.value)}
                    onKeyPress={(e) => {
                      if (e.key === 'Enter') {
                        handleSendMessage();
                      }
                    }}
                    size="small"
                    sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }}
                  />
                  <Button
                    variant="contained"
                    color="primary"
                    onClick={handleSendMessage}
                    endIcon={<SendIcon />}
                    sx={{ px: 3, py: 1.2 }}
                  >
                    Send
                  </Button>
                </Box>
              </>
            ) : (
              <Box
                sx={{
                  flexGrow: 1,
                  display: 'flex',
                  flexDirection: 'column',
                  justifyContent: 'center',
                  alignItems: 'center',
                  p: 3,
                  color: 'grey.500',
                }}
              >
                <ChatBubbleOutlineIcon sx={{ fontSize: 80, mb: 2 }} />
                <Typography variant="h6">Select a conversation to view messages</Typography>
                <Typography variant="body2">
                  Click on a conversation from the left panel to get started.
                </Typography>
              </Box>
            )}
          </Grid>
        </Grid>
      </Paper>
      <CreateConversationDialogContent
        showDialog={openCreateConversationDialog}
        closeDialog={handleCloseCreateConversationDialog}
        createConversation={handleCreateConversation}
        vendors={vendors}
        setSelectedVendor={setSelectedVendor}
        selectedVendor={selectedVendor}
      />
    </Container>
  );
};

export default Messages;
