/*
 * §5B 업무 화면 공유 유틸 — 날짜 포맷·상태 필·토스트.
 * 백엔드 상태 문자열은 그대로 표기(권위)하되, 알려진 코드는 톤으로 매핑한다.
 */
import { useCallback, useState } from 'react';
import { ApiRequestError } from '../../api/client';

/** ISO/DB 문자열 → "MM.DD" (실패 시 원문 앞 10자). */
export function fmtDate(s: string | null | undefined): string {
  if (!s) return '-';
  const d = new Date(s);
  if (Number.isNaN(d.getTime())) return s.slice(0, 10);
  return `${String(d.getMonth() + 1).padStart(2, '0')}.${String(d.getDate()).padStart(2, '0')}`;
}

/** ISO/DB 문자열 → "YYYY.MM.DD HH:mm". */
export function fmtDateTime(s: string | null | undefined): string {
  if (!s) return '-';
  const d = new Date(s);
  if (Number.isNaN(d.getTime())) return s;
  const p = (n: number) => String(n).padStart(2, '0');
  return `${d.getFullYear()}.${p(d.getMonth() + 1)}.${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
}

/** 상대 시간(방금·N분·N시간·N일 전). */
export function timeAgo(s: string | null | undefined): string {
  if (!s) return '';
  const d = new Date(s);
  if (Number.isNaN(d.getTime())) return fmtDate(s);
  const diff = Date.now() - d.getTime();
  const min = Math.floor(diff / 60000);
  if (min < 1) return '방금';
  if (min < 60) return `${min}분 전`;
  const hr = Math.floor(min / 60);
  if (hr < 24) return `${hr}시간 전`;
  const day = Math.floor(hr / 24);
  if (day < 7) return `${day}일 전`;
  return fmtDate(s);
}

/** 봉투 오류 → 한국어 메시지(코드 우선). */
export function errMessage(e: unknown): string {
  if (e instanceof ApiRequestError) {
    if (e.code === 'FORBIDDEN') return '권한이 없습니다.';
    if (e.code === 'NOT_FOUND') return '대상을 찾을 수 없습니다.';
    if (e.code === 'NOT_IMPLEMENTED') return '준비 중인 기능입니다.';
    return e.message;
  }
  if (e instanceof Error) return e.message;
  return '요청을 처리하지 못했습니다.';
}

type PillTone = 'neutral' | 'info' | 'warn' | 'success' | 'danger';

/** 상태 코드 → 필 톤·라벨(백엔드 원문 라벨 표기, 알려진 코드만 톤 부여). */
export function statusPillTone(raw: string | null | undefined): PillTone {
  const v = (raw ?? '').toUpperCase();
  if (['DONE', 'ANSWERED', 'COMPLETED', 'COMPLETE', '완료', '답변완료', 'CLOSED'].includes(v)) return 'success';
  if (['REVIEWING', 'IN_PROGRESS', 'PROGRESS', '진행중', '검토중', 'OPEN'].includes(v)) return 'info';
  if (['RECEIVED', '접수', 'PENDING', 'WAIT'].includes(v)) return 'neutral';
  if (['REJECTED', '반려', 'BLOCKED', 'FAILED'].includes(v)) return 'danger';
  if (['HOLD', 'DELAYED', '보류'].includes(v)) return 'warn';
  return 'neutral';
}

/** 상태 필 — 라벨은 원문 유지. */
export function StatusPill({ value }: { value: string | null | undefined }) {
  if (!value) return <span className="kx-pill kx-pill--neutral">-</span>;
  return <span className={`kx-pill kx-pill--${statusPillTone(value)}`}>{value}</span>;
}

/** 간단 토스트 훅. */
export function useToast() {
  const [toast, setToast] = useState<string | null>(null);
  const show = useCallback((msg: string) => {
    setToast(msg);
    window.setTimeout(() => setToast(null), 2600);
  }, []);
  const node = toast ? (
    <div className="kx-toast" role="status">
      {toast}
    </div>
  ) : null;
  return { show, node };
}
