'use client'

import classNames from 'classnames'
import {
  ForwardedRef,
  forwardRef,
  HTMLAttributes,
  ReactNode,
  Ref,
  useCallback,
  useEffect,
  useRef,
} from 'react'

import { PktButton } from '../button/Button'

export interface IPktModal
  extends Omit<HTMLAttributes<HTMLDialogElement>, 'onClose' | 'open'> {
  open?: boolean
  headingText?: string
  hideCloseButton?: boolean
  closeOnBackdropClick?: boolean
  size?: 'small' | 'medium' | 'large' | 'fit-content'
  removePadding?: boolean
  closeButtonSkin?: 'blue' | 'yellow-filled'
  variant?: 'dialog' | 'drawer'
  drawerPosition?: 'left' | 'right'
  transparentBackdrop?: boolean
  onClose?: () => void
  children?: ReactNode
  ref?: Ref<HTMLDialogElement>
}

export const PktModal = forwardRef(
  (
    {
      children,
      className,
      open = false,
      headingText = '',
      hideCloseButton = false,
      closeOnBackdropClick = false,
      size = 'medium',
      removePadding = false,
      closeButtonSkin = 'blue',
      variant = 'dialog',
      drawerPosition = 'right',
      transparentBackdrop = false,
      onClose,
      ...props
    }: IPktModal,
    ref: ForwardedRef<HTMLDialogElement>,
  ) => {
    const internalRef = useRef<HTMLDialogElement>(null)
    const dialogRef = (ref as React.RefObject<HTMLDialogElement>) || internalRef

    const close = useCallback(() => {
      if (!dialogRef.current?.open) return
      dialogRef.current?.close()
      onClose?.()
    }, [dialogRef, onClose])

    // Synkroniser scroll-lock med dialogens faktiske åpen/lukket-tilstand
    useEffect(() => {
      const dialog = dialogRef.current
      if (!dialog) return

      const observer = new MutationObserver(() => {
        if (dialog.open) {
          document.body.classList.add('pkt-modal--open')
        } else {
          document.body.classList.remove('pkt-modal--open')
        }
      })
      observer.observe(dialog, { attributes: true, attributeFilter: ['open'] })
      return () => observer.disconnect()
    }, [dialogRef])

    // Deklarativ åpne/lukke via open-prop
    useEffect(() => {
      if (open) {
        if (!dialogRef.current?.open) {
          dialogRef.current?.showModal()
        }
      } else {
        if (dialogRef.current?.open) {
          dialogRef.current?.close()
        }
      }
    }, [open, dialogRef])

    const handleBackdropClick = useCallback(
      (event: React.MouseEvent<HTMLDialogElement>) => {
        if (closeOnBackdropClick && event.target === dialogRef.current) {
          close()
        }
      },
      [closeOnBackdropClick, dialogRef, close],
    )

    const handleNativeClose = useCallback(() => {
      onClose?.()
    }, [onClose])

    const isCloseButtonSkinDefault = closeButtonSkin === 'blue'

    const classes = classNames(
      {
        'pkt-modal': true,
        'pkt-modal--removePadding': removePadding,
        'pkt-modal--noHeadingText': !headingText,
        'pkt-modal--noShadow': closeButtonSkin === 'yellow-filled',
        'pkt-modal--transparentBackdrop': transparentBackdrop,
        [`pkt-modal--${size}`]: size,
        [`pkt-modal__${variant}`]: variant,
        [`pkt-modal__drawer--${drawerPosition}`]: variant === 'drawer',
      },
      className,
    )

    return (
      <dialog
        {...props}
        className={classes}
        ref={dialogRef}
        aria-labelledby={headingText ? 'pkt-modal__headingText' : undefined}
        aria-describedby="pkt-modal__content"
        onClick={handleBackdropClick}
        onClose={handleNativeClose}
      >
        <div className="pkt-modal__wrapper">
          {(headingText || !hideCloseButton) && (
            <div className="pkt-modal__header">
              <div className="pkt-modal__header-background" />
              {headingText ? (
                <h1 id="pkt-modal__headingText" className="pkt-modal__headingText pkt-txt-24">
                  {headingText}
                </h1>
              ) : (
                <div className="pkt-modal__headingText" />
              )}
              {!hideCloseButton ? (
                <div
                  className={classNames('pkt-modal__closeButton', {
                    [`pkt-modal__closeButton--${closeButtonSkin}`]: true,
                  })}
                >
                  <PktButton
                    onClick={close}
                    aria-label="close"
                    iconName="close"
                    variant="icon-only"
                    size="medium"
                    skin={isCloseButtonSkinDefault ? 'tertiary' : 'primary'}
                  >
                    Lukk
                  </PktButton>
                </div>
              ) : (
                <div className="pkt-modal__noCloseButton" />
              )}
            </div>
          )}
          <div className="pkt-modal__container">
            <div id="pkt-modal__content" className="pkt-modal__content pkt-txt-18-light">
              {children}
            </div>
          </div>
        </div>
      </dialog>
    )
  },
)

PktModal.displayName = 'PktModal'
