import { useEffect, useState, useRef } from 'react'
import { View, Text, ScrollView, StyleSheet, TouchableOpacity, RefreshControl, Animated } from 'react-native'
import { COLORS } from '../../constants/Config'
import { getNotifications, markNotificationRead } from '../../services/api'
import { useWebSocket } from '../../hooks/useWebSocket'
import LineIcon from '../../components/LineIcon'

type IconName = Parameters<typeof LineIcon>[0]['name']

const TYPE_ICON_NAME: Record<string, IconName> = {
  SR_CREATED: 'sr',       SR_UPDATED: 'sync',     SR_COMPLETED: 'check',
  INCIDENT:   'alert',    SLA_BREACH: 'bell',      DEPLOY_SUCCESS: 'zap',
  DEPLOY_FAIL:'alert',    LICENSE:    'lock',       SYSTEM: 'settings',
  DEFAULT:    'bell',
  sr_created: 'sr',       sr_updated: 'sync',      sr_completed: 'check',
  deploy_notify: 'zap',   incident_created: 'alert', sla_breach: 'bell',
  anomaly_alert: 'alert', batch_notify: 'settings',
}

/* 하위 호환: 이모지 대신 타입 색상 */
const TYPE_COLOR: Record<string, string> = {
  SR_CREATED: '#00A0C8', SR_UPDATED: '#f59e0b', SR_COMPLETED: '#22c55e',
  INCIDENT: '#ef4444',   SLA_BREACH: '#f59e0b', DEPLOY_SUCCESS: '#22c55e',
  DEPLOY_FAIL: '#ef4444', DEFAULT: '#64748b',
  sr_created: '#00A0C8', sr_updated: '#f59e0b', sr_completed: '#22c55e',
  deploy_notify: '#22c55e', incident_created: '#ef4444',
}

/** 이전 코드와의 호환을 위한 빈 맵 (미사용) */
const TYPE_ICON: Record<string, string> = {}

interface NotifItem {
  id: string | number; type: string; title: string
  message: string; is_read: boolean; created_at: string
  source: 'api' | 'ws'
}

const SAMPLE: NotifItem[] = [
  { id:'s1', type:'SR_CREATED', title:'[샘플] SR 신규 접수',
    message:'서버 재시작 요청이 접수되었습니다.',
    is_read:false, created_at:new Date().toISOString(), source:'api' },
  { id:'s2', type:'DEPLOY_SUCCESS', title:'[샘플] 배포 완료',
    message:'zioinfo-web 배포가 완료되었습니다.',
    is_read:true, created_at:new Date(Date.now()-3600000).toISOString(), source:'api' },
]

const fmtTitle = (t: string) => ({
  sr_created:'SR 신규 접수', sr_updated:'SR 상태 변경', sr_completed:'SR 완료',
  deploy_notify:'배포 알림', incident_created:'인시던트 발생', sla_breach:'SLA 위반 경고',
  SR_CREATED:'SR 신규 접수', INCIDENT:'인시던트', SLA_BREACH:'SLA 위반',
  DEPLOY_SUCCESS:'배포 성공', DEPLOY_FAIL:'배포 실패',
} as Record<string,string>)[t] ?? t

const fmtMsg = (evt: { event_type:string; data:Record<string,unknown> }) => {
  const d = evt.data ?? {}
  if (d.title) return String(d.title)
  if (d.message) return String(d.message)
  if (d.sr_id) return `SR ${d.sr_id}: ${d.status ?? ''}`
  return `${evt.event_type} 이벤트 수신`
}

export default function NotificationsScreen() {
  const [items,   setItems]   = useState<NotifItem[]>([])
  const [loading, setLoading] = useState(true)
  const [refresh, setRefresh] = useState(false)
  const pulseAnim = useRef(new Animated.Value(1)).current
  const { connected, lastEvent, events: wsEvents } = useWebSocket(['sr','deploy','sla','incident'])

  useEffect(() => {
    if (connected) {
      Animated.loop(Animated.sequence([
        Animated.timing(pulseAnim, { toValue:0.4, duration:900, useNativeDriver:true }),
        Animated.timing(pulseAnim, { toValue:1.0, duration:900, useNativeDriver:true }),
      ])).start()
    } else { pulseAnim.setValue(1) }
  }, [connected])

  useEffect(() => {
    if (!lastEvent) return
    const item: NotifItem = {
      id:`ws-${Date.now()}`, type:lastEvent.event_type,
      title:fmtTitle(lastEvent.event_type), message:fmtMsg(lastEvent),
      is_read:false, created_at:(lastEvent.timestamp as string) || new Date().toISOString(),
      source:'ws',
    }
    setItems(prev => [item, ...prev])
  }, [lastEvent])

  const load = async (r = false) => {
    r ? setRefresh(true) : setLoading(true)
    try {
      const res = await getNotifications()
      const api: NotifItem[] = (res.data.content ?? res.data.items ?? res.data ?? [])
        .map((n: any) => ({ ...n, source:'api' as const }))
      setItems(prev => [...prev.filter(i => i.source==='ws'), ...api])
    } catch { if (!r) setItems(prev => prev.length===0 ? SAMPLE : prev) }
    finally { setLoading(false); setRefresh(false) }
  }

  useEffect(() => { load() }, [])

  const markRead = async (id: string | number) => {
    setItems(prev => prev.map(n => n.id===id ? {...n, is_read:true} : n))
    if (!String(id).startsWith('ws-')) try { await markNotificationRead(Number(id)) } catch {}
  }

  const unread = items.filter(n => !n.is_read).length

  return (
    <View style={{ flex:1, backgroundColor:COLORS.bg }}>
      <View style={s.header}>
        <View>
          <Text style={s.title}>알림</Text>
          <View style={s.wsRow}>
            <Animated.View style={[s.dot, { opacity:pulseAnim, backgroundColor:connected?COLORS.success:'#94a3b8' }]} />
            <Text style={[s.wsLabel, { color:connected?COLORS.success:'#94a3b8' }]}>
              {connected ? 'GUARDiA 실시간 연결' : '연결 중...'}
            </Text>
          </View>
        </View>
        {unread>0 && <View style={s.badge}><Text style={s.badgeText}>{unread}</Text></View>}
      </View>

      {wsEvents.length>0 && wsEvents[0] && (
        <View style={s.wsBanner}>
          <View style={s.wsIcon}>
            <LineIcon name={TYPE_ICON_NAME[wsEvents[0]?.event_type ?? ''] ?? 'bell'} size={20} color={COLORS.accent} />
          </View>
          <View style={{ flex:1 }}>
            <Text style={s.wsBannerT}>실시간: {fmtTitle(wsEvents[0]?.event_type ?? '')}</Text>
            <Text style={s.wsBannerM} numberOfLines={1}>{fmtMsg(wsEvents[0])}</Text>
          </View>
        </View>
      )}

      <ScrollView refreshControl={<RefreshControl refreshing={refresh} onRefresh={() => load(true)} />}>
        {!loading && items.length===0 && (
          <View style={s.empty}>
            <View style={{ width: 60, height: 60, borderRadius: 30, backgroundColor: 'rgba(0,160,200,.1)',
              alignItems: 'center', justifyContent: 'center' }}>
              <LineIcon name="bell" size={32} color={COLORS.accent} />
            </View>
            <Text style={s.emptyT}>알림이 없습니다.</Text>
            <Text style={s.emptyH}>SR 등록 또는 배포 실행 시{'\n'}알림이 표시됩니다.</Text>
          </View>
        )}
        {items.map(n => {
          const iconName = TYPE_ICON_NAME[n.type] ?? TYPE_ICON_NAME.DEFAULT
          const iconColor = TYPE_COLOR[n.type] ?? '#64748b'
          return (
            <TouchableOpacity key={String(n.id)} style={[s.item, !n.is_read && s.unread]} onPress={() => markRead(n.id)}>
              <View style={[s.iconBox, { backgroundColor: iconColor + '18' }]}>
                <LineIcon name={iconName} size={20} color={iconColor} />
                {n.source==='ws' && <View style={s.wsPin} />}
              </View>
              <View style={{ flex:1 }}>
                <Text style={[s.iT, !n.is_read && { fontWeight:'700' }]}>{n.title}</Text>
                <Text style={s.iM} numberOfLines={2}>{n.message}</Text>
                <View style={{ flexDirection:'row', gap:8, marginTop:4 }}>
                  <Text style={s.iTime}>{new Date(n.created_at).toLocaleString('ko-KR')}</Text>
                  {n.source==='ws' && <Text style={[s.iTime,{color:COLORS.accent}]}>실시간</Text>}
                </View>
              </View>
              {!n.is_read && <View style={s.readDot} />}
            </TouchableOpacity>
          )
        })}
        <View style={{ height:24 }} />
      </ScrollView>
    </View>
  )
}

const s = StyleSheet.create({
  header:    { flexDirection:'row', alignItems:'center', justifyContent:'space-between',
               padding:16, backgroundColor:'#fff', borderBottomWidth:1, borderBottomColor:COLORS.border },
  title:     { fontSize:17, fontWeight:'700', color:COLORS.text },
  wsRow:     { flexDirection:'row', alignItems:'center', gap:5, marginTop:3 },
  dot:       { width:7, height:7, borderRadius:4 },
  wsLabel:   { fontSize:11, fontWeight:'500' },
  badge:     { backgroundColor:COLORS.danger, borderRadius:10, paddingHorizontal:7, paddingVertical:2 },
  badgeText: { color:'#fff', fontSize:11, fontWeight:'700' },
  wsBanner:  { flexDirection:'row', alignItems:'center', gap:10, padding:12,
               backgroundColor:'#eff2ff', borderBottomWidth:1, borderBottomColor:'#c7d2fe' },
  wsIcon:    { fontSize:20 },
  wsBannerT: { fontSize:12, fontWeight:'700', color:COLORS.accent },
  wsBannerM: { fontSize:11, color:COLORS.muted },
  item:      { flexDirection:'row', backgroundColor:'#fff', padding:14,
               borderBottomWidth:1, borderBottomColor:'#f1f5f9', gap:10, alignItems:'flex-start' },
  unread:    { backgroundColor:'#f8f9ff' },
  iconBox:   { width:40, height:40, borderRadius:10, alignItems:'center', justifyContent:'center',
               position:'relative', flexShrink:0 },
  icon:      { fontSize:24, marginTop:2 },
  wsPin:     { position:'absolute', top:-2, right:-4, width:8, height:8, borderRadius:4, backgroundColor:COLORS.accent },
  iT:        { fontSize:14, color:COLORS.text },
  iM:        { fontSize:12, color:COLORS.muted, marginTop:3, lineHeight:17 },
  iTime:     { fontSize:11, color:COLORS.muted },
  readDot:   { width:8, height:8, borderRadius:4, backgroundColor:COLORS.accent, marginTop:6 },
  empty:     { alignItems:'center', marginTop:60, gap:10, paddingHorizontal:32 },
  emptyT:    { fontSize:15, fontWeight:'600', color:COLORS.muted },
  emptyH:    { fontSize:12, color:COLORS.muted, textAlign:'center', lineHeight:18 },
})
