import React, { useEffect, useMemo, useState } from 'react';
import { approveRequest, listPendingRequests, rejectRequest } from '../api';
import { VisitRequestView } from '../types';
import { formatVisitRange } from '../status';
import { Dialog } from '../components/Dialog';

type SortKey = 'visitorName' | 'company' | 'zoneName' | 'purpose' | 'visitFrom';
type BusyAction = 'approve' | 'reject';

const COLUMNS: { key: SortKey; label: string }[] = [
  { key: 'visitorName', label: '방문자' },
  { key: 'company', label: '회사' },
  { key: 'zoneName', label: '출입구역' },
  { key: 'purpose', label: '출입목적' },
  { key: 'visitFrom', label: '출입기간' },
];

export const ApprovalQueuePage: React.FC = () => {
  const [items, setItems] = useState<VisitRequestView[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [busyAction, setBusyAction] = useState<{ id: number; action: BusyAction } | null>(null);
  const [sortKey, setSortKey] = useState<SortKey | null>(null);
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
  const [rejectingId, setRejectingId] = useState<number | null>(null);

  const onSort = (key: SortKey) => {
    if (sortKey === key) {
      setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));
    } else {
      setSortKey(key);
      setSortDir('asc');
    }
  };

  const sortedItems = useMemo(() => {
    if (!sortKey) return items;
    const arr = [...items];
    arr.sort((a, b) => {
      const cmp = sortKey === 'visitFrom'
        ? new Date(a.visitFrom).getTime() - new Date(b.visitFrom).getTime()
        : String(a[sortKey] ?? '').localeCompare(String(b[sortKey] ?? ''), 'ko');
      return sortDir === 'asc' ? cmp : -cmp;
    });
    return arr;
  }, [items, sortKey, sortDir]);

  const load = () => {
    setLoading(true);
    listPendingRequests()
      .then(setItems)
      .catch((e) => setError(e instanceof Error ? e.message : '조회 실패'))
      .finally(() => setLoading(false));
  };

  useEffect(load, []);

  const approve = async (id: number) => {
    setError(null);
    setBusyAction({ id, action: 'approve' });
    try {
      await approveRequest(id);
      load();
    } catch (e) {
      setError(e instanceof Error ? e.message : '처리 실패');
    } finally {
      setBusyAction(null);
    }
  };

  const confirmReject = async (comment?: string) => {
    const id = rejectingId;
    setRejectingId(null);
    if (id == null) return;
    setError(null);
    setBusyAction({ id, action: 'reject' });
    try {
      await rejectRequest(id, comment);
      load();
    } catch (e) {
      setError(e instanceof Error ? e.message : '처리 실패');
    } finally {
      setBusyAction(null);
    }
  };

  return (
    <div>
      <div className="page-head"><h2>승인 대기 ({items.length})</h2></div>
      {error && <div className="alert alert-error">{error}</div>}

      <div className="card">
        {loading ? (
          <p className="muted">불러오는 중…</p>
        ) : items.length === 0 ? (
          <p className="muted">승인 대기 중인 신청이 없습니다.</p>
        ) : (
          <table className="table">
            <thead>
              <tr>
                {COLUMNS.map((c) => (
                  <th
                    key={c.key}
                    onClick={() => onSort(c.key)}
                    style={{ cursor: 'pointer', userSelect: 'none', whiteSpace: 'nowrap' }}
                    title="클릭하여 정렬"
                  >
                    {c.label}{sortKey === c.key ? (sortDir === 'asc' ? ' ▲' : ' ▼') : ''}
                  </th>
                ))}
                <th>처리</th>
              </tr>
            </thead>
            <tbody>
              {sortedItems.map((r) => (
                <tr key={r.id}>
                  <td>{r.visitorName}</td>
                  <td>{r.company || '-'}</td>
                  <td>{r.zoneName || '-'}</td>
                  <td>{r.purpose}</td>
                  <td>{formatVisitRange(r.visitFrom, r.visitTo)}</td>
                  <td className="action-cell">
                    <button
                      className="btn-success"
                      disabled={busyAction?.id === r.id && busyAction.action === 'approve'}
                      onClick={() => {
                        if (busyAction?.id === r.id) return;
                        approve(r.id);
                      }}
                    >
                      {busyAction?.id === r.id && busyAction.action === 'approve' ? '처리 중...' : '승인'}
                    </button>
                    <button
                      className="btn-danger"
                      disabled={busyAction?.id === r.id && busyAction.action === 'reject'}
                      onClick={() => {
                        if (busyAction?.id === r.id) return;
                        setRejectingId(r.id);
                      }}
                    >
                      {busyAction?.id === r.id && busyAction.action === 'reject' ? '처리 중...' : '반려'}
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {rejectingId != null && (
        <Dialog
          title="반려 처리"
          message="반려 사유를 입력하세요 (선택)."
          withInput
          inputPlaceholder="반려 사유"
          confirmLabel="반려"
          danger
          onConfirm={confirmReject}
          onCancel={() => setRejectingId(null)}
        />
      )}
    </div>
  );
};
