import { useEffect, useState } from 'react'
import { getTimeline, type Org, type TimelineEvent } from '../api/client'
import { useStages, type Stages } from '../codes/stage'
import StatusChip from '../ui/StatusChip'
import StatusGlyph, { type GlyphKind } from '../ui/StatusGlyph'

const dateFormatter = new Intl.DateTimeFormat('ko-KR', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  weekday: 'short',
})

const timeFormatter = new Intl.DateTimeFormat('ko-KR', {
  hour: '2-digit',
  minute: '2-digit',
  hour12: false,
})

function dateParts(at: number): { year: string; month: string; day: string; weekday: string } {
  const parts = dateFormatter.formatToParts(new Date(at))
  const get = (type: string) => parts.find((p) => p.type === type)?.value ?? ''
  return { year: get('year'), month: get('month'), day: get('day'), weekday: get('weekday') }
}

function dateKey(at: number): string {
  const { year, month, day } = dateParts(at)
  return `${year}-${month}-${day}`
}

function dateHeader(at: number): string {
  const { year, month, day, weekday } = dateParts(at)
  return `${year}-${month}-${day} (${weekday})`
}

function formatTime(at: number): string {
  return timeFormatter.format(new Date(at))
}

interface EventGroup {
  key: string
  header: string
  items: TimelineEvent[]
}

function groupByDate(events: TimelineEvent[]): EventGroup[] {
  const groups: EventGroup[] = []
  for (const event of events) {
    const key = dateKey(event.at)
    const current = groups[groups.length - 1]
    if (current && current.key === key) {
      current.items.push(event)
    } else {
      groups.push({ key, header: dateHeader(event.at), items: [event] })
    }
  }
  return groups
}

/**
 * 이벤트 종류별 색·글리프. 이모지를 쓰지 않는 이유는 두 가지다. 하나는 OS마다 그림이 달라
 * 같은 화면이 사람마다 다르게 보인다는 것, 다른 하나는 둥근 이모지가 이 화면의 각진 상태
 * 태그와 어울리지 않는다는 것이다. 대신 같은 글리프 세트를 쓴다.
 */
const EVENT_META: Record<
  TimelineEvent['type'],
  { dot: string; glyph: GlyphKind; badge: string; tone: string }
> = {
  STAGE: { dot: 'bg-blue-600', glyph: 'progress', badge: '단계 변경', tone: 'blue' },
  FILE: { dot: 'bg-amber-500', glyph: 'document', badge: '자료 등록', tone: 'amber' },
  MEMO: { dot: 'bg-emerald-600', glyph: 'note', badge: '업무메모', tone: 'emerald' },
}

/** STAGE 이벤트의 title(단계 번호 문자열)을 "5. 법률검토(권리확인) 진행" 형태로 바꾼다. */
function stageEventText(title: string, stages: Stages): string {
  const n = Number(title)
  if (!Number.isInteger(n)) {
    return `${title} 단계로 진행`
  }
  return `${n}. ${stages.label(n)} 단계로 진행`
}

function EventBody({ event }: { event: TimelineEvent }) {
  const stages = useStages()
  if (event.type === 'STAGE') {
    return <p className="text-sm font-medium text-gray-900">{stageEventText(event.title, stages)}</p>
  }
  if (event.type === 'FILE') {
    return (
      <p className="text-sm text-gray-900">
        <span className="font-semibold">{event.title}</span>
        {event.detail && <span className="ml-2 text-xs text-gray-400">{event.detail}</span>}
      </p>
    )
  }
  return (
    <p className="text-sm text-gray-900">
      <span className="font-semibold">{event.title}</span>
      {event.detail && <span className="ml-2 text-xs text-gray-500">{event.detail}</span>}
    </p>
  )
}

/** 기관관리 상세의 타임라인 탭. 단계 변경 이력·업무메모·채널 첨부파일 등록을 하나의 시간순
 * 목록으로 합쳐 보여준다(조회는 GET /api/orgs/{id}/timeline 한 번뿐이고 폴링은 없다). */
export default function Timeline({ org }: { org: Org }) {
  const [events, setEvents] = useState<TimelineEvent[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [reloadKey, setReloadKey] = useState(0)

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    setError(null)

    getTimeline(org.id)
      .then((data) => {
        if (!cancelled) {
          setEvents(data)
        }
      })
      .catch((e: Error) => {
        if (!cancelled) {
          setError(e.message)
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoading(false)
        }
      })

    return () => {
      cancelled = true
    }
  }, [org.id, reloadKey])

  const groups = groupByDate(events)

  return (
    <div className="p-4">
      <div className="flex justify-end">
        <button
          type="button"
          onClick={() => setReloadKey((k) => k + 1)}
          className="rounded-md border border-gray-300 px-3 py-1 text-xs text-gray-600 hover:bg-gray-50"
        >
          새로고침
        </button>
      </div>

      {loading && <p className="py-6 text-center text-sm text-gray-400">불러오는 중…</p>}
      {!loading && error && <p className="py-4 text-center text-sm text-red-600">{error}</p>}
      {!loading && !error && events.length === 0 && (
        <p className="py-10 text-center text-sm text-gray-300">
          아직 기록이 없습니다. 채널을 만들고 업무를 진행하면 여기에 쌓입니다.
        </p>
      )}

      {!loading && !error && events.length > 0 && (
        <div className="mt-3 space-y-6">
          {groups.map((group) => (
            <section key={group.key}>
              <h3 className="text-xs font-semibold text-gray-500">{group.header}</h3>
              <ol className="mt-2 space-y-4 border-l-2 border-gray-200 pl-5">
                {group.items.map((event, i) => {
                  const meta = EVENT_META[event.type]
                  return (
                    <li key={`${group.key}-${i}`} className="relative">
                      <span
                        aria-hidden="true"
                        className={`absolute -left-[1.6rem] flex h-[18px] w-[18px] items-center justify-center text-white ${meta.dot}`}
                      >
                        <StatusGlyph kind={meta.glyph} />
                      </span>
                      <div className="flex items-baseline gap-2">
                        <span className="text-xs tabular-nums text-gray-400">{formatTime(event.at)}</span>
                        <StatusChip label={meta.badge} tone={meta.tone} glyph={meta.glyph} />
                      </div>
                      <div className="mt-1">
                        <EventBody event={event} />
                      </div>
                    </li>
                  )
                })}
              </ol>
            </section>
          ))}
        </div>
      )}
    </div>
  )
}
