<template>
    <div class="chatContainer">
        <div class="chatContainer__card">
            <ChatHeader @toggle-chat="toggleChat" />
            <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" },
        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: "",
            mediaRecorder: null,
            chunks: [],
            isRecording: false,
            audioUrl: null,
        };
    },
    computed: {
        csrfToken() {
            const tokenMeta = document.querySelector('meta[name="csrf-token"]');
            return tokenMeta ? tokenMeta.getAttribute('content') : null;
        }
    },
    mounted() {
        // generate a random guest ID for the session
        let guestId = Date.now().toString(36) + Math.random().toString(36).substr(2);

        window.Echo.connector.options.auth.headers['X-Guest-ID'] = guestId;
        localStorage.setItem('guestId', 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;
            });
    },
    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 sendMessage(msg) {
            const userMessage = {
                text: msg,
                isUser: true,
                time: this.getCurrentTime(),
            };
            this.messages.push(userMessage);

            if (!msg) return;
            this.toggleThinking(true);
            this.isLoading = true;
            this.statusMessage = "Thinking...";
            this.statusType = "loading";

            const formData = new FormData();
            formData.append("message", msg);
            let guestId = localStorage.getItem('guestId');
            if (guestId) {
                formData.append("guestId", guestId);
            }

            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;
            }
        },

        startRecording() {
            console.log("Starting recording...");
            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                alert("Your browser does not support audio recording.");
                return;
            }

            navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
                this.mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
                this.mediaRecorder.start();
                this.isRecording = true;
                this.statusMessage = "Recording...";
                this.statusType = "loading";

                this.mediaRecorder.ondataavailable = (e) => {
                    this.chunks.push(e.data);
                };

                this.mediaRecorder.onstop = async () => {
                    const blob = new Blob(this.chunks, { type: "audio/webm" });
                    this.audioUrl = URL.createObjectURL(blob);
                    if(this.$refs.recordedAudio) {
                        this.$refs.recordedAudio.src = this.audioUrl;
                    }

                    const formData = new FormData();
                    const file = new File([blob], "user_audio.webm", { type: "audio/webm" });
                    formData.append("audio_file", file);

                    this.statusMessage = "Transcribing audio...";
                    this.statusType = "loading";

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

                        if (!response.ok) throw new Error("Transcription failed");
                        const data = await response.json();

                        if (data.text) {
                            this.message = data.text;
                            this.statusMessage = "Audio transcribed successfully.";
                            this.statusType = "success";
                        }

                    } catch (error) {
                        this.statusMessage = "Error processing audio";
                        this.statusType = "error";
                    } finally {
                        this.chunks = [];
                        this.isRecording = false;
                    }
                };
            }).catch(err => {
                this.statusMessage = "Microphone access denied";
                this.statusType = "error";
            });
        },

        stopRecording() {
            if (this.mediaRecorder && this.isRecording) {
                this.mediaRecorder.stop();
                this.isRecording = false;
            }
        }
    }
};
</script>

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