import {
  CheckCircleOutlined,
  ClockCircleOutlined,
  ExclamationCircleOutlined,
  PauseCircleOutlined,
  PlayCircleOutlined,
} from '@ant-design/icons';
import { Empty } from 'antd';
import type { CSSProperties, ReactNode } from 'react';
import './TimelinePanelUI.css';

export type TimelineEventStatus = 'completed' | 'inProgress' | 'warning' | 'blocked' | 'planned';

export type TimelinePanelEvent = {
  id: string;
  title: ReactNode;
  timeLabel: ReactNode;
  description?: ReactNode;
  status?: TimelineEventStatus;
  badgeLabel?: ReactNode;
  meta?: ReactNode;
  icon?: ReactNode;
};

export type TimelinePanelUIProps = {
  eyebrow?: ReactNode;
  title?: ReactNode;
  description?: ReactNode;
  events: TimelinePanelEvent[];
  compact?: boolean;
  className?: string;
  style?: CSSProperties;
  emptyTitle?: ReactNode;
  emptyDescription?: ReactNode;
};

type TimelineAppearance = {
  accent: string;
  accentSoft: string;
  accentBorder: string;
  cardBackground: string;
  badgeLabel: string;
  icon: ReactNode;
};

const appearanceMap: Record<TimelineEventStatus, TimelineAppearance> = {
  completed: {
    accent: '#15803d',
    accentSoft: 'rgba(34, 197, 94, 0.14)',
    accentBorder: 'rgba(34, 197, 94, 0.2)',
    cardBackground: 'linear-gradient(180deg, rgba(240, 253, 244, 0.98) 0%, rgba(220, 252, 231, 0.82) 100%)',
    badgeLabel: '완료',
    icon: <CheckCircleOutlined />,
  },
  inProgress: {
    accent: '#2563eb',
    accentSoft: 'rgba(37, 99, 235, 0.14)',
    accentBorder: 'rgba(59, 130, 246, 0.22)',
    cardBackground: 'linear-gradient(180deg, rgba(239, 246, 255, 0.98) 0%, rgba(219, 234, 254, 0.84) 100%)',
    badgeLabel: '진행중',
    icon: <PlayCircleOutlined />,
  },
  warning: {
    accent: '#c2410c',
    accentSoft: 'rgba(249, 115, 22, 0.14)',
    accentBorder: 'rgba(249, 115, 22, 0.22)',
    cardBackground: 'linear-gradient(180deg, rgba(255, 247, 237, 0.98) 0%, rgba(254, 215, 170, 0.54) 100%)',
    badgeLabel: '주의',
    icon: <ExclamationCircleOutlined />,
  },
  blocked: {
    accent: '#b91c1c',
    accentSoft: 'rgba(239, 68, 68, 0.14)',
    accentBorder: 'rgba(239, 68, 68, 0.2)',
    cardBackground: 'linear-gradient(180deg, rgba(254, 242, 242, 0.98) 0%, rgba(254, 226, 226, 0.82) 100%)',
    badgeLabel: '차단',
    icon: <PauseCircleOutlined />,
  },
  planned: {
    accent: '#475569',
    accentSoft: 'rgba(148, 163, 184, 0.16)',
    accentBorder: 'rgba(148, 163, 184, 0.22)',
    cardBackground: 'linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(241, 245, 249, 0.92) 100%)',
    badgeLabel: '예정',
    icon: <ClockCircleOutlined />,
  },
};

function joinClassNames(...classNames: Array<string | false | null | undefined>) {
  return classNames.filter(Boolean).join(' ');
}

function buildItemStyle(appearance: TimelineAppearance): CSSProperties {
  return {
    '--timeline-panel-accent': appearance.accent,
    '--timeline-panel-accent-soft': appearance.accentSoft,
    '--timeline-panel-accent-border': appearance.accentBorder,
    '--timeline-panel-card-background': appearance.cardBackground,
  } as CSSProperties;
}

export function TimelinePanelUI({
  eyebrow = 'Timeline Panel',
  title = '운영 타임라인',
  description,
  events,
  compact = false,
  className,
  style,
  emptyTitle = '표시할 이벤트가 없습니다.',
  emptyDescription = '조건에 맞는 이벤트가 쌓이면 이 영역에 시간순으로 표시됩니다.',
}: TimelinePanelUIProps) {
  return (
    <section
      className={joinClassNames(
        'timeline-panel',
        compact && 'timeline-panel--compact',
        className,
      )}
      style={style}
    >
      {(eyebrow || title || description) ? (
        <header className="timeline-panel__header">
          {eyebrow ? <span className="timeline-panel__eyebrow">{eyebrow}</span> : null}
          {title ? <h3 className="timeline-panel__title">{title}</h3> : null}
          {description ? <p className="timeline-panel__description">{description}</p> : null}
        </header>
      ) : null}

      {events.length > 0 ? (
        <div className="timeline-panel__list" role="list" aria-label="timeline-events">
          {events.map((event) => {
            const appearance = appearanceMap[event.status ?? 'planned'];
            const badgeLabel = event.badgeLabel ?? appearance.badgeLabel;
            const icon = event.icon ?? appearance.icon;

            return (
              <article
                key={event.id}
                className="timeline-panel__item"
                style={buildItemStyle(appearance)}
                role="listitem"
              >
                <div className="timeline-panel__time">{event.timeLabel}</div>
                <div className="timeline-panel__track" aria-hidden="true">
                  <span className="timeline-panel__icon">{icon}</span>
                </div>
                <div className="timeline-panel__card">
                  <div className="timeline-panel__row">
                    <div className="timeline-panel__title-wrap">
                      <div className="timeline-panel__item-title">{event.title}</div>
                      {event.meta ? <div className="timeline-panel__item-meta">{event.meta}</div> : null}
                    </div>
                    <span className="timeline-panel__badge">
                      {icon}
                      {badgeLabel}
                    </span>
                  </div>
                  {event.description ? (
                    <p className="timeline-panel__description-text">{event.description}</p>
                  ) : null}
                </div>
              </article>
            );
          })}
        </div>
      ) : (
        <div className="timeline-panel__empty">
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description={
              <div>
                <strong>{emptyTitle}</strong>
                <div>{emptyDescription}</div>
              </div>
            }
          />
        </div>
      )}
    </section>
  );
}
