/*
 * Copyright (C) 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 <https://www.gnu.org/licenses/>.
 */

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

import net.jami.Constants 1.1

// This component will attempt to occupy the maximum width of the layout
// If width constraints are required, use Layout.maximumWidth
ColumnLayout {
    id: root

    property bool isTall: false

    // Leading icon properties
    // The icon colour is only exposed here for the sake of UsernameTextEdit,
    // ideally it should remain untouched for consistency throughout the UI
    property color leadingIconColor: JamiTheme.textColor
    property string leadingIconSource: ""
    property bool leadingIconIsSpinning: false

    // TextField properties
    property real textFieldHeight: isTall ? JamiTheme.newMaterialTextFieldTallHeight : JamiTheme.newMaterialTextFieldHeight
    // placeholderText is the text that will be shown when textFieldContent and modifiedTextFieldContent are empty
    // (ex: "Add description" SwarmDetailsPanel (swarm only))
    property string placeholderText: ""
    // textFieldContent is the text that is shown in the text field, it essentially acts as a default/prefill
    // (ex: The actual description of the swarm)
    property string textFieldContent: ""
    // modifiedTextFieldContent is the text that represents the modified version of the textFieldContent
    // (ex: The modified description of the swarm prior to calling the accepted signal)
    property string modifiedTextFieldContent
    property int maxCharacters: -1
    property bool readOnly: false
    property string textFieldFontFamily: JamiTheme.ubuntuFontFamily
    property real textFieldFontPixelSize: JamiTheme.materialLineEditPixelSize
    property int echoMode: TextInput.Normal
    property bool inputIsValid: true
    property var validator: RegularExpressionValidator {}
    signal editingFinished()

    // Trailing icon properties
    property color trailingIconColor: JamiTheme.textColor
    property string trailingIconSource: ""
    property string trailingIconToolTipText: ""
    property bool trailingIconChecked: false
    property string trailingIconAccessibleDescription: ""
    signal trailingIconClicked()

    // Tooltip properties
    property alias toolTipText: toolTip.text

    // Supporting text
    property real supportingTextX: textFieldEditor.background.radius
    property real supportingTextY: textFieldEditor.background.height + JamiTheme.newMaterialTextFieldSupportingTextTopPadding
    property string supportingText: ""
    property color supportingTextColor: JamiTheme.textColor

    // Background properties
    property color borderColor: JamiTheme.tintedBlue

    opacity: textField.activeFocus && !root.readOnly ? 1.0 : 0.7

    Behavior on opacity {
        NumberAnimation {
            duration: JamiTheme.shortFadeDuration
        }
    }

    Layout.fillWidth: true

    Control {
        id: textFieldEditor

        Layout.fillWidth: true
        Layout.preferredHeight: root.textFieldHeight
        Layout.maximumHeight: root.textFieldHeight

        leftPadding: root.leadingIconSource !== "" ? JamiTheme.newMaterialTextFieldIconHorizontalPadding : JamiTheme.newMaterialTextFieldHorizontalPadding
        rightPadding: root.trailingIconSource !== "" ? JamiTheme.newMaterialTextFieldIconHorizontalPadding : JamiTheme.newMaterialTextFieldHorizontalPadding
        topPadding: (textFieldHeight / JamiTheme.iconButtonMedium) / 2
        bottomPadding: (textFieldHeight / JamiTheme.iconButtonMedium) / 2

        contentItem: RowLayout {
            spacing: 0

            Button {
                id: leadingIcon

                Layout.alignment: Qt.AlignVCenter

                padding: 0

                width: JamiTheme.iconButtonMedium
                height: JamiTheme.iconButtonMedium

                icon.width: JamiTheme.iconButtonMedium
                icon.height: JamiTheme.iconButtonMedium
                icon.source: root.leadingIconSource
                icon.color: root.leadingIconColor

                background: null

                // This shouldnt be interactive, so we disable its background
                // and fix the icon's colour
                enabled: false

                activeFocusOnTab: false

                visible: root.leadingIconSource !== ""

                // Spin the button
                RotationAnimator {
                    id: rotationAnimator
                    target: leadingIcon
                    running: root.leadingIconIsSpinning
                    from: 0
                    to: 360
                    duration: 1000
                    loops: Animation.Infinite
                }

                rotation: root.leadingIconIsSpinning ? leadingIcon.rotation : 0
            }

            TextField {
                id: textField
                objectName: "textField"

                Layout.fillWidth: true
                Layout.alignment: Qt.AlignVCenter

                text: root.textFieldContent
                placeholderText: root.placeholderText
                placeholderTextColor: JamiTheme.textColor
                verticalAlignment: TextInput.AlignVCenter
                horizontalAlignment: TextInput.AlignLeft

                color: JamiTheme.textColor
                font.family: root.textFieldFontFamily
                font.pixelSize: root.textFieldFontPixelSize

                maximumLength: root.maxCharacters ? root.maxCharacters : 32767
                readOnly: root.readOnly
                wrapMode: TextInput.NoWrap

                echoMode: root.echoMode
                validator: root.validator

                background: null

                onReleased: function (event) {
                    if (event.button === Qt.RightButton)
                        contextMenu.openMenuAt(event);
                }

                onEditingFinished: {
                    if (inputIsValid && root.textFieldContent !== root.modifiedTextFieldContent)
                        root.editingFinished()
                }

                onTextChanged: root.modifiedTextFieldContent = text

                Connections {
                    target: root
                    function onModifiedTextFieldContentChanged() {
                        if (textField.text !== root.modifiedTextFieldContent)
                            textField.text = root.modifiedTextFieldContent
                    }
                }

                LineEditContextMenu {
                    id: contextMenu

                    lineEditObj: parent
                    selectOnly: root.readOnly
                }
            }


            Button {
                id: trailingIcon

                Layout.alignment: Qt.AlignVCenter

                padding: 0

                icon.width: JamiTheme.iconButtonMedium
                icon.height: JamiTheme.iconButtonMedium
                icon.source: root.trailingIconSource
                icon.color: {
                    if (pressed) {
                        return JamiTheme.textColor;
                    } else if (hovered) {
                        return JamiTheme.newMaterialTextFieldTrailingIconHoveredColor;
                    } else {
                        return JamiTheme.newMaterialTextFieldTrailingIconColor;
                    }
                }

                Behavior on icon.color {
                    ColorAnimation {
                        duration: 200
                    }
                }

                onClicked: root.trailingIconClicked()

                activeFocusOnTab: icon.source !== ""

                checked: root.trailingIconChecked

                background: null

                visible: root.trailingIconSource !== "" && !readOnly

                MaterialToolTip {
                    id: iconButtonToolTip

                    parent: trailingIcon

                    text: root.trailingIconToolTipText

                    visible: (trailingIcon.hovered || trailingIcon.activeFocus) && (toolTipText.length > 0)
                    delay: Qt.styleHints.mousePressAndHoldInterval
                }

                Accessible.role: Accessible.Button
                Accessible.name: root.trailingIconToolTipText
                Accessible.description: root.trailingIconAccessibleDescription
            }
        }

        background: Rectangle {
            id: bgRect

            color: JamiTheme.newMaterialTextFieldColor
            radius: JamiTheme.iconButtonMedium / 2 + parent.rightPadding

            border.width: 1
            border.color: textField.activeFocus && !root.readOnly ? root.borderColor : JamiTheme.transparentColor

            Behavior on border.color {
                ColorAnimation  {
                    duration: JamiTheme.shortFadeDuration
                }
            }
        }

        Text {
            x: root.supportingTextX
            y: root.supportingTextY

            text: root.supportingText
            color: root.supportingTextColor
            horizontalAlignment: Qt.AlignLeft
            font.pixelSize: JamiTheme.mediumFontSize
        }

        MaterialToolTip {
            id: toolTip

            parent: parent
            visible: parent.hovered && root.toolTipText !== "" && !root.readOnly && !trailingIcon.hovered
            delay: Qt.styleHints.mousePressAndHoldInterval
        }
    }
}
