/*!
 *
 * Copyright (c) 2022-2023 Diality Inc. - All Rights Reserved.
 * \copyright
 * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN
 * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER.
 *
 * \file    SettingsExportLogs.qml
 * \author  (last)      Vy
 * \date    (last)      01-Jun-2023
 * \author  (original)  Behrouz NematiPour
 * \date    (original)  27-Jun-2022
 *
 */

// Qt
import QtQuick                  2.12
import QtQuick.Controls         2.12
import Qt.labs.folderlistmodel  2.12


// TODO: Add the fileCopy function to have control over the copy
// TODO: Add cancel
// TODO: Add Service and Treatment log export and exit

// TODO: Add selecction export
// TODO: Add error display

// Project
import Gui.Actions 0.1

//  Qml imports
import "qrc:/"
import "qrc:/globals"
import "qrc:/components"

/*!
 * \brief   SettingsExportLogs is used to Export logs, and display the SD-Card and USB device informaiton and list of files.
 */
SettingsBase                                                { id: _root

    ////////////////////////////////////////////////////////////////////////////////
    // FIXME: The model being used here is the QML FileListModel.                 //
    //        This model is so limited and do not update well.                    //
    //        This model definitely has to be replaced with a C++ one,            //
    //        like the other MVC classes we have.                                 //
    ////////////////////////////////////////////////////////////////////////////////

    readonly property string sdcLabel                       : qsTr("SD-Card")
    readonly property string devUnit                        : "MB" // no translation
    readonly property string devUnitLabel                   : " (" + devUnit + ")\n" // no translation
    readonly property string usbLabel                       : qsTr("USB Drive")
    readonly property int    headetRowHight                 : 50

    readonly property int    typeIndexApplication           : 0
    readonly property int    typeIndexService               : 1
    readonly property int    typeIndexTreatment             : 2

    readonly property string typeLabelApplication           : qsTr("Application"                  )
    readonly property string typeLabelService               : qsTr("Service"                      )
    readonly property string typeLabelTreatment             : qsTr("Treatment"                    )

             property bool   isDevice                       : true //false // it has to be true to make it work on the devices.
    readonly property string typePathClr                    : ""
    readonly property string typePathPrefix                 : "file://"
    readonly property string typePathSrc                    : typePathPrefix + (isDevice ? "/media/sd-card" : "/home/denali/Desktop/sd-card" )
    readonly property string typePathDst                    : typePathPrefix + (isDevice ? "/media/usb"     : "/home/denali/Desktop/usb-disk")
    readonly property string typeFolderApplication          : "/log"
    readonly property string typeFolderService              : "/service"
    readonly property string typeFolderTreatment            : "/treatment"

    readonly property string typeFolderApplicationSrc       : typePathSrc + typeFolderApplication
    readonly property string typeFolderApplicationDst       : typePathDst + typeFolderApplication
    readonly property string typeFolderServiceSrc           : typePathSrc + typeFolderService
    readonly property string typeFolderServiceDst           : typePathDst + typeFolderService
    readonly property string typeFolderTreatmentSrc         : typePathSrc + typeFolderTreatment
    readonly property string typeFolderTreatmentDst         : typePathDst + typeFolderTreatment

    readonly property var    typeFilterAll                  : ["*"]
    readonly property var    typeFilterClr                  : []


    itemIndex                                               : SettingsStack.ExportLogs
    confirmVisible                                          : false

    function refreshModels() {
        _usbFolderColumn.clearModel()
        _usbFolderColumn.updateModel()
    }

    function doExport() {
        refreshModels()

        switch (_logTypeCombo.currentIndex) {
        case typeIndexApplication:
            _GuiView.doExportLog()
            break
        case typeIndexService:
            _GuiView.doExportService()
            break
        case typeIndexTreatment:
            _GuiView.doExportTreatment()
            break
        }

        refreshModels()
    }

    property bool isUpdatePanels: false
    function updatePanels (vIndex) {
        isUpdatePanels = true

        _GuiView.doExportListRemove()
        _sdcFolderColumn.clearModel()
        _usbFolderColumn.clearModel()

        switch (vIndex) {
        case typeIndexApplication:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderApplicationSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderApplicationDst
            break
        case typeIndexService:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderServiceSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderServiceDst
            break
        case typeIndexTreatment:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderTreatmentSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderTreatmentDst
            break
        }

        _sdcFolderColumn.updateModel()
        _usbFolderColumn.updateModel()

        isUpdatePanels = false
    }

    Connections { target: _GuiView
        function onSdIsReadyChanged     ( vValue                        ) { _root.updatePanels()                                        }
        function onDidExportStat        ( vIndex, vFileName, vPercent   ) { _sdcFolderView.positionViewAtIndex(vIndex, ListView.Center) }
        function onDidUSBDriveUmount    (                               ) { _usbFolderColumn. clearModel ( )                            }
        function onDidUSBDriveRemove    (                               ) { _usbFolderColumn. clearModel ( )                            }
        function onDidExportLog         ( vValue                        ) { _usbFolderColumn. clearModel ( )                            }
        function onDidUSBDriveMount     (                               ) { _usbFolderColumn.updateModel ( )                            }
        function onDidExport            (                               ) { _usbFolderColumn.updateModel ( )                            }
    }

    USBButton                                               { id: _usbEjectButton
        width                                               : 155
        height                                              :  50
        anchors.right                                       : _root.right
        anchors.top                                         : _root.top
        anchors.margins                                     : Variables.headerButtonsMargin
        enabled                                             : _GuiView.usbIsReady && !_GuiView.exportRunning && ! isUpdatePanels
    }

    Row                                                     { id : _contentRect
        spacing                                             : Variables.minVGap
        anchors.fill                                        : parent
        anchors.topMargin                                   : parent.   topMarginContent - 25 // move 25 up
        anchors.bottomMargin                                : parent.bottomMarginContent
        anchors.rightMargin                                 : parent. sidesMarginContent
        anchors.leftMargin                                  : parent. sidesMarginContent
        anchors.horizontalCenter                            : parent.horizontalCenter

        readonly property int columnWidthProgress           : 350
        readonly property int columnWidthFolder             : 420
        readonly property int columnWidthFileName           : 285 // 285 best combination
        readonly property int columnWidthFileSize           : 105 // 105 best combination

        Column { id                                         : _progressColumn
            property int progressWidth                      : 125
            property int progressHeight                     : height - _logTypeCombo.height - _logTypeExportButton.height

            spacing                                         : 10
            width                                           : _contentRect.columnWidthProgress
            height                                          : parent.height
            anchors.verticalCenter                          : parent.verticalCenter

            Row { id                                        : _logTypeRow
                anchors.left                                : parent.left
                width                                       : parent.width
                height                                      : _root.headetRowHight
                spacing                                     : _logTypeCombo.width - _logTypeExportButton.width

                // FIXME: This combobox needs to be a global Component
                ComboBox { id                               : _logTypeCombo
                    onCurrentIndexChanged                   : {
                        _root.updatePanels(currentIndex)
                    }
                    enabled                                 : ! _GuiView.exportRunning && ! isUpdatePanels
                    currentIndex                            : 0
                    displayText                             : currentText
                    font.pixelSize                          : Fonts.fontPixelTextRectExtra
                    width                                   : parent.width
                    height                                  : parent.height
                    padding                                 : 10
                    model                                   : [
                        _root.typeLabelApplication          ,
                        _root.typeLabelService              ,
                        _root.typeLabelTreatment
                    ]

                    background                              : Rectangle {
                        color                               : Colors.transparent
                        border.color                        : enabled ? Colors.borderButton : Colors.borderDisableButton
                        radius                              : Variables.dialogRadius
                    }

                    delegate: ItemDelegate                  { id : _logTypeDelegate
                        width                               : _logTypeCombo.width // + anchors.margins - 2 // 2 is the border width
                        height                              : 50
                        contentItem: Text                   {
                            text                            : modelData
                            color                           : Colors.textMain
                            font                            : _logTypeCombo.font
                            padding                         : 10
                            verticalAlignment               : Text.AlignVCenter
                        }
                        background                          : Rectangle {
                            anchors.fill                    : parent
                            anchors.margins                 : 10 / 2
                            visible                         : _logTypeDelegate.down || _logTypeDelegate.highlighted || _logTypeDelegate.visualFocus
                            color                           : _logTypeDelegate.down ? Colors.backgroundButtonSelect    :
                                                                                      Colors.backgroundButtonSelectDark
                        }
                        highlighted                         : _logTypeCombo.highlightedIndex === index
                    }
                    popup: Popup {
                        y                                   : _logTypeCombo.height
                        x                                   :                     - _logTypeCombo.anchors.leftMargin
                        width                               : _logTypeCombo.width + _logTypeCombo.anchors.leftMargin
                        implicitHeight                      : contentItem.implicitHeight
                        contentItem                         : ListView {
                            clip                            : true
                            implicitHeight                  : contentHeight
                            currentIndex                    : _logTypeCombo.highlightedIndex
                            model                           : _logTypeCombo.popup.visible ? _logTypeCombo.delegateModel : null
                        }
                        background: Rectangle               {
                            color                           : Colors.backgroundMain
                            border.color                    : Colors.borderButton
                            radius                          : Variables.dialogRadius
                        }
                    }
                }
            }
            Column {
                width                                       : _progressColumn.progressWidth
                height                                      : _progressColumn.progressHeight - 2 * _progressColumn.spacing
                Item { id                                   : _SDC_item
                    width                                   : _progressColumn.progressWidth
                    height                                  : parent.height / 2

                    SDCProgressItem                         { id: _SDC_progressItem
                        thickness                           : 2
                        displayInformation                  : false
                        anchors.fill                        : parent
                    }
                    Label {
                        anchors.left                        : _SDC_progressItem.right
                        anchors.leftMargin                  : _progressColumn.spacing
                        anchors.verticalCenter              : parent.verticalCenter
                        text                                : _root.sdcLabel + _root.devUnitLabel + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.sdAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.sdTotal, 1000, 3) )
                    }
                    Label {
                        anchors.fill                        : parent
                        verticalAlignment                   : Text.AlignVCenter
                        horizontalAlignment                 : Text.AlignHCenter
                        text                                : _SDC_progressItem.percent
                    }
                }
                Item { id                                   : _USB_item
                    width                                   : _progressColumn.progressWidth
                    height                                  : parent.height / 2

                    USBProgressItem                         { id: _USB_progressItem
                        thickness                           : 2
                        displayInformation                  : false
                        anchors.fill                        : parent
                    }
                    Label {
                        anchors.left                        : _USB_progressItem.right
                        anchors.leftMargin                  : _progressColumn.spacing
                        anchors.verticalCenter              : parent.verticalCenter
                        text                                : _root.usbLabel + _root.devUnitLabel + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.usbAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.usbTotal, 1000, 3) )
                    }
                    Label {
                        anchors.fill                        : parent
                        verticalAlignment                   : Text.AlignVCenter
                        horizontalAlignment                 : Text.AlignHCenter
                        text                                : _USB_progressItem.percent
                    }
                }
            }
            ExportButton { id                               : _logTypeExportButton
                width                                       : parent.width
                height                                      : Variables.touchRectHeight
                radius                                      : Variables.touchRectRadius
                border.width                                : Variables.borderWidth
                enabled                                     : _GuiView.usbIsReady && !_GuiView.exportRunning && ! isUpdatePanels
                onClicked                                   : doExport()
            }
        }
        Column { id                                         : _sdcFolderColumn
            property string currentTypeFolderApplication    : _root.typeFolderApplicationSrc

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            function updateModel() {
                _sdcFolderModel.folder                      = currentTypeFolderApplication  // FIXME: there has to be a View for this which also get changed by log type.
                _sdcFolderModel.nameFilters                 = _root.typeFilterAll
            }
            function clearModel() {
                _sdcFolderModel.folder                      = _root.typePathClr
                _sdcFolderModel.nameFilters                 = _root.typeFilterClr
            }

            spacing                                         : 5
            width                                           : _contentRect.columnWidthFolder
            height                                          : parent.height
            anchors.verticalCenter                          : parent.verticalCenter
            Label { id                                      : _sdcLabel
                text                                        : _root.sdcLabel + ": %1 files"/*, %2 %3"*/.arg(_sdcFolderView.visibleFileCounter) + (_GuiView.exportCount ? " [Selected: %1]".arg(_GuiView.exportCount ) : "") //.arg("__").arg(_root.dvcUnit)
                width                                       : parent.width
                height                                      : _root.headetRowHight
                verticalAlignment                           : Text.AlignVCenter
            }
            Rectangle { id                                  : _sdcFolderRectangle
                color                                       : Colors.transparent
                border.color                                : Colors.borderButton
                radius                                      : Variables.dialogRadius
                anchors.left                                : parent.left
                width                                       : parent.width
                height                                      : parent.height - _sdcLabel.height

                ScrollBar {
                    anchors.fill                            : _sdcFolderView
                    flickable                               : _sdcFolderView
                    handleWidth                             : Variables.settingsExportLogsScrollBarWidth
                }

                ListView { id                               : _sdcFolderView
                    property int visibleFileCounter         : 0
                    enabled                                 : !_GuiView.exportRunning && ! isUpdatePanels
                    clip                                    : true
                    anchors.fill                            : parent
                    anchors.margins                         : 10
                    anchors.leftMargin                      : 5
                    anchors.rightMargin                     : 5
                    spacing                                 : 3
                    FolderListModel { id                    : _sdcFolderModel
                        onStatusChanged: {
                            // onFolderChanged does not get emitted when switching folders, but status change does.
                            // Reset the displayed file counter when the state of the model is null
                            if (_sdcFolderModel.status == FolderListModel.Null)
                            {
                                _sdcFolderView.visibleFileCounter = 0
                            }
                        }
                        showDirs                            : false
                        sortField                           : FolderListModel.Time
                        folder                              : _sdcFolderColumn.currentTypeFolderApplication // FIXME: there has to be a View for this which also get changed by log type.
                    }

                    Component { id                          : _sdcFileDelegate
                        ProgressBar {                   id  : _sdcItemBackground
                            // *** IMPORTANT ***
                            // QML kills the items when they get out of the view port in regards to the cacheBuffer,
                            // and the next time it gets in the view port will be created with all the properties in their defaults.
                            property bool inExportList      :   _GuiView.exportList         [ index ]   // I couldn't make it work and this always returns undefined, but has to be used to trigger the change.
                                                              ? _GuiView.exportList         [ index ]   // In case the issue fixes it should return true if it is true, obviously!
                                                              : _GuiView.doExportListSelect ( index )   // otherwise for now, it calls the contains() function of the list in C++ backend.
                            property int    exportPercent   :   _GuiView.exportIndex === index
                                                              ? _GuiView.exportPercent
                                                              : 0
                            onExportPercentChanged          : console.log( "%", exportPercent)

                            property bool isShownInList     : !_GuiView.isPathSymLink(_sdcFolderColumn.currentTypeFolderApplication.replace(typePathPrefix, "") + "/" + fileName)
                            Component.onCompleted: if ( isShownInList ) _sdcFolderView.visibleFileCounter++

                            //DEBUG: onInExportListChanged: console.debug(" * ", index, inExportList)
                            function exportListUpdate() {
                                if (_GuiView.doExportListSelect( index ) ) {
                                    _GuiView.doExportListDelete( index )
                                }
                                else {
                                    _GuiView.doExportListInsert( index , fileName )
                                }
                            }

                            MouseArea                       {
                                anchors.fill                : parent
                                onClicked                   : exportListUpdate()
                            }
                            progress.z                      : 0
                            minText.visible                 : false
                            maxText.visible                 : false
                            marker.visible                  : false
                            maximum                         : 100 // percent
                            value                           : maximum - exportPercent

                            // Setting height and width to 0 when the file is not shown in the list because
                            // it is a symlink or other conditions
                            width                           : isShownInList ? _sdcFolderView.width : 0
                            height                          : isShownInList ? 40                   : 0

                            bgColor                         : Colors.transparent
                            color                           : inExportList ? Colors.borderButtonSelected : Colors.transparent
                            radius                          : 5
                            Row {                       id  : _sdcFileRow
                                // Setting height and width to 0 when the file is not shown in the list because
                                // it is a symlink or other conditions
                                width                       : isShownInList ? parent.width : 0
                                height                      : isShownInList ? 40           : 0

                                leftPadding                 : 5
                                Text {                  id  : _sdcFileNameText
                                    x                       : 2
                                    clip                    : true
                                    width                   : isShownInList ? (_contentRect.columnWidthFileName - 2) : 0
                                    text                    : fileName
                                    color                   : Colors.textMain
                                    font.pixelSize          : Fonts.fontPixelTextRectExtra
                                    verticalAlignment       : Text.AlignVCenter
                                    horizontalAlignment     : Text.AlignLeft
                                }
                                Rectangle {             id  : _sdcColumnVerticalLine
                                    color                   : Colors.borderButtonUnselected
                                    width                   : isShownInList ? 1 : 0
                                    height                  : parent.height + _usbFolderColumn.spacing
                                }
                                Text {                  id  : _sdcFileSizeText
                                    clip                    : true
                                     width                   : isShownInList ? _contentRect.columnWidthFileSize : 0
                                    text                    : Variables.sizeConverted( fileSize, 1000, 3)
                                    color                   : Colors.textMain
                                    font.pixelSize          : Fonts.fontPixelTextRectExtra
                                    verticalAlignment       : Text.AlignVCenter
                                    horizontalAlignment     : Text.AlignRight
                                }
                            }
                        }
                    }
                    model                                   : _sdcFolderModel
                    delegate                                : _sdcFileDelegate
                }
            }
        }

        Column { id                                         : _usbFolderColumn
            property string currentTypeFolderApplication    : _root.typeFolderApplicationDst

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            function updateModel() {
                _usbFolderModel.folder                      = currentTypeFolderApplication  // FIXME: there has to be a View for this which also get changed by log type.
                _usbFolderModel.nameFilters                 = _root.typeFilterAll
            }
            function clearModel() {
                _usbFolderModel.folder                      = _root.typePathClr
                _usbFolderModel.nameFilters                 = _root.typeFilterClr
            }

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            Timer { id: _usbUpdate
                interval    : 500
                repeat      : true
                running     : _GuiView.exportRunning
                onRunningChanged: {
                    if(!running) {
                        // do one last update to get the correct file size else the USB file size is displayed
                        // as being smaller than the same file on SD card
                        _usbFolderColumn. clearModel()
                        _usbFolderColumn.updateModel()
                    }
                }

                onTriggered : {
                    _usbFolderColumn. clearModel()
                    _usbFolderColumn.updateModel()
                }
            }

            spacing                                         : 5
            width                                           : _contentRect.columnWidthFolder
            height                                          : parent.height
            anchors.verticalCenter                          : parent.verticalCenter

            Label { id                                      : _usbLabel
                text                                        : _root.usbLabel + ": %1 files"/*", %2 %3"*/.arg(_usbFolderModel.count)//.arg("__").arg(_root.dvcUnit)
                width                                       : parent.width
                height                                      : _root.headetRowHight
                verticalAlignment                           : Text.AlignVCenter
            }

            Rectangle { id                                  : _usbFolderRectangle
                color                                       : Colors.transparent
                border.color                                : Colors.borderButton
                radius                                      : Variables.dialogRadius
                anchors.left                                : parent.left
                width                                       : parent.width
                height                                      : parent.height -  _sdcLabel.height

                ScrollBar {
                    anchors.fill                            : _usbFolderView
                    flickable                               : _usbFolderView
                    handleWidth                             : Variables.settingsExportLogsScrollBarWidth
                }

                ListView { id                               : _usbFolderView
                    clip                                    : true
                    anchors.fill                            : parent
                    anchors.margins                         : 10
                    spacing                                 : 3

                    anchors.leftMargin                      : 5
                    anchors.rightMargin                     : 5

                    FolderListModel { id                    : _usbFolderModel // FIXME: I don't like this model, it's too lazy and I don't have control over it. There has to be a Model for this.
                        showDirs                            : false
                        sortField                           : FolderListModel.Time
                        folder                              : _usbFolderColumn.currentTypeFolderApplication
                    }
                    Component { id                          : _usbFileDelegate
                        Row { id                            : _usbFileRow
                            width                           : _usbFolderView.width
                            height                          : 40
                            Text { id                       : _usbFileNameText
                                clip                        : true
                                width                       : _contentRect.columnWidthFileName
                                text                        : fileName
                                color                       : Colors.textMain
                                font.pixelSize              : Fonts.fontPixelTextRectExtra
                                verticalAlignment           : Text.AlignVCenter
                                horizontalAlignment         : Text.AlignLeft
                            }
                            Rectangle {
                                color: Colors.borderButtonUnselected
                                width: 1
                                height: parent.height + _usbFolderColumn.spacing
                            }
                            Text { id                       : _usbFileSizeText
                                clip                        : true
                                width                       : _contentRect.columnWidthFileSize
                                text                        : Variables.sizeConverted( fileSize, 1000, 3)
                                color                       : Colors.textMain
                                font.pixelSize              : Fonts.fontPixelTextRectExtra
                                verticalAlignment           : Text.AlignVCenter
                                horizontalAlignment         : Text.AlignRight
                            }
                        }
                    }
                    model                                   : _usbFolderModel
                    delegate                                : _usbFileDelegate
                }
            }
        }
    }
}
