'use client'

import classNames from 'classnames'
import { forwardRef, HTMLAttributes, Ref, useEffect, useMemo, useRef, useState } from 'react'
import type {
  TAriaLive,
  TProgressbarRole,
  TProgressbarSkin,
  TProgressbarStatusPlacement,
  TProgressbarStatusType,
  TProgressbarTitlePosition,
} from 'shared-types'
import { uuidish } from 'shared-utils/utils'

export type { TProgressbarRole, TProgressbarSkin, TProgressbarStatusPlacement, TProgressbarStatusType, TProgressbarTitlePosition }

export interface IPktProgressbar extends Omit<HTMLAttributes<HTMLDivElement>, 'role' | 'title'> {
  ariaLabel?: string | null
  ariaLabelledby?: string | null
  ariaLive?: TAriaLive
  ariaValueText?: string | null
  id?: string
  role?: TProgressbarRole
  skin?: TProgressbarSkin
  statusPlacement?: TProgressbarStatusPlacement
  statusType?: TProgressbarStatusType
  title?: string | null
  titlePosition?: TProgressbarTitlePosition
  valueCurrent: number
  valueMax?: number
  valueMin?: number
  ref?: Ref<HTMLDivElement>
}

export const PktProgressbar = forwardRef<HTMLDivElement, IPktProgressbar>(
  (
    {
      ariaLabel,
      ariaLabelledby,
      ariaLive = 'polite',
      ariaValueText,
      id,
      role = 'progressbar',
      skin = 'dark-blue',
      statusPlacement = 'following',
      statusType = 'none',
      title,
      titlePosition = 'left',
      valueCurrent = 0,
      valueMax = 100,
      valueMin = 0,
      className,
      ...props
    },
    ref,
  ) => {
    const generatedId = useMemo(() => uuidish(), [])
    const progressbarId = id || generatedId

    const labelRef = useRef<HTMLSpanElement>(null)
    const [labelWidth, setLabelWidth] = useState(0)

    useEffect(() => {
      if (labelRef.current) {
        setLabelWidth(labelRef.current.getBoundingClientRect().width || 0)
      }
    }, [valueCurrent])

    const totalSteps = valueMax - valueMin
    const currentPercentage =
      statusType === 'fraction'
        ? Math.round((valueCurrent / totalSteps) * 100)
        : Math.round(((valueCurrent - valueMin) / totalSteps) * 100)

    const formattedTitle = `${valueCurrent} av ${totalSteps}`

    const computedAriaValueText =
      statusType === 'fraction' && !ariaValueText
        ? `${valueCurrent} av ${valueMax - valueMin}`
        : ariaValueText || undefined

    const computedAriaLabelledby = !ariaLabel
      ? ariaLabelledby || `${progressbarId}-title`
      : undefined

    return (
      <div
        ref={ref}
        id={progressbarId}
        role={role}
        aria-live={ariaLive}
        aria-atomic="true"
        aria-valuenow={valueCurrent}
        aria-valuemin={valueMin}
        aria-valuemax={valueMax}
        aria-valuetext={computedAriaValueText}
        aria-label={ariaLabel || undefined}
        aria-labelledby={computedAriaLabelledby}
        className={classNames('pkt-progressbar', className)}
        {...props}
      >
        <div
          className="pkt-progressbar__container"
          style={{
            '--pkt-progress-label-width': `${labelWidth}px`,
            '--pkt-progress-width': `${currentPercentage}%`,
          } as React.CSSProperties}
        >
          {title && (
            <p
              id={`${progressbarId}-title`}
              className={classNames('pkt-progressbar__title', {
                'pkt-progressbar__title-center': titlePosition === 'center',
              })}
            >
              {title}
            </p>
          )}

          <div className="pkt-progressbar__bar-wrapper">
            <div className={classNames('pkt-progressbar__bar', `pkt-progressbar__bar--${skin}`)} />
          </div>

          {statusType !== 'none' && (
            <div
              className={classNames('pkt-progressbar__status', {
                'pkt-progressbar__status--center': statusPlacement === 'center',
              })}
            >
              <span
                ref={labelRef}
                className={classNames({
                  'pkt-progressbar__status-placement--following': statusPlacement === 'following',
                  'pkt-progressbar__status-placement--center': statusPlacement === 'center',
                  'pkt-progressbar__status-placement--left': statusPlacement === 'left',
                })}
              >
                {statusType === 'percentage' ? `${currentPercentage}%` : formattedTitle}
              </span>
            </div>
          )}
        </div>
      </div>
    )
  },
)

PktProgressbar.displayName = 'PktProgressbar'
