import React, { useEffect, useState } from 'react';
import { useLocalSearchParams } from 'expo-router';
import { YStack, XStack, Text, Input, Button, ScrollView } from 'tamagui';
import { chacha20Encrypt,chacha20Decrypt } from '../../components/crypto';

const ChatApp = () => {
  const {friendUsername } = useLocalSearchParams(); // Friend's username passed via params
  const [messages, setMessages] = useState([]);
  const [inputText, setInputText] = useState('');
  const [loading, setLoading] = useState(true);
  const [friendPubKey, setFriendPubKey] = useState(null); // Friend's public key

  // Fetch friend's public key
  const fetchPublicKey = async () => {
    try {
      const authToken = localStorage.getItem('jwtToken');
      if (!authToken) {
        console.error('User is not authenticated');
        return;
      }

      const response = await fetch(`http://localhost:4000/user/pubkey?username=${friendUsername}`, {
        headers: {
          Authorization: `Bearer ${authToken}`,
        },
      });

      if (!response.ok) throw new Error('Failed to fetch public key');
      const { pubKey } = await response.json();
      setFriendPubKey(pubKey);
    } catch (err) {
      console.error('Error fetching public key:', err);
    }
  };

  // Fetch messages
  // Fetch messages
  const fetchMessages = async () => {
    try {
      const authToken = localStorage.getItem('jwtToken');
      if (!authToken) {
        console.error('User is not authenticated');
        return;
      }
  
      const response = await fetch(`http://localhost:4000/messages/?receiverUsername=${friendUsername}`, {
        headers: {
          Authorization: `Bearer ${authToken}`,
        },
      });
  
      if (!response.ok) throw new Error('Failed to fetch messages');
  
      // Fetch encrypted messages as JSON
      const encryptedMessages = await response.json();
      console.log('Encrypted Messages:', encryptedMessages); // Debug: log encrypted messages
  
      // Decrypt each message and store the decrypted result
      const decryptedMessages = await Promise.all(
        encryptedMessages.map(async (msg) => {
          const decryptedMessage = await chacha20Decrypt(msg);
          return { ...msg, content: decryptedMessage }; // Attach decrypted message to original message
        })
      );
  
      console.log('Decrypted Messages:', decryptedMessages); // Debug: log decrypted messages
  
      // Update the state with the decrypted messages
      setMessages(decryptedMessages);
    } catch (err) {
      console.error('Error fetching messages:', err);
      setMessages(["Error fetching messages"]);  // Provide a default error message
    } finally {
      setLoading(false);
    }
  };
  


  // Fetch initial data
  useEffect(() => {
    fetchPublicKey();
    fetchMessages();

    // Poll for new messages every 5 seconds
    const intervalId = setInterval(fetchMessages, 1000);

    return () => clearInterval(intervalId); // Cleanup on component unmount
  }, [friendUsername]);

  // Send message
  const sendMessage = async () => {
    if (!inputText.trim() || !friendPubKey) return;
  
    try {
      const authToken = localStorage.getItem('jwtToken');
      if (!authToken) {
        console.error('User is not authenticated');
        return;
      }
      // Prepare the JSON object for encryption
      const messageData = JSON.stringify({
        message: inputText,
        receiver: friendUsername,
        pubkey: friendPubKey,
      });
  
      // Encrypt the message using chacha20Encrypt
      const encryptedPayload = chacha20Encrypt(messageData);
      console.log("payload", JSON.parse(encryptedPayload))
      const decrypted = chacha20Decrypt(encryptedPayload)
      console.log("decrypted:", decrypted)
  
      // Send the encrypted message to the server
      const response = await fetch('http://localhost:4000/messages', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${authToken}`,
        },
        body: encryptedPayload, // Send the encrypted payload
      });
  
      if (!response.ok) throw new Error('Failed to send message');
  
      const newMessage = await response.json();
      setMessages((prevMessages) => [...prevMessages, newMessage]);
      setInputText('');
    } catch (err) {
      console.error('Error sending message:', err);
    }
  };
  


  return (
    <YStack flex={1} bg="$background" padding={10}>
      {/* Chat Header */}
      <Text fontSize={20} fontWeight="bold" mb={10}>
        Chat with {friendUsername}
      </Text>

      {/* Messages List */}
      <ScrollView flex={1} mb={10}>
        {loading ? (
          <Text>Loading...</Text>
        ) : (
          messages.map((msg) => (
            <MessageBubble
              key={msg.id}
              text={msg.content}
              sender={msg.senderUsername === friendUsername ? 'friend' : 'user'}
            />
          ))
        )}
      </ScrollView>

      {/* Input Field and Send Button */}
      <XStack space={10} alignItems="center">
        <Input
          flex={1}
          value={inputText}
          onChangeText={setInputText}
          placeholder="Type a message..."
          onSubmitEditing={sendMessage}
        />
        <Button size="large" onPress={sendMessage}>
          Send
        </Button>
      </XStack>
    </YStack>
  );
};

const MessageBubble = ({ text, sender }) => {
  const isUser = sender === 'user';
  return (
    <XStack
      justifyContent={isUser ? 'flex-end' : 'flex-start'}
      paddingVertical={5}
      paddingHorizontal={10}
    >
      <YStack
        maxWidth="70%"
        padding={10}
        borderRadius={10}
        backgroundColor={isUser ? '#007aff' : '#e5e5ea'}
      >
        <Text color={isUser ? '#fff' : '#000'}>{text}</Text>
      </YStack>
    </XStack>
  );
};

export default ChatApp;
