/**
 * ScrollArea - Styled scrollable container component
 * @countermeasure/web-components/primitives/scroll-area
 */

import { resolveContainer } from '../utils'

export type ScrollOrientation = 'vertical' | 'horizontal' | 'both'

export interface ScrollAreaConfig {
  container?: HTMLElement | string
  maxHeight?: string
  orientation?: ScrollOrientation
  className?: string
}

export class ScrollArea {
  public readonly el: HTMLDivElement

  private readonly viewportEl: HTMLDivElement

  constructor(config: ScrollAreaConfig) {
    const orientation = config.orientation ?? 'vertical'

    // Create the outer wrapper
    this.el = document.createElement('div')
    this.el.className = 'cmm-scroll-area'

    if (config.className) {
      this.el.classList.add(config.className)
    }

    // Create the scrollable viewport
    this.viewportEl = document.createElement('div')
    this.viewportEl.className = `cmm-scroll-area__viewport cmm-scroll-area__viewport--${orientation}`

    if (config.maxHeight !== undefined) {
      this.viewportEl.style.maxHeight = config.maxHeight
    }

    this.el.appendChild(this.viewportEl)

    // Mount if container provided
    if (config.container !== undefined) {
      const parent = resolveContainer(config.container)
      parent.appendChild(this.el)
    }
  }

  /** Returns the viewport element for appending content */
  getViewport(): HTMLDivElement {
    return this.viewportEl
  }

  /** Scroll to a specific position */
  scrollTo(top: number, left?: number): void {
    this.viewportEl.scrollTop = top
    if (left !== undefined) {
      this.viewportEl.scrollLeft = left
    }
  }

  /** Scroll to the top of the viewport */
  scrollToTop(): void {
    this.viewportEl.scrollTop = 0
  }

  /** Scroll to the bottom of the viewport */
  scrollToBottom(): void {
    this.viewportEl.scrollTop = this.viewportEl.scrollHeight
  }

  /** Remove from the DOM */
  destroy(): void {
    this.el.remove()
  }
}
