/*
 * SCR-47 알림센터 (notification). 참조: UIWS NotificationsPage.
 * 카테고리 칩 + 시간순 목록 + 읽음/모두읽음 + 딥링크 + 삭제.
 * 백엔드: /api/work/notifications (list·unread-count·read·read-all·delete).
 */
import { useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { notificationApi } from '../../api/endpoints';
import type { NotificationDto } from '../../api/types';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { IconArrowRight, IconBell, IconCheck } from '../../components/ui/icons';
import { errMessage, timeAgo, useToast } from './workShared';
import './work.css';

// 알림 유형 라벨(백엔드 notiType 원문 매핑, 미지정은 원문 표기).
const TYPE_LABEL: Record<string, string> = {
  DEADLINE: '마감',
  AWARD: '낙찰',
  APPROVAL: '승인',
  PAYMENT: '결제',
  SYSTEM: '시스템',
};

export function NotificationCenterPage() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const { show, node: toast } = useToast();
  const [category, setCategory] = useState<string>('ALL');

  const listQ = useQuery({
    queryKey: ['notifications-center'],
    queryFn: () => notificationApi.list({ page: 0, size: 100 }),
  });

  const readM = useMutation({
    mutationFn: (id: string) => notificationApi.read(id),
    onSuccess: () => invalidate(),
  });
  const readAllM = useMutation({
    mutationFn: () => notificationApi.readAll(),
    onSuccess: () => {
      show('모두 읽음 처리했습니다.');
      invalidate();
    },
    onError: (e) => show(errMessage(e)),
  });
  const delM = useMutation({
    mutationFn: (id: string) => notificationApi.remove(id),
    onSuccess: () => invalidate(),
    onError: (e) => show(errMessage(e)),
  });

  function invalidate() {
    qc.invalidateQueries({ queryKey: ['notifications-center'] });
    qc.invalidateQueries({ queryKey: ['notif-unread'] });
  }

  const items = listQ.data?.items ?? [];
  const categories = useMemo(() => {
    const present = Array.from(new Set(items.map((n) => n.notiType)));
    return ['ALL', ...present];
  }, [items]);
  const filtered = category === 'ALL' ? items : items.filter((n) => n.notiType === category);
  const unreadCount = items.filter((n) => !n.readAt).length;

  function openItem(n: NotificationDto) {
    if (!n.readAt) readM.mutate(n.id);
    if (n.link) {
      if (/^https?:\/\//.test(n.link)) window.open(n.link, '_blank', 'noopener');
      else navigate(n.link);
    }
  }

  return (
    <div className="kx-page">
      <header className="kx-work__head">
        <div>
          <h1 className="kx-work__title">알림</h1>
          <p className="kx-work__subtitle">
            마감·낙찰·승인·결제·시스템 알림 {unreadCount > 0 && `· 안읽음 ${unreadCount}`}
          </p>
        </div>
        <div className="kx-work__head-actions">
          <Button
            variant="secondary"
            leadingIcon={<IconCheck size={16} />}
            disabled={unreadCount === 0 || readAllM.isPending}
            onClick={() => readAllM.mutate()}
          >
            모두 읽음
          </Button>
        </div>
      </header>

      <div className="kx-noti__chips">
        {categories.map((c) => (
          <button
            key={c}
            className={`kx-chip ${category === c ? 'is-active' : ''}`}
            onClick={() => setCategory(c)}
          >
            {c === 'ALL' ? '전체' : (TYPE_LABEL[c] ?? c)}
          </button>
        ))}
      </div>

      <section className="kx-card" style={{ padding: 0 }} aria-label="알림 목록">
        {listQ.isLoading &&
          Array.from({ length: 6 }).map((_, i) => (
            <div className="kx-noti__item" key={i}>
              <Skeleton height={32} width={32} radius={16} />
              <div style={{ flex: 1 }}>
                <Skeleton height={16} width="40%" />
                <Skeleton height={14} width="70%" />
              </div>
            </div>
          ))}
        {listQ.isError && (
          <ErrorState message={errMessage(listQ.error)} onRetry={() => listQ.refetch()} />
        )}
        {!listQ.isLoading && !listQ.isError && filtered.length === 0 && (
          <EmptyState title="새 알림이 없습니다" icon={<IconBell size={28} />} />
        )}
        {filtered.map((n) => (
          <div key={n.id} className={`kx-noti__item ${!n.readAt ? 'is-unread' : ''}`}>
            <span className="kx-noti__icon">
              <IconBell size={16} />
            </span>
            <div
              className="kx-noti__body"
              style={{ cursor: n.link ? 'pointer' : 'default' }}
              onClick={() => openItem(n)}
            >
              <div className="kx-noti__title">
                <span className="kx-pill kx-pill--info" style={{ marginRight: 6 }}>
                  {TYPE_LABEL[n.notiType] ?? n.notiType}
                </span>
                {n.title}
              </div>
              {n.message && <div className="kx-noti__desc">{n.message}</div>}
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>
              <span className="kx-noti__time">{timeAgo(n.createdAt)}</span>
              <div style={{ display: 'flex', gap: 6 }}>
                {n.link && (
                  <button
                    className="kx-tag"
                    onClick={() => openItem(n)}
                    aria-label="바로가기"
                  >
                    바로가기 <IconArrowRight size={12} />
                  </button>
                )}
                <button className="kx-tag" onClick={() => delM.mutate(n.id)} aria-label="삭제">
                  삭제
                </button>
              </div>
            </div>
            {!n.readAt && <span className="kx-noti__dot" aria-label="안읽음" />}
          </div>
        ))}
      </section>

      <p className="kx-list-table__muted" style={{ fontSize: 12 }}>
        알림 규칙 설정은 마이페이지 &gt; 알림 설정에서 관리합니다.
      </p>
      {toast}
    </div>
  );
}
