import type { LayoutService } from "./index"
import { LayoutPriority, type View } from "./splitView"

const createProportionLayout = (proportion: number, layoutService: LayoutService) => () =>
  proportion * layoutService.size

const None = () => undefined

interface PaneViewOptions {
  element: HTMLElement
  minimumSize?: number
  maximumSize?: number
  priority?: LayoutPriority
  preferredSize?: number | string
  snap?: boolean
}

export class PaneView implements View {
  public minimumSize = 0
  public maximumSize: number = Number.POSITIVE_INFINITY

  readonly element: HTMLElement
  readonly priority?: LayoutPriority | undefined
  readonly snap: boolean

  private getPreferredSize: () => number | undefined

  get preferredSize(): number | undefined {
    return this.getPreferredSize()
  }

  set preferredSize(preferredSize: number | string | undefined) {
    if (typeof preferredSize === "number") {
      this.getPreferredSize = () => preferredSize
    } else if (typeof preferredSize === "string") {
      const trimmedPreferredSize = preferredSize.trim()

      if (trimmedPreferredSize.endsWith("%")) {
        const proportion = Number(trimmedPreferredSize.slice(0, -1)) / 100

        this.getPreferredSize = createProportionLayout(proportion, this.layoutService)
      } else if (trimmedPreferredSize.endsWith("px")) {
        const pixels = Number(trimmedPreferredSize.slice(0, -2)) / 100

        this.getPreferredSize = () => pixels
      } else if (typeof Number.parseFloat(trimmedPreferredSize) === "number") {
        const number = Number.parseFloat(trimmedPreferredSize)

        this.getPreferredSize = () => number
      } else {
        this.getPreferredSize = None
      }
    } else {
      this.getPreferredSize = None
    }
  }

  constructor(
    private readonly layoutService: LayoutService,
    options: PaneViewOptions,
  ) {
    this.element = options.element

    this.minimumSize = options.minimumSize ?? 30
    this.maximumSize = options.maximumSize ?? Number.POSITIVE_INFINITY

    if (typeof options.preferredSize === "number") {
      const { preferredSize } = options
      this.getPreferredSize = () => preferredSize
    } else if (typeof options.preferredSize === "string") {
      const preferredSize = options.preferredSize.trim()

      if (preferredSize.endsWith("%")) {
        const proportion = Number(preferredSize.slice(0, -1)) / 100

        this.getPreferredSize = createProportionLayout(proportion, layoutService)
      } else if (preferredSize.endsWith("px")) {
        const pixels = Number(preferredSize.slice(0, -2))

        this.getPreferredSize = () => pixels
      } else if (typeof Number.parseFloat(preferredSize) === "number") {
        const number = Number.parseFloat(preferredSize)
        this.getPreferredSize = () => number
      } else {
        this.getPreferredSize = None
      }
    } else {
      this.getPreferredSize = None
    }

    this.priority = options.priority ?? LayoutPriority.Normal

    this.snap = options.snap ?? false
  }

  layout(): void {}
}
