import tkinter as tk
from tkinter import scrolledtext
import tkinter.simpledialog
import socket
import threading

class P2PMessenger:
    def __init__(self, root):
        self.root = root
        self.root.title("P2P")

        self.chat_window = scrolledtext.ScrolledText(root, state='disabled', wrap='word', height=20, width=50)
        self.chat_window.grid(row=0, column=0, columnspan=2, padx=10, pady=10)

        self.msg_entry = tk.Entry(root, width=40)
        self.msg_entry.grid(row=1, column=0, padx=10, pady=5)
        self.msg_entry.bind("<Return>", lambda event: self.send_message())
        
        self.send_button = tk.Button(root, text="Send", command=self.send_message)
        self.send_button.grid(row=1, column=1, padx=10, pady=5)

        self.start_button = tk.Button(root, text="Start", command=self.start_messenger)
        self.start_button.grid(row=2, column=0, columnspan=2, pady=10)

        self.socket = None
        self.local_port = 0
        self.peer_ip = ""
        self.peer_port = 0
        self.running = False

    def start_messenger(self):
        # Get user input for local port and peer address
        self.local_port = int(tk.simpledialog.askstring("Local Port", "Enter your local port:"))
        peer_address = tk.simpledialog.askstring("Peer Address", "Enter peer's IP:Port (e.g., 127.0.0.1:12345):")

        self.peer_ip, self.peer_port = peer_address.split(":")
        self.peer_port = int(self.peer_port)

        # Initialize socket
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.bind(("0.0.0.0", self.local_port))

        self.running = True
        self.thread_receiver = threading.Thread(target=self.receive_messages)
        self.thread_receiver.daemon = True
        self.thread_receiver.start()

        self.chat_window.config(state='normal')
        self.chat_window.insert(tk.END, "Messenger started on port " + str(self.local_port) + "\n")
        self.chat_window.insert(tk.END, "Connected to peer at " + str(self.peer_ip) + ":" + str(self.peer_port) + "\n")
        self.chat_window.config(state='disabled')

    def send_message(self):
        message = self.msg_entry.get()
        if message:
            if self.socket:
                self.socket.sendto(message.encode('utf-8'), (self.peer_ip, self.peer_port))
                self.chat_window.config(state='normal')
                self.chat_window.insert(tk.END, "You: " + str(message) + "\n")
                self.chat_window.config(state='disabled')
                self.msg_entry.delete(0, tk.END)
            else:
                self.chat_window.config(state='normal')
                self.chat_window.insert(tk.END, "You aren't connected to the peer!\n")
                self.chat_window.config(state='disabled')
                self.msg_entry.delete(0, tk.END)

    def receive_messages(self):
        while self.running:
            try:
                data, addr = self.socket.recvfrom(1024)
                message = data.decode('utf-8')
                self.chat_window.config(state='normal')
                self.chat_window.insert(tk.END, "Peer: " + str(message) + "\n")
                self.chat_window.config(state='disabled')
            except Exception as e:
                print("Error receiving message: " + str(e))

    def on_close(self):
        self.running = False
        if self.socket:
            self.socket.close()
        self.root.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    app = P2PMessenger(root)
    root.protocol("WM_DELETE_WINDOW", app.on_close)
    root.mainloop()

