/*
 * Copyright (C) 2024-2026 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import QtQml.Models
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Enums 1.1
import net.jami.Constants 1.1
import net.jami.Helpers 1.1
import "../../commoncomponents"

SettingsPageBase {
    id: root

    property int itemWidth: 266
    property real aspectRatio: 0.75
    title: JamiStrings.video

    flickableContent: ColumnLayout {
        id: rootLayout

        width: contentFlickableWidth
        spacing: JamiTheme.settingsCategoryAudioVideoSpacing
        anchors.left: parent.left
        anchors.leftMargin: JamiTheme.preferredSettingsMarginSize

        function startPreviewing(force = false) {
            if (!visible) {
                return;
            }
            previewWidget.startWithId(VideoDevices.getDefaultDevice(), force);
        }

        Connections {
            target: VideoDevices

            function onDefaultResChanged() {
                rootLayout.startPreviewing(true);
            }

            function onDefaultFpsChanged() {
                rootLayout.startPreviewing(true);
            }

            function onDeviceAvailable() {
                rootLayout.startPreviewing();
            }

            function onDeviceListChanged() {
                var deviceModel = deviceComboBoxSetting.comboModel;
                var resModel = resolutionComboBoxSetting.comboModel;
                var fpsModel = fpsComboBoxSetting.comboModel;
                var resultList = deviceModel.match(deviceModel.index(0, 0), VideoInputDeviceModel.DeviceId, VideoDevices.defaultId);
                deviceComboBoxSetting.modelIndex = resultList.length > 0 ? resultList[0].row : deviceModel.rowCount() ? 0 : -1;
                resultList = resModel.match(resModel.index(0, 0), VideoFormatResolutionModel.Resolution, VideoDevices.defaultRes);
                resolutionComboBoxSetting.modelIndex = resultList.length > 0 ? resultList[0].row : deviceModel.rowCount() ? 0 : -1;
                resultList = fpsModel.match(fpsModel.index(0, 0), VideoFormatFpsModel.FPS, VideoDevices.defaultFps);
                fpsComboBoxSetting.modelIndex = resultList.length > 0 ? resultList[0].row : deviceModel.rowCount() ? 0 : -1;
            }
        }

        Component.onCompleted: {
            flipControl.checked = UtilsAdapter.getAppValue(Settings.FlipSelf);
            hardwareAccelControl.checked = AvAdapter.getHardwareAcceleration();
            var currentRes = AvAdapter.getConferenceResolution();
            for (var i = 0; i < conferenceResModel.count; i++) {
                if (conferenceResModel.get(i).Resolution === currentRes) {
                    conferenceResolutionComboBox.modelIndex = i;
                    break;
                }
            }
            startPreviewing(true);
        }

        Component.onDestruction: previewWidget.stop()

        // video Preview
        Rectangle {
            visible: VideoDevices.listSize !== 0

            Layout.alignment: Qt.AlignHCenter
            Layout.preferredHeight: width * previewWidget.invAspectRatio

            Layout.minimumWidth: 200
            Layout.maximumWidth: 515
            Layout.preferredWidth: parent.width

            Layout.bottomMargin: JamiTheme.preferredMarginSize

            color: JamiTheme.primaryForegroundColor

            LocalVideo {
                id: previewWidget

                anchors.fill: parent
                flip: flipControl.checked

                underlayItems: Text {
                    anchors.centerIn: parent
                    font.pointSize: 18
                    font.capitalization: Font.AllUppercase
                    color: "white"
                    text: JamiStrings.noCamera
                }
            }
        }

        ToggleSwitch {
            id: flipControl

            Layout.fillWidth: true
            labelText: JamiStrings.mirrorLocalVideo

            onSwitchToggled: {
                UtilsAdapter.setAppValue(Settings.FlipSelf, checked);
                CurrentCall.flipSelf = UtilsAdapter.getAppValue(Settings.FlipSelf);
            }
        }

        SettingsComboBox {
            id: deviceComboBoxSetting

            Layout.fillWidth: true

            enabled: VideoDevices.listSize !== 0
            opacity: enabled ? 1.0 : 0.5

            widthOfComboBox: itemWidth

            labelText: JamiStrings.device
            tipText: JamiStrings.selectVideoDevice
            placeholderText: JamiStrings.noVideoDevice
            currentSelectionText: VideoDevices.defaultName

            comboModel: SortFilterProxyModel {
                id: filteredDevicesModel
                model: SortFilterProxyModel {
                    id: deviceSourceModel
                    model: VideoDevices.deviceSourceModel
                }
                filters: ValueFilter {
                    roleName: "DeviceName"
                    value: VideoDevices.defaultName
                    invert: true
                    enabled: deviceSourceModel.rowCount() > 1
                }
            }
            role: "DeviceName"

            onActivated: {
                // TODO: start and stop preview logic in here should be in LRC
                previewWidget.startWithId("");
                VideoDevices.setDefaultDevice(filteredDevicesModel.mapToSource(filteredDevicesModel.index(modelIndex, 0)).row);
                rootLayout.startPreviewing();
            }
        }

        SettingsComboBox {
            id: resolutionComboBoxSetting

            Layout.fillWidth: true

            enabled: VideoDevices.listSize !== 0
            opacity: enabled ? 1.0 : 0.5

            widthOfComboBox: itemWidth

            labelText: JamiStrings.resolution
            currentSelectionText: VideoDevices.defaultRes
            tipText: JamiStrings.selectVideoResolution

            comboModel: SortFilterProxyModel {
                id: filteredResModel
                model: SortFilterProxyModel {
                    id: resSourceModel
                    model: VideoDevices.resSourceModel
                }
                filters: ValueFilter {
                    roleName: "Resolution"
                    value: VideoDevices.defaultRes
                    invert: true
                    enabled: resSourceModel.rowCount() > 1
                }
            }
            role: "Resolution"

            onActivated: VideoDevices.setDefaultDeviceRes(filteredResModel.mapToSource(filteredResModel.index(modelIndex, 0)).row)
        }

        SettingsComboBox {
            id: fpsComboBoxSetting

            Layout.fillWidth: true

            enabled: VideoDevices.listSize !== 0
            opacity: enabled ? 1.0 : 0.5

            widthOfComboBox: itemWidth

            tipText: JamiStrings.selectFPS
            labelText: JamiStrings.fps
            currentSelectionText: VideoDevices.defaultFps.toString()
            comboModel: SortFilterProxyModel {
                id: filteredFpsModel
                model: SortFilterProxyModel {
                    id: fpsSourceModel
                    model: VideoDevices.fpsSourceModel
                }
                filters: ValueFilter {
                    roleName: "FPS"
                    value: VideoDevices.defaultFps
                    invert: true
                    enabled: fpsSourceModel.rowCount() > 1
                }
            }
            role: "FPS"

            onActivated: VideoDevices.setDefaultDeviceFps(filteredFpsModel.mapToSource(filteredFpsModel.index(modelIndex, 0)).row)
        }

        ToggleSwitch {
            id: hardwareAccelControl

            Layout.fillWidth: true

            labelText: JamiStrings.enableHWAccel

            onSwitchToggled: {
                AvAdapter.setHardwareAcceleration(checked);
                rootLayout.startPreviewing(true);
            }
        }

        ColumnLayout {
            id: conferencesSection

            Layout.fillWidth: true
            Layout.topMargin: JamiTheme.preferredMarginSize
            spacing: JamiTheme.settingsCategorySpacing

            Text {
                Layout.alignment: Qt.AlignLeft
                Layout.fillWidth: true

                text: JamiStrings.groupCallsAndConferences
                color: JamiTheme.textColor
                horizontalAlignment: Text.AlignLeft
                verticalAlignment: Text.AlignVCenter
                wrapMode: Text.WordWrap

                font.pixelSize: JamiTheme.settingsTitlePixelSize
                font.kerning: true
            }

            SettingsComboBox {
                id: conferenceResolutionComboBox

                Layout.fillWidth: true

                widthOfComboBox: itemWidth

                labelText: JamiStrings.conferenceResolution
                comboModel: ListModel {
                    id: conferenceResModel
                    ListElement {
                        Label: "HD 720p"
                        Resolution: "1280x720"
                    }
                    ListElement {
                        Label: "Full HD 1080p"
                        Resolution: "1920x1080"
                    }
                    ListElement {
                        Label: "Quad HD 1440p"
                        Resolution: "2560x1440"
                    }
                }
                role: "Label"

                onActivated: {
                    var resolution = conferenceResModel.get(modelIndex).Resolution;
                    AvAdapter.setConferenceResolution(resolution);
                }
            }
        }
    }
}
