import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Effects
import Quickshell
import Quickshell.Io
import qs.Commons
import qs.Services.Compositor
import qs.Services.UI
import qs.Widgets

Item {
  id: root

  property ShellScreen screen

  // Widget properties passed from Bar.qml for per-instance settings
  property string widgetId: ""
  property string section: ""
  property int sectionWidgetIndex: -1
  property int sectionWidgetsCount: 0

  property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
  property var widgetSettings: {
    if (section && sectionWidgetIndex >= 0) {
      var widgets = Settings.data.bar.widgets[section]
      if (widgets && sectionWidgetIndex < widgets.length) {
        return widgets[sectionWidgetIndex]
      }
    }
    return {}
  }

  readonly property string barPosition: Settings.data.bar.position
  readonly property bool isVertical: barPosition === "left" || barPosition === "right"
  readonly property bool density: Settings.data.bar.density
  readonly property real baseDimensionRatio: {
    const b = (density === "compact") ? 0.85 : 0.65
    if (widgetSettings.labelMode === "none") {
      return b * 0.75
    }
    return b
  }

  readonly property string labelMode: (widgetSettings.labelMode !== undefined) ? widgetSettings.labelMode : widgetMetadata.labelMode
  readonly property bool hideUnoccupied: (widgetSettings.hideUnoccupied !== undefined) ? widgetSettings.hideUnoccupied : widgetMetadata.hideUnoccupied
  readonly property int characterCount: isVertical ? 2 : ((widgetSettings.characterCount !== undefined) ? widgetSettings.characterCount : widgetMetadata.characterCount)

  property bool isDestroying: false
  property bool hovered: false

  property ListModel localWorkspaces: ListModel {}
  property real masterProgress: 0.0
  property bool effectsActive: false
  property color effectColor: Color.mPrimary

  property int horizontalPadding: Style.marginS
  property int spacingBetweenPills: Style.marginXS

  // Wheel scroll handling
  property int wheelAccumulatedDelta: 0
  property bool wheelCooldown: false

  signal workspaceChanged(int workspaceId, color accentColor)

  implicitWidth: isVertical ? Style.barHeight : computeWidth()
  implicitHeight: isVertical ? computeHeight() : Style.barHeight

  function getWorkspaceWidth(ws) {
    const d = Style.capsuleHeight * root.baseDimensionRatio
    const factor = ws.isActive ? 2.2 : 1

    // For name mode, calculate width based on actual text content
    if (labelMode === "name" && ws.name && ws.name.length > 0) {
      const displayText = ws.name.substring(0, characterCount)
      const textWidth = displayText.length * (d * 0.4) // Approximate width per character
      const padding = d * 0.6 // Padding on both sides
      return Math.max(d * factor, textWidth + padding)
    }

    return d * factor
  }

  function getWorkspaceHeight(ws) {
    const d = Style.capsuleHeight * root.baseDimensionRatio
    const factor = ws.isActive ? 2.2 : 1
    return d * factor
  }

  function computeWidth() {
    let total = 0
    for (var i = 0; i < localWorkspaces.count; i++) {
      const ws = localWorkspaces.get(i)
      total += getWorkspaceWidth(ws)
    }
    total += Math.max(localWorkspaces.count - 1, 0) * spacingBetweenPills
    total += horizontalPadding * 2
    return Math.round(total)
  }

  function computeHeight() {
    let total = 0
    for (var i = 0; i < localWorkspaces.count; i++) {
      const ws = localWorkspaces.get(i)
      total += getWorkspaceHeight(ws)
    }
    total += Math.max(localWorkspaces.count - 1, 0) * spacingBetweenPills
    total += horizontalPadding * 2
    return Math.round(total)
  }

  function getFocusedLocalIndex() {
    for (var i = 0; i < localWorkspaces.count; i++) {
      if (localWorkspaces.get(i).isFocused === true)
        return i
    }
    return -1
  }

  function switchByOffset(offset) {
    if (localWorkspaces.count === 0)
      return
    var current = getFocusedLocalIndex()
    if (current < 0)
      current = 0
    var next = (current + offset) % localWorkspaces.count
    if (next < 0)
      next = localWorkspaces.count - 1
    const ws = localWorkspaces.get(next)
    if (ws && ws.idx !== undefined)
      CompositorService.switchToWorkspace(ws)
  }

  Component.onCompleted: {
    refreshWorkspaces()
  }

  Component.onDestruction: {
    root.isDestroying = true
  }

  onScreenChanged: refreshWorkspaces()
  onHideUnoccupiedChanged: refreshWorkspaces()

  Connections {
    target: CompositorService
    function onWorkspacesChanged() {
      refreshWorkspaces()
    }
  }

  function refreshWorkspaces() {
    localWorkspaces.clear()
    if (screen !== null) {
      for (var i = 0; i < CompositorService.workspaces.count; i++) {
        const ws = CompositorService.workspaces.get(i)
        if (ws.output.toLowerCase() === screen.name.toLowerCase()) {
          if (hideUnoccupied && !ws.isOccupied && !ws.isFocused) {
            continue
          }
          localWorkspaces.append(ws)
        }
      }
    }
    workspaceRepeaterHorizontal.model = localWorkspaces
    workspaceRepeaterVertical.model = localWorkspaces
    updateWorkspaceFocus()
  }

  function triggerUnifiedWave() {
    effectColor = Color.mPrimary
    masterAnimation.restart()
  }

  function updateWorkspaceFocus() {
    for (var i = 0; i < localWorkspaces.count; i++) {
      const ws = localWorkspaces.get(i)
      if (ws.isFocused === true) {
        root.triggerUnifiedWave()
        root.workspaceChanged(ws.id, Color.mPrimary)
        break
      }
    }
  }

  SequentialAnimation {
    id: masterAnimation
    PropertyAction {
      target: root
      property: "effectsActive"
      value: true
    }
    NumberAnimation {
      target: root
      property: "masterProgress"
      from: 0.0
      to: 1.0
      duration: Style.animationSlow * 2
      easing.type: Easing.OutQuint
    }
    PropertyAction {
      target: root
      property: "effectsActive"
      value: false
    }
    PropertyAction {
      target: root
      property: "masterProgress"
      value: 0.0
    }
  }

  Rectangle {
    id: workspaceBackground
    width: isVertical ? Style.capsuleHeight : parent.width
    height: isVertical ? parent.height : Style.capsuleHeight
    radius: Style.radiusM
    color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent

    anchors.horizontalCenter: parent.horizontalCenter
    anchors.verticalCenter: parent.verticalCenter
  }

  // Debounce timer for wheel interactions
  Timer {
    id: wheelDebounce
    interval: 150
    repeat: false
    onTriggered: {
      root.wheelCooldown = false
      root.wheelAccumulatedDelta = 0
    }
  }

  // Scroll to switch workspaces
  WheelHandler {
    id: wheelHandler
    target: root
    acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
    onWheel: function (event) {
      if (root.wheelCooldown)
        return
      // Prefer vertical delta, fall back to horizontal if needed
      var dy = event.angleDelta.y
      var dx = event.angleDelta.x
      var useDy = Math.abs(dy) >= Math.abs(dx)
      var delta = useDy ? dy : dx
      // One notch is typically 120
      root.wheelAccumulatedDelta += delta
      var step = 120
      if (Math.abs(root.wheelAccumulatedDelta) >= step) {
        var direction = root.wheelAccumulatedDelta > 0 ? -1 : 1
        // For vertical layout, natural mapping: wheel up -> previous, down -> next (already handled by sign)
        // For horizontal layout, same mapping using vertical wheel
        root.switchByOffset(direction)
        root.wheelCooldown = true
        wheelDebounce.restart()
        root.wheelAccumulatedDelta = 0
        event.accepted = true
      }
    }
  }

  // Horizontal layout for top/bottom bars
  Row {
    id: pillRow
    spacing: spacingBetweenPills
    anchors.verticalCenter: workspaceBackground.verticalCenter
    x: horizontalPadding
    visible: !isVertical

    Repeater {
      id: workspaceRepeaterHorizontal
      model: localWorkspaces
      Item {
        id: workspacePillContainer
        width: root.getWorkspaceWidth(model)
        height: Style.capsuleHeight * root.baseDimensionRatio

        Rectangle {
          id: pill
          anchors.fill: parent

          Loader {
            active: (labelMode !== "none")
            sourceComponent: Component {
              NText {
                x: (pill.width - width) / 2
                y: (pill.height - height) / 2 + (height - contentHeight) / 2
                text: {
                  if (labelMode === "name" && model.name && model.name.length > 0) {
                    return model.name.substring(0, characterCount)
                  } else {
                    return model.idx.toString()
                  }
                }
                family: Settings.data.ui.fontFixed
                pointSize: model.isActive ? workspacePillContainer.height * 0.45 : workspacePillContainer.height * 0.42
                applyUiScale: false
                font.capitalization: Font.AllUppercase
                font.weight: Style.fontWeightBold
                wrapMode: Text.Wrap
                color: {
                  if (model.isFocused)
                    return Color.mOnPrimary
                  if (model.isUrgent)
                    return Color.mOnError
                  if (model.isOccupied)
                    return Color.mOnSecondary

                  return Color.mOnSecondary
                }
              }
            }
          }

          radius: width * 0.5
          color: {
            if (model.isFocused)
              return Color.mPrimary
            if (model.isUrgent)
              return Color.mError
            if (model.isOccupied)
              return Color.mSecondary

            return Qt.alpha(Color.mSecondary, 0.3)
          }
          scale: model.isActive ? 1.0 : 0.9
          z: 0

          MouseArea {
            id: pillMouseArea
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            onClicked: {
              CompositorService.switchToWorkspace(model)
            }
            hoverEnabled: true
          }
          // Material 3-inspired smooth animation for width, height, scale, color, opacity, and radius
          Behavior on width {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on height {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on scale {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on color {
            ColorAnimation {
              duration: Style.animationFast
              easing.type: Easing.InOutCubic
            }
          }
          Behavior on opacity {
            NumberAnimation {
              duration: Style.animationFast
              easing.type: Easing.InOutCubic
            }
          }
          Behavior on radius {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
        }

        Behavior on width {
          NumberAnimation {
            duration: Style.animationNormal
            easing.type: Easing.OutBack
          }
        }
        Behavior on height {
          NumberAnimation {
            duration: Style.animationNormal
            easing.type: Easing.OutBack
          }
        }
        // Burst effect overlay for focused pill (smaller outline)
        Rectangle {
          id: pillBurst
          anchors.centerIn: workspacePillContainer
          width: workspacePillContainer.width + 18 * root.masterProgress * scale
          height: workspacePillContainer.height + 18 * root.masterProgress * scale
          radius: width / 2
          color: Color.transparent
          border.color: root.effectColor
          border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
          opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
          visible: root.effectsActive && model.isFocused
          z: 1
        }
      }
    }
  }

  // Vertical layout for left/right bars
  Column {
    id: pillColumn
    spacing: spacingBetweenPills
    anchors.horizontalCenter: workspaceBackground.horizontalCenter
    y: horizontalPadding
    visible: isVertical

    Repeater {
      id: workspaceRepeaterVertical
      model: localWorkspaces
      Item {
        id: workspacePillContainerVertical
        width: Style.capsuleHeight * root.baseDimensionRatio
        height: root.getWorkspaceHeight(model)

        Rectangle {
          id: pillVertical
          anchors.fill: parent

          Loader {
            active: (labelMode !== "none")
            sourceComponent: Component {
              NText {
                x: (pillVertical.width - width) / 2
                y: (pillVertical.height - height) / 2 + (height - contentHeight) / 2
                text: {
                  if (labelMode === "name" && model.name && model.name.length > 0) {
                    return model.name.substring(0, characterCount)
                  } else {
                    return model.idx.toString()
                  }
                }
                family: Settings.data.ui.fontFixed
                pointSize: model.isActive ? workspacePillContainerVertical.width * 0.45 : workspacePillContainerVertical.width * 0.42
                applyUiScale: false
                font.capitalization: Font.AllUppercase
                font.weight: Style.fontWeightBold
                wrapMode: Text.Wrap
                color: {
                  if (model.isFocused)
                    return Color.mOnPrimary
                  if (model.isUrgent)
                    return Color.mOnError
                  if (model.isOccupied)
                    return Color.mOnSecondary

                  return Color.mOnSurface
                }
              }
            }
          }

          radius: width * 0.5
          color: {
            if (model.isFocused)
              return Color.mPrimary
            if (model.isUrgent)
              return Color.mError
            if (model.isOccupied)
              return Color.mSecondary

            return Color.mOutline
          }
          scale: model.isActive ? 1.0 : 0.9
          z: 0

          MouseArea {
            id: pillMouseAreaVertical
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            onClicked: {
              CompositorService.switchToWorkspace(model)
            }
            hoverEnabled: true
          }
          // Material 3-inspired smooth animation for width, height, scale, color, opacity, and radius
          Behavior on width {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on height {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on scale {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
          Behavior on color {
            ColorAnimation {
              duration: Style.animationFast
              easing.type: Easing.InOutCubic
            }
          }
          Behavior on opacity {
            NumberAnimation {
              duration: Style.animationFast
              easing.type: Easing.InOutCubic
            }
          }
          Behavior on radius {
            NumberAnimation {
              duration: Style.animationNormal
              easing.type: Easing.OutBack
            }
          }
        }

        Behavior on width {
          NumberAnimation {
            duration: Style.animationNormal
            easing.type: Easing.OutBack
          }
        }
        Behavior on height {
          NumberAnimation {
            duration: Style.animationNormal
            easing.type: Easing.OutBack
          }
        }
        // Burst effect overlay for focused pill (smaller outline)
        Rectangle {
          id: pillBurstVertical
          anchors.centerIn: workspacePillContainerVertical
          width: workspacePillContainerVertical.width + 18 * root.masterProgress * scale
          height: workspacePillContainerVertical.height + 18 * root.masterProgress * scale
          radius: width / 2
          color: Color.transparent
          border.color: root.effectColor
          border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
          opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
          visible: root.effectsActive && model.isFocused
          z: 1
        }
      }
    }
  }
}
