'use client'

// 2026-04-26 P2.5 by Claude — AIOps Timeline
// ============================================================
// AiopsTimelinePanel — 全景時序面板主體
// 包含 header / filter / 事件列表 / per-incident timeline
// ============================================================

import { useState, useMemo, useCallback } from 'react'
import { useTranslations } from 'next-intl'
import { useQuery } from '@tanstack/react-query'
import {
  GitBranch,
  RefreshCw,
  AlertCircle,
  InboxIcon,
  ChevronDown,
  ChevronUp,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { TimelineFilter } from './TimelineFilter'
import { TimelineStage } from './TimelineStage'
import { SAMPLE_TIMELINE_INCIDENTS } from './sample-incidents'
import type {
  TimelineIncident,
  TimelineFilterState,
  StageType,
} from './types'

// ============================================================
// Constants
// ============================================================

// 保留既有環境變數相容；UI 以「範例資料」呈現，避免誤讀為正式證據。
const USE_SAMPLE_TIMELINE = process.env.NEXT_PUBLIC_AIOPS_TIMELINE_MOCK === 'true'
const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? ''

const STAGE_ORDER: StageType[] = ['alert', 'diagnose', 'decide', 'execute', 'verify', 'learn']

const SEVERITY_CONFIG = {
  P0: { bg: 'bg-status-critical/10', text: 'text-status-critical', border: 'border-status-critical/20' },
  P1: { bg: 'bg-status-warning/10',  text: 'text-status-warning',  border: 'border-status-warning/20' },
  P2: { bg: 'bg-claw-blue/10',       text: 'text-claw-blue',       border: 'border-claw-blue/20' },
  P3: { bg: 'bg-nothing-gray-100',   text: 'text-nothing-gray-500', border: 'border-nothing-gray-200' },
}

// ============================================================
// API fetch
// ============================================================

async function fetchTimeline(incidentId: string): Promise<TimelineIncident[]> {
  const params = new URLSearchParams()
  if (incidentId) params.set('incident_id', incidentId)
  params.set('limit', '20')

  const res = await fetch(`${API_BASE}/api/v1/aiops/timeline?${params.toString()}`)
  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  const json = await res.json()
  return json.data ?? json
}

// ============================================================
// IncidentCard — 單筆事件展開區塊
// ============================================================

interface IncidentCardProps {
  incident: TimelineIncident
  index: number
}

function IncidentCard({ incident, index }: IncidentCardProps) {
  const t = useTranslations('aiopsTimeline')
  const [expanded, setExpanded] = useState(true)

  const sev = incident.severity
  const sevCfg = SEVERITY_CONFIG[sev] ?? SEVERITY_CONFIG.P3

  const successCount = incident.stages.filter(s => s.status === 'success').length
  const totalStages = incident.stages.length

  // 計算持續時間
  const durationLabel = useMemo(() => {
    if (!incident.resolved_at) return t('incident.in_progress')
    const ms = new Date(incident.resolved_at).getTime() - new Date(incident.started_at).getTime()
    if (ms < 60000) return `${Math.round(ms / 1000)}s`
    return `${Math.round(ms / 60000)}m ${Math.round((ms % 60000) / 1000)}s`
  }, [incident, t])

  // 格式化日期時間
  const startedLabel = useMemo(() => {
    try {
      return new Date(incident.started_at).toLocaleString('zh-TW', {
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false,
      })
    } catch {
      return incident.started_at
    }
  }, [incident.started_at])

  // 按 STAGE_ORDER 排序，補齊缺失階段
  const sortedStages = useMemo(() => {
    return STAGE_ORDER.map(stageType => {
      const entry = incident.stages.find(s => s.stage === stageType)
      return entry ?? null
    })
  }, [incident.stages])

  return (
    <article
      className="animate-slide-in-up"
      style={{ animationDelay: `${index * 80}ms`, animationFillMode: 'both' }}
      aria-label={incident.title}
    >
      {/* Incident header card */}
      <div
        className="bg-white rounded-card border border-nothing-gray-200 shadow-card mb-3 overflow-hidden"
      >
        {/* Severity stripe */}
        <div className={cn('h-1', {
          'bg-status-critical': sev === 'P0',
          'bg-status-warning': sev === 'P1',
          'bg-claw-blue': sev === 'P2',
          'bg-nothing-gray-300': sev === 'P3',
        })} />

        {/* Incident summary */}
        <div
          className="flex items-start gap-3 p-4 cursor-pointer hover:bg-nothing-gray-50 transition-colors"
          onClick={() => setExpanded(!expanded)}
          role="button"
          aria-expanded={expanded}
          tabIndex={0}
          onKeyDown={(e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault()
              setExpanded(!expanded)
            }
          }}
        >
          {/* Severity badge */}
          <span className={cn(
            'flex-shrink-0 inline-flex items-center px-2 py-0.5 rounded text-[11px] font-body font-bold uppercase mt-0.5',
            sevCfg.bg, sevCfg.text, 'border', sevCfg.border
          )}>
            {sev}
          </span>

          {/* Title + meta */}
          <div className="flex-1 min-w-0">
            <p className="font-heading text-sm font-semibold text-nothing-black leading-tight">
              {incident.title}
            </p>
            <div className="flex items-center gap-3 mt-1 flex-wrap">
              <span className="font-body text-[11px] text-nothing-gray-400 font-mono">
                {incident.incident_id}
              </span>
              <span className="text-nothing-gray-200">·</span>
              <span className="font-body text-[11px] text-nothing-gray-400">
                {startedLabel}
              </span>
              <span className="text-nothing-gray-200">·</span>
              <span className="font-body text-[11px] text-nothing-gray-500 font-medium">
                {durationLabel}
              </span>
            </div>
          </div>

          {/* Progress summary + toggle */}
          <div className="flex items-center gap-3 flex-shrink-0">
            {/* Mini progress bar */}
            <div className="hidden sm:flex flex-col items-end gap-1">
              <span className="text-[10px] font-body text-nothing-gray-400">
                {t('incident.stages_summary', { success: successCount, total: totalStages })}
              </span>
              <div className="w-20 h-1 bg-nothing-gray-100 rounded-full overflow-hidden">
                <div
                  className="h-full bg-status-healthy rounded-full"
                  style={{ width: `${(successCount / totalStages) * 100}%` }}
                />
              </div>
            </div>
            {expanded
              ? <ChevronUp className="w-4 h-4 text-nothing-gray-400" />
              : <ChevronDown className="w-4 h-4 text-nothing-gray-400" />
            }
          </div>
        </div>
      </div>

      {/* Timeline stages (展開時顯示) */}
      {expanded && (
        <div className="pl-4 sm:pl-8 mb-6">
          {/* Vertical rail */}
          <div className="relative">
            {/* 主軌道線 — 粗，貫穿整個 timeline */}
            <div
              className="absolute left-0 top-4 bottom-4 w-0.5 bg-nothing-gray-200"
              aria-hidden="true"
            />

            <div className="space-y-2 pl-6">
              {sortedStages.map((entry, i) => {
                if (!entry) {
                  // 缺失階段：顯示佔位
                  const stageType = STAGE_ORDER[i]
                  return (
                    <div
                      key={stageType}
                      className="relative animate-fade-in"
                      style={{ animationDelay: `${(index * 80) + (i * 60)}ms`, animationFillMode: 'both' }}
                    >
                      {/* 連接點 */}
                      <div className="absolute -left-6 top-3 w-2 h-2 rounded-full bg-nothing-gray-200 border-2 border-nothing-gray-300" />
                    </div>
                  )
                }

                return (
                  <div
                    key={entry.stage}
                    className="relative"
                  >
                    {/* 軌道連接點 */}
                    <div
                      className={cn(
                        'absolute -left-6 top-3.5 w-2.5 h-2.5 rounded-full border-2',
                        entry.status === 'success' ? 'bg-status-healthy border-status-healthy/40'
                        : entry.status === 'failed' ? 'bg-status-critical border-status-critical/40'
                        : entry.status === 'running' ? 'bg-status-syncing border-status-syncing/40 animate-pulse'
                        : 'bg-nothing-gray-300 border-nothing-gray-200'
                      )}
                      aria-hidden="true"
                    />
                    <TimelineStage
                      stage={entry.stage}
                      status={entry.status}
                      timestamp={entry.timestamp}
                      duration_ms={entry.duration_ms}
                      data={entry.data}
                      animationDelay={(index * 80) + (i * 60)}
                    />
                  </div>
                )
              })}
            </div>
          </div>
        </div>
      )}
    </article>
  )
}

// ============================================================
// Main Panel
// ============================================================

export default function AiopsTimelinePanel() {
  const t = useTranslations('aiopsTimeline')

  const [filter, setFilter] = useState<TimelineFilterState>({
    incident_id: '',
    time_range: '24h',
    status_filter: 'all',
  })

  const handleFilterChange = useCallback((updated: Partial<TimelineFilterState>) => {
    setFilter(prev => ({ ...prev, ...updated }))
  }, [])

  // React Query — 真實 API
  const {
    data: apiData,
    isLoading,
    error,
    refetch,
  } = useQuery({
    queryKey: ['aiops-timeline', filter.incident_id, filter.time_range],
    queryFn: () => fetchTimeline(filter.incident_id),
    enabled: !USE_SAMPLE_TIMELINE,
    staleTime: 30_000,
    refetchInterval: 60_000,
  })

  // 客戶端篩選 — rawIncidents 內聯進 useMemo 避免 conditional 依賴警告
  const incidents = useMemo(() => {
    const rawIncidents: TimelineIncident[] = USE_SAMPLE_TIMELINE ? SAMPLE_TIMELINE_INCIDENTS : (apiData ?? [])
    let list = rawIncidents

    if (filter.incident_id.trim()) {
      const q = filter.incident_id.toLowerCase()
      list = list.filter(
        inc => inc.incident_id.toLowerCase().includes(q) || inc.title.toLowerCase().includes(q)
      )
    }

    if (filter.status_filter !== 'all') {
      list = list.filter(inc => {
        if (filter.status_filter === 'success') {
          return inc.stages.every(s => s.status === 'success')
        }
        if (filter.status_filter === 'failed') {
          return inc.stages.some(s => s.status === 'failed')
        }
        if (filter.status_filter === 'running') {
          return inc.stages.some(s => s.status === 'running')
        }
        return true
      })
    }

    return list
  }, [apiData, filter.incident_id, filter.status_filter])

  // ---- Render ----

  return (
    <section aria-label={t('title')}>
      {/* Page header */}
      <div className="flex items-start justify-between gap-4 mb-6">
        <div>
          <h1 className="font-heading text-2xl font-bold text-nothing-black flex items-center gap-2.5">
            <GitBranch className="w-6 h-6 text-claw-blue" aria-hidden="true" />
            {t('title')}
            {USE_SAMPLE_TIMELINE && (
              <span className="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-body font-bold uppercase tracking-widest bg-status-warning/10 border border-status-warning/20 text-status-warning">
                {t('sampleBadge')}
              </span>
            )}
          </h1>
          <p className="mt-1 text-sm font-body text-nothing-gray-500">
            {t('subtitle')}
          </p>
        </div>

        {/* Refresh button (僅真實模式顯示) */}
        {!USE_SAMPLE_TIMELINE && (
          <button
            onClick={() => refetch()}
            disabled={isLoading}
            className={cn(
              'flex items-center gap-1.5 px-3 py-1.5 rounded-lg flex-shrink-0',
              'text-xs font-body bg-nothing-gray-100 text-nothing-gray-600',
              'hover:bg-nothing-gray-200 transition-colors',
              'disabled:opacity-50 disabled:cursor-not-allowed'
            )}
            aria-label={t('common.refresh')}
          >
            <RefreshCw className={cn('w-3.5 h-3.5', isLoading && 'animate-spin')} />
          </button>
        )}
      </div>

      {/* Filter bar */}
      <TimelineFilter
        filter={filter}
        onChange={handleFilterChange}
        incidentCount={incidents.length}
      />

      {/* Loading state (真實 API) */}
      {!USE_SAMPLE_TIMELINE && isLoading && (
        <div className="flex items-center justify-center py-20" role="status" aria-live="polite">
          <RefreshCw className="w-5 h-5 animate-spin text-nothing-gray-400" />
          <span className="ml-2 font-body text-sm text-nothing-gray-400">{t('loading')}</span>
        </div>
      )}

      {/* Error state */}
      {!USE_SAMPLE_TIMELINE && error && !isLoading && (
        <div
          className="flex flex-col items-center justify-center py-20 gap-3"
          role="alert"
        >
          <AlertCircle className="w-10 h-10 text-status-critical" />
          <p className="font-heading text-base font-semibold text-nothing-black">{t('error.title')}</p>
          <button
            onClick={() => refetch()}
            className="px-4 py-2 rounded-lg bg-nothing-black text-white font-body text-sm hover:opacity-80 transition-opacity"
          >
            {t('error.retry')}
          </button>
        </div>
      )}

      {/* Empty state */}
      {!isLoading && !error && incidents.length === 0 && (
        <div
          className="flex flex-col items-center justify-center py-20 gap-3"
          role="status"
        >
          <InboxIcon className="w-10 h-10 text-nothing-gray-300" aria-hidden="true" />
          <p className="font-heading text-base font-semibold text-nothing-gray-500">{t('empty.title')}</p>
          <p className="font-body text-sm text-nothing-gray-400">{t('empty.subtitle')}</p>
        </div>
      )}

      {/* Timeline list */}
      {incidents.length > 0 && (
        <div role="list" aria-label={t('title')}>
          {incidents.map((incident, i) => (
            <div key={incident.incident_id} role="listitem">
              <IncidentCard incident={incident} index={i} />
            </div>
          ))}
        </div>
      )}
    </section>
  )
}
