/*
 * F-B6 라이브 공지 발행 콘솔(조직자) [M17/운영]. 인증·행사 접근권 필요.
 * 진행 중 행사에 긴급/프로그램/안내/일반 공지를 발행 → 공개·관람객 피드로 즉시 노출.
 * API: liveNoticeApi(GET 목록 · POST 발행 · archive 보관 · pin 고정 토글). 대상 행사=useResolvedEventId.
 * Nifty 문자 그대로: kx-card/kx-cms-* 재사용 + kx-ln-*(liveNotice.css) + 공용 LiveNoticeBadge. 하드코딩 0.
 */
import { useCallback, useEffect, useMemo, useState, type FormEvent } from 'react';
import { Button } from '../../components/ui/Button';
import { EmptyState } from '../../components/ui/States';
import { ApiRequestError } from '../../api/client';
import { useResolvedEventId } from '../../hooks/useResolvedEventId';
import { LiveNoticeBadge } from '../public/LiveNoticeFeed';
import { liveNoticeApi, type LiveNoticeCategory, type LiveNoticeDto } from './liveNoticeApi';
import { IconBell, IconMapPin, IconPlus, IconWarning, IconCheckCircle } from '../../components/ui/icons';
import './liveNotice.css';

const CATEGORIES: LiveNoticeCategory[] = ['URGENT', 'PROGRAM', 'INFO', 'GENERAL'];
const CAT_LABEL: Record<LiveNoticeCategory, string> = {
  URGENT: '긴급',
  PROGRAM: '프로그램',
  INFO: '안내',
  GENERAL: '일반',
};

function fmt(iso: string | null): string {
  if (!iso) return '-';
  const d = new Date(iso);
  return Number.isNaN(d.getTime()) ? '-' : d.toLocaleString('ko-KR', { dateStyle: 'medium', timeStyle: 'short' });
}

export function LiveNoticePublisherPage() {
  const eventId = useResolvedEventId();
  const [items, setItems] = useState<LiveNoticeDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  // 발행 폼 상태
  const [category, setCategory] = useState<LiveNoticeCategory>('GENERAL');
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const [pinned, setPinned] = useState(false);

  const reload = useCallback(async () => {
    if (!eventId) {
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const list = await liveNoticeApi.list(eventId, undefined, 100);
      setItems(list);
    } catch (e) {
      setError(e instanceof ApiRequestError ? e.message : '공지를 불러오지 못했습니다.');
    } finally {
      setLoading(false);
    }
  }, [eventId]);

  useEffect(() => {
    void reload();
  }, [reload]);

  const canPublish = !!eventId && title.trim().length > 0 && !busy;

  async function publish(e: FormEvent) {
    e.preventDefault();
    if (!canPublish || !eventId) return;
    setBusy(true);
    setError(null);
    try {
      const created = await liveNoticeApi.create(eventId, {
        category,
        title: title.trim(),
        body: body.trim() || null,
        pinned,
      });
      setItems((prev) => [created, ...prev]);
      setTitle('');
      setBody('');
      setPinned(false);
      setCategory('GENERAL');
    } catch (err) {
      setError(err instanceof ApiRequestError ? err.message : '공지 발행에 실패했습니다.');
    } finally {
      setBusy(false);
    }
  }

  async function togglePin(n: LiveNoticeDto) {
    if (!eventId || busy) return;
    setBusy(true);
    setError(null);
    try {
      const updated = await liveNoticeApi.pin(eventId, n.id, !n.pinned);
      setItems((prev) => prev.map((it) => (it.id === updated.id ? updated : it)));
    } catch (err) {
      setError(err instanceof ApiRequestError ? err.message : '고정 상태 변경에 실패했습니다.');
    } finally {
      setBusy(false);
    }
  }

  async function archive(n: LiveNoticeDto) {
    if (!eventId || busy) return;
    if (!window.confirm(`"${n.title}" 공지를 보관하시겠습니까? 공개 피드에서 제거됩니다.`)) return;
    setBusy(true);
    setError(null);
    try {
      const updated = await liveNoticeApi.archive(eventId, n.id);
      setItems((prev) => prev.map((it) => (it.id === updated.id ? updated : it)));
    } catch (err) {
      setError(err instanceof ApiRequestError ? err.message : '보관에 실패했습니다.');
    } finally {
      setBusy(false);
    }
  }

  const published = useMemo(() => items.filter((n) => n.status === 'published'), [items]);

  return (
    <div className="kx-page kx-ln">
      <header className="kx-cms__head">
        <div>
          <h1 className="kx-cms__title"><IconBell className="kx-title-ic" size={20} />라이브 공지 발행</h1>
          <p className="kx-cms__subtitle">
            진행 중 행사에 긴급·프로그램 변경·안내 공지를 발행 · 관람객/공개 피드 즉시 반영 · 고정·보관 관리
          </p>
        </div>
      </header>

      {error && (
        <div className="kx-cms-alert" role="alert">
          <IconWarning size={14} /> {error}
        </div>
      )}

      {!eventId ? (
        <EmptyState title="행사를 선택해 주세요" description="라이브 공지를 발행할 대상 행사가 지정되지 않았습니다." />
      ) : (
        <div className="kx-ln-grid">
          {/* 발행 폼 */}
          <form className="kx-card kx-ln-form" onSubmit={publish} aria-label="공지 발행">
            <div className="kx-cms-sublabel" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <IconBell size={18} /> 새 공지 발행
            </div>

            <span className="kx-ln-label">카테고리</span>
            <div className="kx-ln-cats" role="radiogroup" aria-label="카테고리">
              {CATEGORIES.map((c) => (
                <button
                  key={c}
                  type="button"
                  role="radio"
                  aria-checked={category === c}
                  className={`kx-ln-cat${category === c ? ' is-active' : ''}`}
                  onClick={() => setCategory(c)}
                >
                  {CAT_LABEL[c]}
                </button>
              ))}
            </div>

            <span className="kx-ln-label">제목</span>
            <input
              className="kx-cms-title-input"
              value={title}
              maxLength={200}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="예: [긴급] 제1주차장 만차 안내"
              aria-label="제목"
            />

            <span className="kx-ln-label">본문 (선택)</span>
            <textarea
              className="kx-ln-textarea"
              value={body}
              maxLength={2000}
              onChange={(e) => setBody(e.target.value)}
              placeholder="상세 안내 내용을 입력하세요."
              aria-label="본문"
            />

            <label className="kx-ln-pinrow">
              <input type="checkbox" checked={pinned} onChange={(e) => setPinned(e.target.checked)} />
              <IconMapPin size={16} /> 상단 고정
            </label>

            <Button type="submit" block disabled={!canPublish} leadingIcon={<IconPlus size={16} />}>
              {busy ? '처리 중…' : '공지 발행'}
            </Button>
          </form>

          {/* 목록 */}
          <section className="kx-card" aria-label="공지 목록">
            <div className="kx-cms-sublabel" style={{ marginBottom: 12 }}>
              발행 공지 {published.length}건 · 전체 {items.length}건
            </div>
            {loading ? (
              <div className="kx-cms-empty">불러오는 중…</div>
            ) : items.length === 0 ? (
              <div className="kx-cms-empty">발행된 공지가 없습니다. 왼쪽에서 첫 공지를 발행하세요.</div>
            ) : (
              <ul className="kx-ln-list">
                {items.map((n) => {
                  const archived = n.status === 'archived';
                  const urgent = n.category === 'URGENT';
                  return (
                    <li
                      key={n.id}
                      className={`kx-ln-item${archived ? ' is-archived' : ''}${urgent && !archived ? ' is-urgent' : ''}`}
                    >
                      <div className="kx-ln-item__top">
                        <LiveNoticeBadge category={n.category} />
                        {n.pinned && !archived && (
                          <span className="kx-cms-pill kx-cms-pill--approved">
                            <IconMapPin size={12} /> 고정
                          </span>
                        )}
                        <span className="kx-ln-status">
                          {archived ? (
                            '보관됨'
                          ) : (
                            <>
                              <IconCheckCircle size={12} /> 게시 중
                            </>
                          )}
                        </span>
                      </div>
                      <p className="kx-ln-item__title">{n.title}</p>
                      {n.body && <p className="kx-ln-item__body">{n.body}</p>}
                      <p className="kx-ln-item__meta">
                        {[n.authorName, fmt(n.updatedAt ?? n.createdAt)].filter(Boolean).join(' · ')}
                      </p>
                      {!archived && (
                        <div className="kx-ln-item__actions">
                          <Button variant="secondary" onClick={() => togglePin(n)} disabled={busy}>
                            {n.pinned ? '고정 해제' : '상단 고정'}
                          </Button>
                          <Button variant="secondary" onClick={() => archive(n)} disabled={busy}>
                            보관
                          </Button>
                        </div>
                      )}
                    </li>
                  );
                })}
              </ul>
            )}
          </section>
        </div>
      )}
    </div>
  );
}
