import { useParams, Link, useNavigate } from "react-router-dom";
import React, { useEffect, useState } from "react";
import { Channel, Messages, User } from "../types";
import TopBar from "../components/TopBar";
import MessageComponent from "../components/MessageComponent";
import axios from "axios";

import "../styles/ChannelPage.css";

export default function ChannelPage({socket}: {socket: WebSocket}) {
    const navigate = useNavigate();
    const { name } = useParams();
    const [channel, setChannel] = useState<Channel>();
    const [messages, setMessages] = useState<Messages>();
    const [token, setToken] = useState<string>("");
    const [user, setUser] = useState<User>();
    const [message, setMessage] = useState<string>("");
    const [maxMessageToShown, setMaxMessageToShown] = useState<number>(10);
    const [searchedUsers, setSearchedUsers] = useState<User[]>([]);
    const ref = React.createRef<HTMLInputElement>();

    function handleSubmit(e: React.FormEvent) {
        e.preventDefault();
        axios
            .post(`/api/channels/${name}/messages/send`, { token, message})
            .then(() => {
                setMessage("");
                setSearchedUsers([]);
            })
            .catch((err) => {
                console.error(err.response);
            });
    }

    function deleteMessage(message_id: number) {
        axios
            .post(`/api/channels/${name}/messages/delete`, { token, message_id })
            .catch((err) => {
                console.error(err.response);
            });
    }

    function purgeChannel() {
        axios
            .post(`/api/channels/${name}/purge`, { token })
            .catch((err) => {
                console.error(err.response);
            }
        );
    }

    function deleteChannel() {
        axios
            .post(`/api/channels/${name}/delete`, { token })
            .then(() => {
                navigate("/");
            })
            .catch((err) => {
                console.error(err.response);
            });
    }

    useEffect(() => {
        const localToken = localStorage.getItem("token");
        if (localToken) {
            setToken(localToken);
            axios.post("/api/auth/me", { token: localToken }).then((res) => {
                    setUser(res.data);
                }
            );
        }
        axios.get(`/api/channels/${name}`).then((res) => {
            setChannel(res.data);
        });

        axios.get(`/api/channels/${name}/messages`).then((res) => {
            setMessages(res.data);
        });
    }, [name]);

    useEffect(() => {          
        socket.addEventListener('message', function (event) {
            const data = JSON.parse(event.data);
            if ((data.type === "new_message" || data.type === "delete_message" || data.type === "purge_channel") && data.channel_id === channel?.id) {
                axios
                    .get(`/api/channels/${name}/messages`).then((res) => {
                        setMessages(res.data)
                    })
            }
            if (data.type === "delete_channel" && data.channel_id === channel?.id) {
                navigate("/");
            }
        });
    }, [channel])

    useEffect(() => {
        const words = message.toString().split(" ");
        const lastWord = words[words.length - 1];
    
        if (lastWord && lastWord.startsWith("@")) {
            const username = lastWord.slice(1);
            axios
                .get(`/api/searchuser?search=${username}`)
                .then((res) => {
                    setSearchedUsers(res.data);
                })
                .catch((err) => {
                    console.error(err.response);
                });
        } else {
            setSearchedUsers([]);
        }
    }, [message]);
    

    if (!channel || !messages) {
        return (
            <div className="channel-page">
                <TopBar user={user} />
                <div className="channel">
                    <p>Loading...</p>
                </div>
            </div>
        )
    }

    return (
        <div className="channel-page">
            <TopBar user={user} />
            <div className="channel">
                <h2>Channel {channel.name}</h2>
                <p>{channel.description}</p>
                <p>Owner: <Link to={`/u/${channel.owner_username}`}>{channel.owner_username}</Link></p>
                {channel.name.toLowerCase().includes("cat") && (
                    <img src="/cat.jpg" alt="cat" className="cat" />
                )}
                {user?.admin == 1 && (
                    <button onClick={purgeChannel}>
                        Purge Channel
                    </button>
                )}
                {user?.admin == 1 && (
                    <button onClick={deleteChannel}>
                        Delete Channel
                    </button>
                )}
                {token ? (
                    <form onSubmit={handleSubmit} className="message-form">
                        <input 
                            type="text"
                            placeholder="Message"
                            value={message}
                            onChange={(e) => setMessage(e.target.value)}
                            ref={ref}
                        />
                        <button type="submit">Send</button>
                        {searchedUsers.length > 0 && (
                            <div className="mentions">
                                {searchedUsers.map((user) => (
                                    <div key={user.id} className="mention">
                                        <Link to={`/u/${user.username}`}>{user.username}</Link>
                                        <button
                                            type="button"
                                            onClick={() => {
                                                setMessage(
                                                    message.split(" ").slice(0, -1).join(" ") + " @" + user.username + " "
                                                );
                                                setSearchedUsers([]);
                                                ref.current?.focus();
                                            }}
                                        >
                                            Mention
                                        </button>
                                    </div>
                                ))}
                            </div>
                        )}
                    </form>
                ) : (
                    <div className="login-prompt">
                        <Link to="/login">Login</Link>
                        <Link to="/register">Register</Link>
                    </div>
                )}
                <div className="messages-list">
                    {messages.slice(0, maxMessageToShown).map((message) => (
                        <MessageComponent
                            key={message.id}
                            message={message}
                            user={user}
                            channel={channel}
                            deleteMessage={deleteMessage}
                        />
                    ))}
                    {messages.length > maxMessageToShown && (
                        <button onClick={() => setMaxMessageToShown(maxMessageToShown + 10)}>Show more</button>
                    )}
                </div>
            </div>
        </div>
    );
}