package ocelot.desktop.ui.widget

import ocelot.desktop.ColorScheme
import ocelot.desktop.color.Color
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.inventory.traits.DiskItem
import ocelot.desktop.ui.layout.{AlignItems, LinearLayout}
import ocelot.desktop.ui.widget.window.PanelWindow
import ocelot.desktop.util.SizeFormatting.formatSize
import ocelot.desktop.util.animation.ColorAnimation
import ocelot.desktop.util.{DiskDriveAware, Orientation}
import totoro.ocelot.brain.entity.traits.{DiskManaged, DiskUnmanaged}
import totoro.ocelot.brain.util.DyeColor

class DiskEditWindow(item: DiskItem) extends PanelWindow {
  private def diskSize: Option[Long] = Some(item.component).collect { case disk: DiskManaged =>
    disk.fileSystem.fileSystem.spaceUsed
  }

  private def diskCapacity: Long = item.component.capacity

  private def isWriteable: Boolean = item.component match {
    case disk: DiskManaged => !disk.fileSystem.fileSystem.isReadOnly
    case disk: DiskUnmanaged => !disk.isLocked
  }

  private def isManaged: Boolean = item.component match {
    case _: DiskManaged => true
    case _: DiskUnmanaged => false
  }

  private def address: Option[String] = Option(item.component.node).flatMap(node => Option(node.address))

  override protected def title: String = s"${item.diskKind} " + address.getOrElse("")

  override protected def titleMaxLength: Int = 32

  setInner(new Widget {
    override val layout = new LinearLayout(this, orientation = Orientation.Vertical)

    children :+= new PaddingBox(
      new Label {
        override def text: String = diskSize match {
          case Some(used) => s"Used: ${formatSize(used)} / ${formatSize(diskCapacity)}"
          case None => s"Capacity: ${formatSize(diskCapacity)}"
        }
      },
      Padding2D(bottom = 12),
    )

    children :+= new PaddingBox(
      new Widget {
        override val layout = new LinearLayout(this,
          orientation = Orientation.Horizontal, alignItems = AlignItems.Center)

        children :+= new Label("Label")

        children :+= new TextInput(item.label.getOrElse("")) {
          override def onConfirm(): Unit = {
            super.onConfirm()
            item.setLabel(Some(text).filter(_.nonEmpty))
          }

          override def enabled: Boolean = item.isLabelWriteable
        }
      },
      Padding2D(bottom = 12),
    )

    if (item.color.nonEmpty) {
      val colorSelector: Widget = new Widget {
        override val layout = new LinearLayout(this, orientation = Orientation.Vertical, gap = 2)

        for (row <- DyeColor.All.iterator.grouped(8)) {
          children :+= new Widget {
            override val layout = new LinearLayout(this, orientation = Orientation.Horizontal, gap = 2)

            for (dyeColor <- row) {
              def isColorSelected: Boolean = dyeColor == item.color.get

              val floppyIcon = IconSource.FloppyDisk(dyeColor).path
              children :+= new IconButton(
                floppyIcon,
                floppyIcon,
                mode = IconButton.Mode.Radio,
                drawBackground = true,
                tooltip = Some(DiskDriveAware.ColorNames(dyeColor)),
                padding = 2,
                sizeMultiplier = 2f,
                model = IconButton.ReadOnlyModel(isColorSelected),
              )
              {
                private val backgroundAnimation = new ColorAnimation(targetBackgroundColor, IconButton.AnimationSpeed)
                private val borderAnimation = new ColorAnimation(targetBorderColor, IconButton.AnimationSpeed)

                private def targetBackgroundColor: Color =
                  if (isColorSelected) ColorScheme("FloppyIconButtonBackgroundSelected")
                  else ColorScheme("ButtonBackground")

                private def targetBorderColor: Color =
                  if (isColorSelected) ColorScheme("FloppyIconButtonBorderSelected")
                  else ColorScheme("ButtonBorder")

                override protected def updateAnimationTargets(): Unit = {
                  super.updateAnimationTargets()
                  backgroundAnimation.goto(targetBackgroundColor)
                  borderAnimation.goto(targetBorderColor)
                }

                override def backgroundColor: Color = backgroundAnimation.color

                override def borderColor: Color = borderAnimation.color

                override def onPressed(): Unit = {
                  if (!isColorSelected) {
                    item.setColor(dyeColor)
                  }
                }

                override def update(): Unit = {
                  super.update()
                  backgroundAnimation.update()
                  borderAnimation.update()
                }
              }
            }

          }
        }
      }

      children :+= new PaddingBox(colorSelector, Padding2D(bottom = 12))
    }

    children :+= new Widget {
      override val layout = new LinearLayout(this, orientation = Orientation.Horizontal, gap = 8)

      children :+= new Button {
        override def text: String = "Make read-only"

        override def onClick(): Unit = item.lock()

        override def enabled: Boolean = isWriteable
      }

      children :+= new Button {
        override def text: String = s"Make ${if (isManaged) "unmanaged" else "managed"}"

        override def onClick(): Unit = item.setManaged(!isManaged)

        override def maximumSize: Size2D = super.maximumSize.copy(width = Float.PositiveInfinity)
      }
    }
  })
}
