---
import type { HTMLAttributes } from 'astro/types'
import BadgeState from '../BadgeState/index.astro'
import Divider from '../Divider/index.astro'
import LinkButton from '../LinkButton/index.astro'
import Skeleton from '../Skeleton/index.astro'
import Switch from '../Switch/index.astro'
import RadioField from '../form/Radio/Field/index.astro'
import IconCheck from '../icons/default/IconCheck.astro'
import IconChevronRight from '../icons/default/IconChevronRight.astro'
import '../../dist/components/ListRow/styles.css'

export type ListRowContent = 'upward' | 'downward'
type BadgeStatus = 'info' | 'success' | 'error' | 'warning' | 'support' | 'neutral'

export type ListRowTrackline = {
  /** Number (etapa numerada), Check (etapa concluída) ou Badge State (etapa com status). Figma: Track line. */
  marker?: 'number' | 'check' | 'badge'
  /** Número da etapa, no marcador Number. */
  number?: number
  /** Status do BadgeState, no marcador Badge State. */
  status?: BadgeStatus
  /** Última etapa: sem o traço (Dash) que liga à próxima. */
  last?: boolean
}

export type ListRowLink = {
  label: string
  href?: string
  target?: string
}

export type ListRowBadge = {
  status: BadgeStatus
  text: string
  variant?: 'regular' | 'strong'
}

export type ListRowRadio = {
  name?: string
  value?: string
  checked?: boolean
  disabled?: boolean
  id?: string
}

export type ListRowToggle = {
  name?: string
  value?: string
  checked?: boolean
  disabled?: boolean
  id?: string
  'aria-label'?: string
}

/**
 * Same props and markup as the React `ListRow`. Differences: `icon` and
 * `partner` are the `icon` and `partner` named slots; `radio` and `toggle`
 * are the initial attributes of the native inputs (listen to their `change`);
 * the link has no `onClick` (it carries `data-au-list-row="link"`) and the
 * row has no `onClick` (an `href` makes the root an `<a>`; otherwise hook a
 * `data-*`). Every other HTML attribute lands on the root.
 */
export type Props = Omit<HTMLAttributes<'div'>, 'content'> & {
  label: string
  /** Segunda linha (Multiple line no Figma). Sem ela a linha tem 56px; com ela, 80px. */
  description?: string
  /** Para cima (label em destaque, padrão) ou para baixo (label pequeno em cima, valor em destaque embaixo). Figma: Downward Content. */
  content?: ListRowContent
  /** Leading com seleção: o `Radio.Field` da lib, sem label (a linha é o label). */
  radio?: ListRowRadio
  /** Leading com trackline: marcador ligado à próxima etapa por um traço. */
  trackline?: ListRowTrackline
  /** Trailing com conteúdo secundário: rótulo alinhado à direita. */
  secondaryLabel?: string
  /** Segunda linha do conteúdo secundário. */
  secondaryDescription?: string
  /** Trailing com link: um `LinkButton` small. */
  link?: ListRowLink
  /** Trailing com badge: um `BadgeState`. */
  badge?: ListRowBadge
  /** Trailing com ícone: o chevron que indica que a linha leva a outra tela. */
  chevron?: boolean
  /** Trailing com toggle: o `Switch` da lib, sem label (passe `aria-label`). */
  toggle?: ListRowToggle
  /** Estado de carregamento, com o mesmo leading e o mesmo número de linhas do conteúdo final. Figma: Skeleton. */
  skeleton?: boolean
  /** A linha inteira leva a outra tela: a raiz vira um `<a>` (`as` é ignorado). Ignorado com `skeleton`. */
  href?: string
  target?: string
  /** Tag da raiz. */
  as?: 'div' | 'li'
}

const {
  label,
  description,
  content = 'upward',
  radio,
  trackline,
  secondaryLabel,
  secondaryDescription,
  link,
  badge,
  chevron = false,
  toggle,
  skeleton = false,
  href,
  target,
  as = 'div',
  class: className,
  ...rest
} = Astro.props

const hasIcon = Astro.slots.has('icon')
const hasPartner = Astro.slots.has('partner')
const leading = trackline ? 'trackline' : radio ? 'radio' : hasPartner ? 'partner' : hasIcon ? 'icon' : null
const hasSecondary = !!secondaryLabel || !!secondaryDescription
const hasTrailing = hasSecondary || !!link || !!badge || chevron || !!toggle
const twoLines = !!description
// The skeleton is `aria-hidden`, so it is never a link: a focusable element
// inside a hidden tree fails WCAG 4.1.2. Same rule as the React one.
const clickable = !!href && !skeleton
const marker = trackline?.marker ?? 'number'

const Tag = clickable ? 'a' : as
---

<Tag
  class:list={[
    'au-list-row',
    `au-list-row--content-${content}`,
    twoLines && 'au-list-row--two-lines',
    leading && `au-list-row--leading-${leading}`,
    hasTrailing && 'au-list-row--with-trailing',
    skeleton && 'au-list-row--skeleton',
    clickable && 'au-list-row--clickable',
    trackline?.last && 'au-list-row--trackline-last',
    className,
  ]}
  href={clickable ? href : undefined}
  target={clickable ? target : undefined}
  aria-busy={skeleton ? 'true' : undefined}
  aria-hidden={skeleton ? 'true' : undefined}
  {...rest}>
  <Divider width="small" />
  <div class="au-list-row__content">
    {
      leading && (
        <div class={`au-list-row__leading au-list-row__leading--${leading}`}>
          {skeleton ? (
            <Fragment>
              {leading === 'icon' && <Skeleton width={20} height={20} />}
              {leading === 'partner' && <Skeleton shape="square" width={40} height={40} />}
              {leading === 'radio' && <Skeleton shape="circle" width={20} height={20} />}
              {leading === 'trackline' && <Skeleton shape="circle" width={24} height={24} />}
            </Fragment>
          ) : (
            <Fragment>
              {leading === 'icon' && (
                <span class="au-list-row__icon" aria-hidden="true">
                  <slot name="icon" />
                </span>
              )}
              {leading === 'partner' && (
                <span class="au-list-row__partner">
                  <slot name="partner" />
                </span>
              )}
              {leading === 'radio' && <RadioField {...radio} />}
              {leading === 'trackline' && (
                <span class="au-list-row__trackline">
                  <span class={`au-list-row__marker au-list-row__marker--${marker}`}>
                    {marker === 'number' && trackline!.number}
                    {marker === 'check' && <IconCheck size="small" />}
                    {marker === 'badge' && <BadgeState status={trackline!.status ?? 'info'} iconOnly />}
                  </span>
                  {!trackline!.last && <span class="au-list-row__dash" aria-hidden="true" />}
                </span>
              )}
            </Fragment>
          )}
        </div>
      )
    }
    <div class="au-list-row__main">
      {
        skeleton ? (
          <Fragment>
            {twoLines && <Skeleton width={104} height={22} />}
            <Skeleton width={160} height={22} />
          </Fragment>
        ) : (
          <Fragment>
            <span class="au-list-row__label">{label}</span>
            {description && <span class="au-list-row__description">{description}</span>}
          </Fragment>
        )
      }
    </div>
    {
      hasTrailing && !skeleton && (
        <div class="au-list-row__trailing">
          <Fragment>
            {hasSecondary && (
              <span class="au-list-row__secondary">
                {secondaryLabel && <span class="au-list-row__secondary-label">{secondaryLabel}</span>}
                {secondaryDescription && (
                  <span class="au-list-row__secondary-description">{secondaryDescription}</span>
                )}
              </span>
            )}
            {link && (
              <LinkButton
                as={link.href ? 'a' : 'button'}
                href={link.href}
                target={link.target}
                size="small"
                class="au-list-row__link"
                data-au-list-row="link">
                {link.label}
              </LinkButton>
            )}
            {badge && <BadgeState status={badge.status} text={badge.text} variant={badge.variant} />}
            {toggle && <Switch {...toggle} />}
            {chevron && (
              <span class="au-list-row__chevron" aria-hidden="true">
                <IconChevronRight />
              </span>
            )}
          </Fragment>
        </div>
      )
    }
  </div>
  <Divider width="small" />
</Tag>
