import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts
import QtQuick.Dialogs
import Qt.labs.folderlistmodel
import Qt5Compat.GraphicalEffects
import llm
import chatlistmodel
import download
import modellist
import network
import gpt4all
import mysettings
import localdocs
ColumnLayout {
    Layout.fillWidth: true
    Layout.alignment: Qt.AlignTop
    spacing: 5
    Label {
        Layout.topMargin: 0
        Layout.bottomMargin: 25
        Layout.rightMargin: 150 * theme.fontScale
        Layout.alignment: Qt.AlignTop
        Layout.fillWidth: true
        verticalAlignment: Text.AlignTop
        text: qsTr("These models have been specifically configured for use in GPT4All. The first few models on the " +
                   "list are known to work the best, but you should only attempt to use models that will fit in your " +
                   "available memory.")
        font.pixelSize: theme.fontSizeLarger
        color: theme.textColor
        wrapMode: Text.WordWrap
    }
    Label {
        visible: !ModelList.gpt4AllDownloadableModels.count && !ModelList.asyncModelRequestOngoing
        Layout.fillWidth: true
        Layout.fillHeight: true
        horizontalAlignment: Qt.AlignHCenter
        verticalAlignment: Qt.AlignVCenter
        text: qsTr("Network error: could not retrieve %1").arg("http://gpt4all.io/models/models3.json")
        font.pixelSize: theme.fontSizeLarge
        color: theme.mutedTextColor
    }
    MyBusyIndicator {
        visible: !ModelList.gpt4AllDownloadableModels.count && ModelList.asyncModelRequestOngoing
        running: ModelList.asyncModelRequestOngoing
        Accessible.role: Accessible.Animation
        Layout.alignment: Qt.AlignCenter
        Accessible.name: qsTr("Busy indicator")
        Accessible.description: qsTr("Displayed when the models request is ongoing")
    }
    RowLayout {
        ButtonGroup {
            id: buttonGroup
            exclusive: true
        }
        MyButton {
            text: qsTr("All")
            checked: true
            borderWidth: 0
            backgroundColor: checked ? theme.lightButtonBackground : "transparent"
            backgroundColorHovered: theme.lighterButtonBackgroundHovered
            backgroundRadius: 5
            padding: 15
            topPadding: 8
            bottomPadding: 8
            textColor: theme.lighterButtonForeground
            fontPixelSize: theme.fontSizeLarge
            fontPixelBold: true
            checkable: true
            ButtonGroup.group: buttonGroup
            onClicked: {
                ModelList.gpt4AllDownloadableModels.filter("");
            }
        }
        MyButton {
            text: qsTr("Reasoning")
            borderWidth: 0
            backgroundColor: checked ? theme.lightButtonBackground : "transparent"
            backgroundColorHovered: theme.lighterButtonBackgroundHovered
            backgroundRadius: 5
            padding: 15
            topPadding: 8
            bottomPadding: 8
            textColor: theme.lighterButtonForeground
            fontPixelSize: theme.fontSizeLarge
            fontPixelBold: true
            checkable: true
            ButtonGroup.group: buttonGroup
            onClicked: {
                ModelList.gpt4AllDownloadableModels.filter("#reasoning");
            }
        }
        Layout.bottomMargin: 10
    }
    ScrollView {
        id: scrollView
        ScrollBar.vertical.policy: ScrollBar.AsNeeded
        Layout.fillWidth: true
        Layout.fillHeight: true
        clip: true
        ListView {
            id: modelListView
            model: ModelList.gpt4AllDownloadableModels
            boundsBehavior: Flickable.StopAtBounds
            spacing: 30
            delegate: Rectangle {
                id: delegateItem
                width: modelListView.width
                height: childrenRect.height + 60
                color: theme.conversationBackground
                radius: 10
                border.width: 1
                border.color: theme.controlBorder
                ColumnLayout {
                    anchors.top: parent.top
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.margins: 30
                    Text {
                        Layout.fillWidth: true
                        Layout.alignment: Qt.AlignLeft
                        text: name
                        elide: Text.ElideRight
                        color: theme.titleTextColor
                        font.pixelSize: theme.fontSizeLargest
                        font.bold: true
                        Accessible.role: Accessible.Paragraph
                        Accessible.name: qsTr("Model file")
                        Accessible.description: qsTr("Model file to be downloaded")
                    }
                    Rectangle {
                        Layout.fillWidth: true
                        height: 1
                        color: theme.dividerColor
                    }
                    RowLayout {
                        Layout.topMargin: 10
                        Layout.fillWidth: true
                        Text {
                            id: descriptionText
                            text: description
                            font.pixelSize: theme.fontSizeLarge
                            Layout.fillWidth: true
                            wrapMode: Text.WordWrap
                            textFormat: Text.StyledText
                            color: theme.textColor
                            linkColor: theme.textColor
                            Accessible.role: Accessible.Paragraph
                            Accessible.name: qsTr("Description")
                            Accessible.description: qsTr("File description")
                            onLinkActivated: function(link) { Qt.openUrlExternally(link); }
                            MouseArea {
                                anchors.fill: parent
                                acceptedButtons: Qt.NoButton // pass clicks to parent
                                cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
                            }
                        }
                        // FIXME Need to overhaul design here which must take into account
                        // features not present in current figma including:
                        // * Ability to cancel a current download
                        // * Ability to resume a download
                        // * The presentation of an error if encountered
                        // * Whether to show already installed models
                        // * Install of remote models with API keys
                        // * The presentation of the progress bar
                        Rectangle {
                            id: actionBox
                            width: childrenRect.width + 20
                            color: "transparent"
                            border.width: 1
                            border.color: theme.dividerColor
                            radius: 10
                            Layout.rightMargin: 20
                            Layout.bottomMargin: 20
                            Layout.minimumHeight: childrenRect.height + 20
                            Layout.alignment: Qt.AlignRight | Qt.AlignTop
                            ColumnLayout {
                                spacing: 0
                                MySettingsButton {
                                    id: downloadButton
                                    text: isDownloading ? qsTr("Cancel") : isIncomplete ? qsTr("Resume") : qsTr("Download")
                                    font.pixelSize: theme.fontSizeLarge
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.fillWidth: true
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    visible: !isOnline && !installed && !calcHash && downloadError === ""
                                    Accessible.description: qsTr("Stop/restart/start the download")
                                    onClicked: {
                                        if (!isDownloading) {
                                            Download.downloadModel(filename);
                                        } else {
                                            Download.cancelDownload(filename);
                                        }
                                    }
                                }
                                MySettingsDestructiveButton {
                                    id: removeButton
                                    text: qsTr("Remove")
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.fillWidth: true
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    visible: !isDownloading && (installed || isIncomplete)
                                    Accessible.description: qsTr("Remove model from filesystem")
                                    onClicked: {
                                        Download.removeModel(filename);
                                    }
                                }
                                MySettingsButton {
                                    id: installButton
                                    visible: !installed && isOnline
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.fillWidth: true
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    text: qsTr("Install")
                                    font.pixelSize: theme.fontSizeLarge
                                    onClicked: {
                                        var apiKeyText = apiKey.text.trim(),
                                        baseUrlText = baseUrl.text.trim(),
                                        modelNameText = modelName.text.trim();
                                        var apiKeyOk = apiKeyText !== "",
                                        baseUrlOk = !isCompatibleApi || baseUrlText !== "",
                                        modelNameOk = !isCompatibleApi || modelNameText !== "";
                                        if (!apiKeyOk)
                                            apiKey.showError();
                                        if (!baseUrlOk)
                                            baseUrl.showError();
                                        if (!modelNameOk)
                                            modelName.showError();
                                        if (!apiKeyOk || !baseUrlOk || !modelNameOk)
                                            return;
                                        if (!isCompatibleApi)
                                            Download.installModel(
                                                        filename,
                                                        apiKeyText,
                                                        );
                                        else
                                            Download.installCompatibleModel(
                                                        modelNameText,
                                                        apiKeyText,
                                                        baseUrlText,
                                                        );
                                    }
                                    Accessible.role: Accessible.Button
                                    Accessible.name: qsTr("Install")
                                    Accessible.description: qsTr("Install online model")
                                }
                                ColumnLayout {
                                    spacing: 0
                                    Label {
                                        Layout.topMargin: 20
                                        Layout.leftMargin: 20
                                        visible: downloadError !== ""
                                        textFormat: Text.StyledText
                                        text: qsTr("Error")
                                        color: theme.textColor
                                        font.pixelSize: theme.fontSizeLarge
                                        linkColor: theme.textErrorColor
                                        Accessible.role: Accessible.Paragraph
                                        Accessible.name: text
                                        Accessible.description: qsTr("Describes an error that occurred when downloading")
                                        onLinkActivated: {
                                            downloadingErrorPopup.text = downloadError;
                                            downloadingErrorPopup.open();
                                        }
                                    }
                                    Label {
                                        visible: LLM.systemTotalRAMInGB() < ramrequired
                                        Layout.topMargin: 20
                                        Layout.leftMargin: 20
                                        Layout.maximumWidth: 300
                                        textFormat: Text.StyledText
                                        text: qsTr("WARNING: Not recommended for your hardware. Model requires more memory (%1 GB) than your system has available (%2).").arg(ramrequired).arg(LLM.systemTotalRAMInGBString())
                                        color: theme.textErrorColor
                                        font.pixelSize: theme.fontSizeLarge
                                        wrapMode: Text.WordWrap
                                        Accessible.role: Accessible.Paragraph
                                        Accessible.name: text
                                        Accessible.description: qsTr("Error for incompatible hardware")
                                        onLinkActivated: {
                                            downloadingErrorPopup.text = downloadError;
                                            downloadingErrorPopup.open();
                                        }
                                    }
                                }
                                ColumnLayout {
                                    visible: isDownloading && !calcHash
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.fillWidth: true
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    spacing: 20
                                    ProgressBar {
                                        id: itemProgressBar
                                        Layout.fillWidth: true
                                        width: 200
                                        value: bytesReceived / bytesTotal
                                        background: Rectangle {
                                            implicitHeight: 45
                                            color: theme.progressBackground
                                            radius: 3
                                        }
                                        contentItem: Item {
                                            implicitHeight: 40
                                            Rectangle {
                                                width: itemProgressBar.visualPosition * parent.width
                                                height: parent.height
                                                radius: 2
                                                color: theme.progressForeground
                                            }
                                        }
                                        Accessible.role: Accessible.ProgressBar
                                        Accessible.name: qsTr("Download progressBar")
                                        Accessible.description: qsTr("Shows the progress made in the download")
                                    }
                                    Label {
                                        id: speedLabel
                                        color: theme.textColor
                                        Layout.alignment: Qt.AlignRight
                                        text: speed
                                        font.pixelSize: theme.fontSizeLarge
                                        Accessible.role: Accessible.Paragraph
                                        Accessible.name: qsTr("Download speed")
                                        Accessible.description: qsTr("Download speed in bytes/kilobytes/megabytes per second")
                                    }
                                }
                                RowLayout {
                                    visible: calcHash
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.maximumWidth: 200
                                    Layout.fillWidth: true
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    clip: true
                                    Label {
                                        id: calcHashLabel
                                        color: theme.textColor
                                        text: qsTr("Calculating...")
                                        font.pixelSize: theme.fontSizeLarge
                                        Accessible.role: Accessible.Paragraph
                                        Accessible.name: text
                                        Accessible.description: qsTr("Whether the file hash is being calculated")
                                    }
                                    MyBusyIndicator {
                                        id: busyCalcHash
                                        running: calcHash
                                        Accessible.role: Accessible.Animation
                                        Accessible.name: qsTr("Busy indicator")
                                        Accessible.description: qsTr("Displayed when the file hash is being calculated")
                                    }
                                }
                                MyTextField {
                                    id: apiKey
                                    visible: !installed && isOnline
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    wrapMode: Text.WrapAnywhere
                                    function showError() {
                                        messageToast.show(qsTr("ERROR: $API_KEY is empty."));
                                        apiKey.placeholderTextColor = theme.textErrorColor;
                                    }
                                    onTextChanged: {
                                        apiKey.placeholderTextColor = theme.mutedTextColor;
                                    }
                                    placeholderText: qsTr("enter $API_KEY")
                                    Accessible.role: Accessible.EditableText
                                    Accessible.name: placeholderText
                                    Accessible.description: qsTr("Whether the file hash is being calculated")
                                }
                                MyTextField {
                                    id: baseUrl
                                    visible: !installed && isOnline && isCompatibleApi
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    wrapMode: Text.WrapAnywhere
                                    function showError() {
                                        messageToast.show(qsTr("ERROR: $BASE_URL is empty."));
                                        baseUrl.placeholderTextColor = theme.textErrorColor;
                                    }
                                    onTextChanged: {
                                        baseUrl.placeholderTextColor = theme.mutedTextColor;
                                    }
                                    placeholderText: qsTr("enter $BASE_URL")
                                    Accessible.role: Accessible.EditableText
                                    Accessible.name: placeholderText
                                    Accessible.description: qsTr("Whether the file hash is being calculated")
                                }
                                MyTextField {
                                    id: modelName
                                    visible: !installed && isOnline && isCompatibleApi
                                    Layout.topMargin: 20
                                    Layout.leftMargin: 20
                                    Layout.minimumWidth: 200
                                    Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
                                    wrapMode: Text.WrapAnywhere
                                    function showError() {
                                        messageToast.show(qsTr("ERROR: $MODEL_NAME is empty."))
                                        modelName.placeholderTextColor = theme.textErrorColor;
                                    }
                                    onTextChanged: {
                                        modelName.placeholderTextColor = theme.mutedTextColor;
                                    }
                                    placeholderText: qsTr("enter $MODEL_NAME")
                                    Accessible.role: Accessible.EditableText
                                    Accessible.name: placeholderText
                                    Accessible.description: qsTr("Whether the file hash is being calculated")
                                }
                            }
                        }
                    }
                    Item  {
                        Layout.minimumWidth: childrenRect.width
                        Layout.minimumHeight: childrenRect.height
                        Layout.bottomMargin: 10
                        RowLayout {
                            id: paramRow
                            anchors.centerIn: parent
                            ColumnLayout {
                                Layout.topMargin: 10
                                Layout.bottomMargin: 10
                                Layout.leftMargin: 20
                                Layout.rightMargin: 20
                                Text {
                                    text: qsTr("File size")
                                    font.pixelSize: theme.fontSizeSmall
                                    color: theme.mutedDarkTextColor
                                }
                                Text {
                                    text: filesize
                                    color: theme.textColor
                                    font.pixelSize: theme.fontSizeSmall
                                    font.bold: true
                                }
                            }
                            Rectangle {
                                width: 1
                                Layout.fillHeight: true
                                color: theme.dividerColor
                            }
                            ColumnLayout {
                                Layout.topMargin: 10
                                Layout.bottomMargin: 10
                                Layout.leftMargin: 20
                                Layout.rightMargin: 20
                                Text {
                                    text: qsTr("RAM required")
                                    font.pixelSize: theme.fontSizeSmall
                                    color: theme.mutedDarkTextColor
                                }
                                Text {
                                    text: ramrequired >= 0 ? qsTr("%1 GB").arg(ramrequired) : qsTr("?")
                                    color: theme.textColor
                                    font.pixelSize: theme.fontSizeSmall
                                    font.bold: true
                                }
                            }
                            Rectangle {
                                width: 1
                                Layout.fillHeight: true
                                color: theme.dividerColor
                            }
                            ColumnLayout {
                                Layout.topMargin: 10
                                Layout.bottomMargin: 10
                                Layout.leftMargin: 20
                                Layout.rightMargin: 20
                                Text {
                                    text: qsTr("Parameters")
                                    font.pixelSize: theme.fontSizeSmall
                                    color: theme.mutedDarkTextColor
                                }
                                Text {
                                    text: parameters !== "" ? parameters : qsTr("?")
                                    color: theme.textColor
                                    font.pixelSize: theme.fontSizeSmall
                                    font.bold: true
                                }
                            }
                            Rectangle {
                                width: 1
                                Layout.fillHeight: true
                                color: theme.dividerColor
                            }
                            ColumnLayout {
                                Layout.topMargin: 10
                                Layout.bottomMargin: 10
                                Layout.leftMargin: 20
                                Layout.rightMargin: 20
                                Text {
                                    text: qsTr("Quant")
                                    font.pixelSize: theme.fontSizeSmall
                                    color: theme.mutedDarkTextColor
                                }
                                Text {
                                    text: quant
                                    color: theme.textColor
                                    font.pixelSize: theme.fontSizeSmall
                                    font.bold: true
                                }
                            }
                            Rectangle {
                                width: 1
                                Layout.fillHeight: true
                                color: theme.dividerColor
                            }
                            ColumnLayout {
                                Layout.topMargin: 10
                                Layout.bottomMargin: 10
                                Layout.leftMargin: 20
                                Layout.rightMargin: 20
                                Text {
                                    text: qsTr("Type")
                                    font.pixelSize: theme.fontSizeSmall
                                    color: theme.mutedDarkTextColor
                                }
                                Text {
                                    text: type
                                    color: theme.textColor
                                    font.pixelSize: theme.fontSizeSmall
                                    font.bold: true
                                }
                            }
                        }
                        Rectangle {
                            color: "transparent"
                            anchors.fill: paramRow
                            border.color: theme.dividerColor
                            border.width: 1
                            radius: 10
                        }
                    }
                    Rectangle {
                        Layout.fillWidth: true
                        height: 1
                        color: theme.dividerColor
                    }
                }
            }
        }
    }
}