<template>
    <div class="chatContainer">
        <div class="chatContainer__card">
            <ChatHeader @toggle-chat="toggleChat" @new-chat="startNewChat" />
            <ChatBody :messages="messages" :thinking="thinking"/>
            <ChatFooter @send-message="sendMessage"/>
        </div>
    </div>
</template>

<script>

import ChatHeader from "./chat/structure/header.vue";
import ChatFooter from "./chat/structure/footer.vue";
import ChatBody from "./chat/structure/body.vue";

export default {
    name: "AgentChat",
    components: {ChatBody, ChatFooter, ChatHeader},
    props: {
        sendUrl: { type: String, default: "/agent/chat" },
        voiceUrl: { type: String, default: "/agent/voice" },
        sessionUrl: { type: String, default: "/agent/session" },
        sessionResetUrl: { type: String, default: "/agent/session/reset" },
        toggleChat: { type: Function, default: null },
    },
    data() {
        return {
            messages: [{
                text: "Hi, how can I assist you today?",
                isUser: false,
                time: this.getCurrentTime(),
            }],
            thinking: false,
            isLoading: false,
            statusMessage: "",
            statusType: "",
            currentGuestId: null,
        };
    },
    computed: {
        csrfToken() {
            const tokenMeta = document.querySelector('meta[name="csrf-token"]');
            return tokenMeta ? tokenMeta.getAttribute('content') : null;
        }
    },
    mounted() {
        if (window.initEcho) {
            window.initEcho();
        }
        this.subscribeToChannel();
    },
    methods: {
        getCurrentTime() {
            const now = new Date();
            const hours = now.getHours().toString().padStart(2, '0');
            const minutes = now.getMinutes().toString().padStart(2, '0');
            return `${hours}:${minutes}`;
        },
        toggleThinking(isThinking) {
            this.thinking = isThinking;
        },
        async fetchGuestId(url, method) {
            const headers = { "Accept": "application/json" };
            if (method !== 'GET' && this.csrfToken) {
                headers["X-CSRF-TOKEN"] = this.csrfToken;
            }
            const res = await fetch(url, {
                method,
                headers,
                credentials: "same-origin",
            });
            if (!res.ok) {
                throw new Error("Failed to initialise chat session");
            }
            const data = await res.json();
            if (!data || !data.guestId) {
                throw new Error("Chat session response missing guestId");
            }
            return data.guestId;
        },
        async subscribeToChannel(url = this.sessionUrl, method = 'GET') {
            try {
                const guestId = await this.fetchGuestId(url, method);
                this.currentGuestId = guestId;

                window.Echo.private('agent-channel.' + guestId)
                    .listen('.new.process', (data) => {
                        if (data.status === 'thinking') {
                            this.toggleThinking(true);
                        }
                    })
                    .listen('.new.notification', (data) => {
                        this.toggleThinking(false);
                        this.messages.push({
                            text: data.message,
                            isUser: false,
                            time: this.getCurrentTime(),
                            productName: data.productName,
                            productData: data.item,
                        });
                        this.isLoading = false;
                    });
            } catch (err) {
                this.statusMessage = "Error: " + (err.message || "Could not start chat");
                this.statusType = "error";
            }
        },
        startNewChat() {
            if (this.currentGuestId) {
                window.Echo.leave('agent-channel.' + this.currentGuestId);
                this.currentGuestId = null;
            }

            this.messages = [{
                text: "Hi, how can I assist you today?",
                isUser: false,
                time: this.getCurrentTime(),
            }];
            this.thinking = false;
            this.isLoading = false;
            this.statusMessage = "";
            this.statusType = "";

            this.subscribeToChannel(this.sessionResetUrl, 'POST');
        },
        async sendMessage(msg) {
            if (!msg) return;

            const userMessage = {
                text: msg,
                isUser: true,
                time: this.getCurrentTime(),
            };
            this.messages.push(userMessage);
            this.toggleThinking(true);
            this.isLoading = true;
            this.statusMessage = "Thinking...";
            this.statusType = "loading";

            const formData = new FormData();
            formData.append("message", msg);

            try {
                const res = await fetch(this.sendUrl, {
                    method: "POST",
                    headers: {
                        "Accept": "application/json",
                        ...(this.csrfToken ? { "X-CSRF-TOKEN": this.csrfToken } : {})
                    },
                    body: formData,
                    credentials: "same-origin"
                });

                if (!res.ok) {
                    let errText = res.statusText;
                    try {
                        const errJson = await res.json();
                        errText = errJson.message || JSON.stringify(errJson);
                    } catch (e) {
                    }
                    throw new Error(errText);
                }

                const data = await res.json();
                if (data.status !== 'message sent') {
                    throw new Error("Failed to send message.");
                }
                // Now we wait for the Echo listener to receive the response.
                this.statusMessage = "Message sent, waiting for response...";

            } catch (err) {
                this.statusMessage = "Error: " + (err.message || "Request failed");
                this.statusType = "error";
                this.isLoading = false;
            }
        },

    }
};
</script>

<style lang="less">
@import "../styles/chat.less";
</style>
