/*
 * SCR-42 공지 (notice). 참조: UIWS notice/*.
 * 고정 공지(상단) + 검색/목록 테이블 + 상세. 쓰기=매니저(백엔드 requireManager) → 홀매니저만 작성 UI 노출.
 * 백엔드: /api/work/notices.
 */
import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { noticeApi } from '../../api/endpoints';
import type { NoticeDto, NoticeSaveRequest } from '../../api/types';
import { useAuthStore } from '../../store/authStore';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { IconPlus, IconSearch } from '../../components/ui/icons';
import { errMessage, fmtDateTime, useToast } from './workShared';
import './work.css';

export function NoticePage() {
  const qc = useQueryClient();
  const { show, node: toast } = useToast();
  const isManager = useAuthStore((s) => s.user?.hallManager ?? false);
  const [keyword, setKeyword] = useState('');
  const [term, setTerm] = useState('');
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [composing, setComposing] = useState(false);

  const listQ = useQuery({
    queryKey: ['notices', term],
    queryFn: () => noticeApi.list({ keyword: term || undefined, page: 0, size: 50 }),
  });
  const detailQ = useQuery({
    queryKey: ['notice', selectedId],
    queryFn: () => noticeApi.get(selectedId as string),
    enabled: !!selectedId && !composing,
  });

  const saveM = useMutation({
    mutationFn: (body: NoticeSaveRequest) => noticeApi.create(body),
    onSuccess: (n: NoticeDto) => {
      show('공지가 등록되었습니다.');
      setComposing(false);
      setSelectedId(n.id);
      qc.invalidateQueries({ queryKey: ['notices'] });
    },
    onError: (e) => show(errMessage(e)),
  });
  const delM = useMutation({
    mutationFn: (id: string) => noticeApi.remove(id),
    onSuccess: () => {
      show('삭제되었습니다.');
      setSelectedId(null);
      qc.invalidateQueries({ queryKey: ['notices'] });
    },
    onError: (e) => show(errMessage(e)),
  });

  const rows = listQ.data?.items ?? [];
  const pinned = rows.filter((r) => r.pinned);
  const normal = rows.filter((r) => !r.pinned);

  const renderRow = (r: NoticeDto) => (
    <tr
      key={r.id}
      className={selectedId === r.id ? 'is-selected' : ''}
      onClick={() => {
        setComposing(false);
        setSelectedId(r.id);
      }}
    >
      <td>
        {r.pinned && <span className="kx-pill kx-pill--danger" style={{ marginRight: 6 }}>중요</span>}
        <span className="kx-list-table__title">{r.title}</span>
        {r.category && <span className="kx-list-table__muted"> · {r.category}</span>}
      </td>
      <td className="kx-list-table__muted">{r.authorName}</td>
      <td className="kx-list-table__muted kx-num">{fmtDateTime(r.publishedAt ?? r.createdAt)}</td>
      <td className="kx-num">{r.viewCount ?? 0}</td>
    </tr>
  );

  return (
    <div className="kx-page">
      <header className="kx-work__head">
        <div>
          <h1 className="kx-work__title">공지</h1>
          <p className="kx-work__subtitle">킨텍스·행사 공지 · 중요 공지 상단 고정</p>
        </div>
        {isManager && (
          <Button leadingIcon={<IconPlus size={16} />} onClick={() => setComposing(true)}>
            공지 작성
          </Button>
        )}
      </header>

      <div className="kx-split">
        <section className="kx-card" aria-label="공지 목록">
          <div className="kx-filterbar">
            <div className="kx-search__box" style={{ height: 40, flex: 1 }}>
              <IconSearch size={18} />
              <input
                placeholder="공지 검색…"
                value={keyword}
                onChange={(e) => setKeyword(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && setTerm(keyword)}
              />
            </div>
            <Button variant="secondary" onClick={() => setTerm(keyword)}>
              검색
            </Button>
          </div>

          <div className="kx-table-scroll kx-scroll-70">
            <table className="kx-list-table">
              <thead>
                <tr>
                  <th>제목</th>
                  <th style={{ width: 110 }}>작성자</th>
                  <th style={{ width: 140 }}>게시일</th>
                  <th style={{ width: 70 }} className="kx-num">
                    조회
                  </th>
                </tr>
              </thead>
              <tbody>
                {listQ.isLoading &&
                  Array.from({ length: 6 }).map((_, i) => (
                    <tr key={i}>
                      <td colSpan={4}>
                        <Skeleton height={20} />
                      </td>
                    </tr>
                  ))}
                {!listQ.isLoading && pinned.map(renderRow)}
                {!listQ.isLoading && normal.map(renderRow)}
              </tbody>
            </table>
          </div>

          {listQ.isError && (
            <ErrorState message={errMessage(listQ.error)} onRetry={() => listQ.refetch()} />
          )}
          {!listQ.isLoading && !listQ.isError && rows.length === 0 && (
            <EmptyState title="등록된 공지가 없습니다" />
          )}
        </section>

        <aside className="kx-detail" aria-label="공지 상세">
          {composing ? (
            <NoticeCompose
              saving={saveM.isPending}
              onCancel={() => setComposing(false)}
              onSave={(b) => saveM.mutate(b)}
            />
          ) : selectedId ? (
            detailQ.isLoading ? (
              <>
                <Skeleton height={24} width="70%" />
                <Skeleton height={16} />
                <Skeleton height={120} />
              </>
            ) : detailQ.isError ? (
              <ErrorState message={errMessage(detailQ.error)} onRetry={() => detailQ.refetch()} />
            ) : detailQ.data ? (
              <>
                <div className="kx-detail__head">
                  <h2 className="kx-detail__title">
                    {detailQ.data.pinned && (
                      <span className="kx-pill kx-pill--danger" style={{ marginRight: 6 }}>
                        중요
                      </span>
                    )}
                    {detailQ.data.title}
                  </h2>
                  {isManager && (
                    <Button
                      variant="danger"
                      onClick={() => {
                        if (window.confirm('이 공지를 삭제할까요?')) delM.mutate(detailQ.data!.id);
                      }}
                    >
                      삭제
                    </Button>
                  )}
                </div>
                <div className="kx-detail__meta">
                  <span>{detailQ.data.authorName}</span>
                  <span>· {fmtDateTime(detailQ.data.publishedAt ?? detailQ.data.createdAt)}</span>
                  <span>· 조회 {detailQ.data.viewCount ?? 0}</span>
                </div>
                <div className="kx-detail__body">{detailQ.data.content || '(내용 없음)'}</div>
              </>
            ) : null
          ) : (
            <EmptyState title="공지를 선택하세요" description="목록에서 공지를 선택하면 내용이 표시됩니다." />
          )}
        </aside>
      </div>
      {toast}
    </div>
  );
}

function NoticeCompose({
  onCancel,
  onSave,
  saving,
}: {
  onCancel: () => void;
  onSave: (b: NoticeSaveRequest) => void;
  saving: boolean;
}) {
  const [title, setTitle] = useState('');
  const [category, setCategory] = useState('일반');
  const [content, setContent] = useState('');
  const [pinned, setPinned] = useState(false);
  return (
    <>
      <div className="kx-detail__head">
        <h2 className="kx-detail__title">공지 작성</h2>
      </div>
      <label className="kx-field">
        <span className="kx-label">제목 *</span>
        <input className="kx-input" value={title} onChange={(e) => setTitle(e.target.value)} />
      </label>
      <label className="kx-field">
        <span className="kx-label">분류</span>
        <select className="kx-select" value={category} onChange={(e) => setCategory(e.target.value)}>
          {['일반', '행사', '규정', '시스템'].map((c) => (
            <option key={c} value={c}>
              {c}
            </option>
          ))}
        </select>
      </label>
      <label className="kx-field">
        <span className="kx-label">내용</span>
        <textarea className="kx-textarea" value={content} onChange={(e) => setContent(e.target.value)} />
      </label>
      <label className="kx-switch">
        <input type="checkbox" checked={pinned} onChange={(e) => setPinned(e.target.checked)} />
        <span>중요 공지로 상단 고정</span>
      </label>
      <div className="kx-detail__actions">
        <Button
          disabled={!title.trim() || saving}
          onClick={() => onSave({ title, category, content, pinned })}
        >
          {saving ? '등록 중…' : '등록'}
        </Button>
        <Button variant="ghost" onClick={onCancel}>
          취소
        </Button>
      </div>
    </>
  );
}
