/*
 * SCR-41 쪽지 (message). 참조: UIWS message/*.
 * 3-패널: 폴더 레일(받은/보낸) · 목록 · 읽기/작성. 읽음 처리·수신자 태그 입력.
 * 백엔드: /api/work/messages (inbox·sent·send·read·delete).
 * ★ 갭: 부서 트리 사용자 디렉터리 엔드포인트 부재 → 수신자는 사용자 ID 직접 입력. 07_work_api_gaps.md 기록.
 */
import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { messageApi } from '../../api/endpoints';
import type { MessageDto, MessageSendRequest } from '../../api/types';
import { Button } from '../../components/ui/Button';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { IconClose, IconPlus } from '../../components/ui/icons';
import { errMessage, fmtDateTime, timeAgo, useToast } from './workShared';
import './work.css';

type Folder = 'inbox' | 'sent';

export function MessagePage() {
  const qc = useQueryClient();
  const { show, node: toast } = useToast();
  const [folder, setFolder] = useState<Folder>('inbox');
  const [selected, setSelected] = useState<MessageDto | null>(null);
  const [composing, setComposing] = useState(false);

  const unreadQ = useQuery({ queryKey: ['msg-unread'], queryFn: () => messageApi.unreadCount() });
  const listQ = useQuery({
    queryKey: ['messages', folder],
    queryFn: () => (folder === 'inbox' ? messageApi.inbox(0, 50) : messageApi.sent(0, 50)),
  });

  const readM = useMutation({
    mutationFn: (id: string) => messageApi.read(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['messages', 'inbox'] });
      qc.invalidateQueries({ queryKey: ['msg-unread'] });
    },
  });
  const delM = useMutation({
    mutationFn: (id: string) => messageApi.remove(id),
    onSuccess: () => {
      show('삭제되었습니다.');
      setSelected(null);
      qc.invalidateQueries({ queryKey: ['messages'] });
      qc.invalidateQueries({ queryKey: ['msg-unread'] });
    },
    onError: (e) => show(errMessage(e)),
  });
  const sendM = useMutation({
    mutationFn: (body: MessageSendRequest) => messageApi.send(body),
    onSuccess: () => {
      show('쪽지를 보냈습니다.');
      setComposing(false);
      qc.invalidateQueries({ queryKey: ['messages', 'sent'] });
    },
    onError: (e) => show(errMessage(e)),
  });

  function openMessage(m: MessageDto) {
    setSelected(m);
    if (folder === 'inbox' && !m.readAt) readM.mutate(m.id);
  }

  const rows = listQ.data?.items ?? [];
  const unread = unreadQ.data?.unread ?? 0;

  return (
    <div className="kx-page">
      <header className="kx-work__head">
        <div>
          <h1 className="kx-work__title">쪽지</h1>
          <p className="kx-work__subtitle">행사 내 커뮤니케이션 · 주최자↔참가↔업체↔홀매니저</p>
        </div>
        <Button leadingIcon={<IconPlus size={16} />} onClick={() => setComposing(true)}>
          쪽지 쓰기
        </Button>
      </header>

      <div className="kx-msg">
        {/* 폴더 레일 */}
        <nav className="kx-msg__rail" aria-label="쪽지 폴더">
          <button
            className={`kx-msg__rail-btn ${folder === 'inbox' ? 'is-active' : ''}`}
            onClick={() => {
              setFolder('inbox');
              setSelected(null);
            }}
          >
            받은 쪽지
            {unread > 0 && <span className="kx-msg__rail-count tnum">{unread}</span>}
          </button>
          <button
            className={`kx-msg__rail-btn ${folder === 'sent' ? 'is-active' : ''}`}
            onClick={() => {
              setFolder('sent');
              setSelected(null);
            }}
          >
            보낸 쪽지
          </button>
        </nav>

        {/* 목록 */}
        <section className="kx-msg__list" aria-label={folder === 'inbox' ? '받은 쪽지 목록' : '보낸 쪽지 목록'}>
          {listQ.isLoading &&
            Array.from({ length: 6 }).map((_, i) => (
              <div className="kx-msg__item" key={i}>
                <Skeleton height={16} width="60%" />
                <Skeleton height={14} width="90%" />
              </div>
            ))}
          {listQ.isError && (
            <ErrorState message={errMessage(listQ.error)} onRetry={() => listQ.refetch()} />
          )}
          {!listQ.isLoading && !listQ.isError && rows.length === 0 && (
            <EmptyState
              title={folder === 'inbox' ? '받은 쪽지가 없습니다' : '보낸 쪽지가 없습니다'}
            />
          )}
          {rows.map((m) => {
            const unreadItem = folder === 'inbox' && !m.readAt;
            return (
              <div
                key={m.id}
                className={`kx-msg__item ${selected?.id === m.id ? 'is-selected' : ''} ${
                  unreadItem ? 'is-unread' : ''
                }`}
                onClick={() => openMessage(m)}
              >
                <div className="kx-msg__item-top">
                  <span className="kx-msg__item-sender">
                    {unreadItem && <span className="kx-msg__unread-dot" aria-label="안읽음" />}{' '}
                    {folder === 'inbox' ? m.senderName : m.title || '(제목 없음)'}
                  </span>
                  <span className="kx-msg__item-time">{timeAgo(m.createdAt)}</span>
                </div>
                <span className="kx-msg__item-title">{m.title || '(제목 없음)'}</span>
              </div>
            );
          })}
        </section>

        {/* 읽기/작성 */}
        <section className="kx-msg__read" aria-label="쪽지 내용">
          {composing ? (
            <ComposeForm
              onCancel={() => setComposing(false)}
              onSend={(b) => sendM.mutate(b)}
              sending={sendM.isPending}
            />
          ) : selected ? (
            <>
              <div className="kx-detail__head">
                <h2 className="kx-detail__title">{selected.title || '(제목 없음)'}</h2>
                <Button
                  variant="danger"
                  onClick={() => {
                    if (window.confirm('이 쪽지를 삭제할까요?')) delM.mutate(selected.id);
                  }}
                >
                  삭제
                </Button>
              </div>
              <div className="kx-detail__meta">
                <span>보낸이: {selected.senderName}</span>
                <span>· {fmtDateTime(selected.createdAt)}</span>
                {selected.recvType && <span>· {selected.recvType === 'REF' ? '참조' : '수신'}</span>}
              </div>
              <div className="kx-detail__body">{selected.content || '(내용 없음)'}</div>
            </>
          ) : (
            <EmptyState title="쪽지를 선택하세요" description="목록에서 쪽지를 선택하면 내용이 표시됩니다." />
          )}
        </section>
      </div>
      {toast}
    </div>
  );
}

function ComposeForm({
  onCancel,
  onSend,
  sending,
}: {
  onCancel: () => void;
  onSend: (b: MessageSendRequest) => void;
  sending: boolean;
}) {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [recipients, setRecipients] = useState<string[]>([]);
  const [entry, setEntry] = useState('');

  function addRecipient() {
    const v = entry.trim();
    if (v && !recipients.includes(v)) setRecipients([...recipients, v]);
    setEntry('');
  }

  return (
    <>
      <div className="kx-detail__head">
        <h2 className="kx-detail__title">쪽지 쓰기</h2>
      </div>
      <div className="kx-field">
        <span className="kx-label">받는 사람 (사용자 ID)</span>
        <div className="kx-tags">
          {recipients.map((r) => (
            <span className="kx-tag" key={r}>
              {r}
              <button
                onClick={() => setRecipients(recipients.filter((x) => x !== r))}
                aria-label={`${r} 제거`}
              >
                <IconClose size={12} />
              </button>
            </span>
          ))}
          <input
            value={entry}
            placeholder="ID 입력 후 Enter"
            onChange={(e) => setEntry(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter' || e.key === ',') {
                e.preventDefault();
                addRecipient();
              }
            }}
          />
        </div>
      </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>
        <textarea
          className="kx-textarea"
          value={content}
          onChange={(e) => setContent(e.target.value)}
        />
      </label>
      <div className="kx-detail__actions">
        <Button
          disabled={recipients.length === 0 || sending}
          onClick={() => onSend({ title, content, recipientIds: recipients })}
        >
          {sending ? '보내는 중…' : '보내기'}
        </Button>
        <Button variant="ghost" onClick={onCancel}>
          취소
        </Button>
      </div>
    </>
  );
}
