import QtQuick
import ZShell.Llm
import ZShell.Config
import qs.Components
import qs.Services
import qs.Modules.Notifications.Sidebar.Chat

Item {
    id: root

    property int animOff
    property Item currentItem
    property bool noAnim: false
    property bool loading: false
    property int lastIdx: -1

    readonly property Component conversationComp: ChatContent {}

    signal requestClose

    function loadConversation(chat): void {
        if (currentItem) {
            currentItem.destroy();
            currentItem = null;
        }

        if (!chat)
            return;

        root.loading = true;

        const incubator = root.conversationComp.incubateObject(container, {
            chatData: chat
        });

        const attach = () => {
            incubator.object.anchors.fill = container;
            incubator.object.requestClose.connect(root.requestClose);
            currentItem = incubator.object;
            root.loading = false;
            if (!noAnim)
                enterAnim.start();
        };

        if (incubator.status === Component.Ready)
            attach();
        else
            incubator.onStatusChanged = status => {
                if (status === Component.Ready)
                    attach();
            };
    }

    Item {
        id: container

        anchors.fill: parent
        layer.enabled: opacity < 1
        objectName: "ConversationContainer"

        Component.onCompleted: {
            if (ChatState.chatSession)
                root.loadConversation(ChatState.chatSession);
        }
    }

    LoadingIndicator {
        anchors.centerIn: parent
        implicitSize: Tokens.font.size.extraLarge * 4
        opacity: root.loading ? 1 : 0
        visible: opacity > 0

        Behavior on opacity {
            Anim {}
        }
    }

    Connections {
        function onChatSessionChanged(): void {
            exitAnim.complete();
            enterAnim.complete();

            if (root.noAnim) {
                root.loadConversation(ChatState.chatSession);
                return;
            }

            root.animOff = Tokens.padding.small * (ChatState.currentIdx > root.lastIdx ? 1 : -1);
            root.lastIdx = ChatState.currentIdx;
            exitAnim.start();
        }

        target: ChatState
    }

    SequentialAnimation {
        id: exitAnim

        Anim {
            property: "opacity"
            target: container
            to: 0
            type: Anim.DefaultEffects
        }

        ScriptAction {
            script: root.loadConversation(ChatState.chatSession)
        }
    }

    SequentialAnimation {
        id: enterAnim

        PropertyAction {
            property: "topMargin"
            target: container.anchors
            value: root.animOff
        }

        PropertyAction {
            property: "bottomMargin"
            target: container.anchors
            value: -root.animOff
        }

        ParallelAnimation {
            Anim {
                from: 0
                property: "opacity"
                target: container
                to: 1
                type: Anim.SlowEffects
            }

            Anim {
                properties: "topMargin,bottomMargin"
                target: container.anchors
                to: 0
                type: Anim.SlowEffects
            }
        }
    }
}
