import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'

import { cn } from '@/lib/utils'

const timelineMarkerVariants = cva(
  'mt-1.5 flex size-2.5 shrink-0 rounded-full ring-4 ring-bg-base',
  {
    variants: {
      tone: {
        default: 'bg-border',
        primary: 'bg-primary',
        success: 'bg-success',
        warning: 'bg-warning',
        error: 'bg-error',
      },
    },
    defaultVariants: {
      tone: 'default',
    },
  }
)

export type TimelineProps = React.OlHTMLAttributes<HTMLOListElement>
export type TimelineItemProps = React.LiHTMLAttributes<HTMLLIElement>
export type TimelineContentProps = React.HTMLAttributes<HTMLDivElement>
export type TimelineTitleProps = React.HTMLAttributes<HTMLDivElement>
export type TimelineDescriptionProps = React.HTMLAttributes<HTMLDivElement>
export type TimelineTimeProps = React.TimeHTMLAttributes<HTMLTimeElement>
export type TimelineConnectorProps = React.HTMLAttributes<HTMLSpanElement>
export interface TimelineMarkerProps
  extends React.HTMLAttributes<HTMLSpanElement>,
    VariantProps<typeof timelineMarkerVariants> {}

function Timeline({ className, ...props }: TimelineProps) {
  return (
    <ol
      data-slot="timeline"
      className={cn('flex flex-col', className)}
      {...props}
    />
  )
}

function TimelineItem({ className, ...props }: TimelineItemProps) {
  return (
    <li
      data-slot="timeline-item"
      className={cn('group/timeline-item relative grid grid-cols-[auto_minmax(0,1fr)] gap-3 pb-6 last:pb-0', className)}
      {...props}
    />
  )
}

function TimelineMarker({ className, tone, ...props }: TimelineMarkerProps) {
  return (
    <span
      data-slot="timeline-marker"
      className={cn(timelineMarkerVariants({ tone }), className)}
      {...props}
    />
  )
}

function TimelineConnector({ className, ...props }: TimelineConnectorProps) {
  return (
    <span
      aria-hidden="true"
      data-slot="timeline-connector"
      className={cn(
        'absolute left-1.5 top-5 h-[calc(100%-1.25rem)] w-px bg-border-tertiary group-last/timeline-item:hidden',
        className
      )}
      {...props}
    />
  )
}

function TimelineContent({ className, ...props }: TimelineContentProps) {
  return (
    <div
      data-slot="timeline-content"
      className={cn('min-w-0', className)}
      {...props}
    />
  )
}

function TimelineTitle({ className, ...props }: TimelineTitleProps) {
  return (
    <div
      data-slot="timeline-title"
      className={cn('text-sm font-medium leading-5 text-text', className)}
      {...props}
    />
  )
}

function TimelineDescription({ className, ...props }: TimelineDescriptionProps) {
  return (
    <div
      data-slot="timeline-description"
      className={cn('mt-1 text-sm leading-6 text-text-tertiary', className)}
      {...props}
    />
  )
}

function TimelineTime({ className, ...props }: TimelineTimeProps) {
  return (
    <time
      data-slot="timeline-time"
      className={cn('mt-1 block text-xs leading-5 text-text-quaternary', className)}
      {...props}
    />
  )
}

export {
  Timeline,
  TimelineItem,
  TimelineMarker,
  TimelineConnector,
  TimelineContent,
  TimelineTitle,
  TimelineDescription,
  TimelineTime,
  timelineMarkerVariants,
}
