export default class Dom {
  els: Element[] = []

  constructor(arg?: string | (() => void) | Element) {
    if (typeof arg === 'string') {
      return this.find(arg)
    }
    if (typeof arg === 'object' && arg instanceof Element) {
      this.els.push(arg)
    }
    if (typeof arg === 'function') {
      document.addEventListener('DOMContentLoaded', arg)
    }
    return this
  }

  replaceClass(class1: string, class2: string) {
    this.els.forEach((el) => {
      el.classList.replace(class1, class2)
    })
    return this
  }

  find(tag: string) {
    let els: Element[] = []
    if (this.els.length) {
      els = Array.from(this.els[0].querySelectorAll(tag))
    } else {
      els = Array.from(document.querySelectorAll(tag))
    }
    if (els.length) {
      this.els = els
    }
    return this
  }

  create(template: string) {
    const tempNode = document.createElement('div')
    tempNode.innerHTML = template.trim()
    const first = tempNode.firstElementChild
    if (first) this.els = [first]
    return this
  }

  append(that: Dom) {
    this.els.forEach((el) => {
      that.els.forEach((child) => el.appendChild(child))
    })
    return this
  }

  on(eventName: string, fn: (e: Event) => void) {
    eventName.split(' ').forEach((event) => {
      this.els.forEach((el) => el.addEventListener(event, fn))
    })
    return this
  }

  remove() {
    this.els.forEach((el) => {
      el.parentNode?.removeChild(el)
    })
    return this
  }
}

export function _css(el: HTMLElement, key: string, value?: string | number) {
  const reg = /^-?\d+.?\d*(px|pt|em|rem|vw|vh|%|rpx|ms)$/i
  if (value === undefined) {
    let val: string | null = null
    if ('getComputedStyle' in window) {
      val = window.getComputedStyle(el, null)[key as keyof CSSStyleDeclaration] as string
    } else {
      val = (el as HTMLElement & { currentStyle?: Record<string, string> }).currentStyle?.[key] ?? null
    }
    return reg.test(val as string) ? parseFloat(val as string) : val
  }
  if (
    ['top', 'left', 'bottom', 'right', 'width', 'height', 'font-size', 'margin', 'padding'].includes(
      key,
    )
  ) {
    if (!reg.test(String(value))) {
      if (!String(value).includes('calc')) {
        value = `${value}px`
      }
    }
  }
  if (key === 'transform') {
    const style = el.style as CSSStyleDeclaration & Record<string, string>
    style.webkitTransform =
      style.MsTransform =
      style.msTransform =
      style.MozTransform =
      style.OTransform =
      style.transform =
        String(value)
  } else {
    ;(el.style as CSSStyleDeclaration & Record<string, string>)[key] = String(value)
  }
}
