// My Reservations / 예약 내역 page — Firestore 실데이터.

// 서버 status → UI 그룹.
// active: 픽업 대기/진행, transit: 배송 중, delivered: 완료, cancelled: 취소
const STATUS_GROUP = {
  paid:             "active",
  confirmed:        "active",
  pickup_scheduled: "active",
  cancel_requested: "active",
  picking_up:       "transit",
  in_progress:      "transit",
  picked_up:        "transit",
  in_transit:       "transit",
  shipping:         "transit",
  pickup_delayed:   "transit",
  returning:        "transit",
  delivered:        "delivered",
  canceled:         "cancelled",
  cancelled:        "cancelled",
  pickup_canceled:  "cancelled",
  pickup_failed:    "cancelled",
  delivery_failed:  "cancelled",
  rejected:         "cancelled",
  expired:          "cancelled",
};

const STATUS_LABEL = {
  paid:             "결제 완료",
  confirmed:        "예약 확정",
  pickup_scheduled: "수거 예정",
  cancel_requested: "취소 요청 중",
  picking_up:       "수거 중",
  in_progress:      "수거 중",
  picked_up:        "수거 완료",
  in_transit:       "배송 중",
  shipping:         "배송 중",
  pickup_delayed:   "수거 지연",
  returning:        "반품 중",
  delivered:        "배송 완료",
  canceled:         "취소",
  cancelled:        "취소",
  pickup_canceled:  "수거 취소",
  pickup_failed:    "수거 실패",
  delivery_failed:  "배송 실패",
  rejected:         "예약 거부",
  expired:          "만료",
};

// 취소 가능한 상태 (서버 CANCELLABLE_STATUSES 와 대응)
const CANCELLABLE = new Set(["paid", "confirmed", "pickup_scheduled"]);

const STATUS_FILTERS = [
  { key: "all", label: "전체" },
  { key: "active", label: "진행 중" },
  { key: "delivered", label: "완료" },
  { key: "cancelled", label: "취소" },
];

const METHOD_LABEL = {
  visit: "방문",
  convenience: "편의점",
};

function fmtTsDate(ts) {
  if (!ts) return "";
  const d = ts.toDate ? ts.toDate() : ts;
  if (!(d instanceof Date) || isNaN(d.getTime())) return "";
  const y = d.getFullYear(), m = d.getMonth() + 1, day = d.getDate();
  return `${y}.${String(m).padStart(2, '0')}.${String(day).padStart(2, '0')}`;
}

function boxSummary(r) {
  const boxes = r.boxes || {};
  const parts = [];
  Object.entries(boxes).forEach(([t, n]) => {
    if (Number(n) > 0) parts.push(`${t}×${n}`);
  });
  return parts.join(", ") || "박스";
}

const MyReservations = ({ navigate }) => {
  const [user, setUser] = React.useState(null);
  const [authReady, setAuthReady] = React.useState(false);
  const [reservations, setReservations] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState("");
  const [filter, setFilter] = React.useState("all");
  const [cancellingId, setCancellingId] = React.useState(null);

  // Auth listen
  React.useEffect(() => {
    let unsub = null, cancelled = false;
    const start = () => {
      if (cancelled) return;
      if (!window.firebaseAuth || !window.firebaseOnAuthStateChanged) {
        setTimeout(start, 50); return;
      }
      unsub = window.firebaseOnAuthStateChanged(window.firebaseAuth, (u) => {
        setUser(u);
        setAuthReady(true);
      });
    };
    start();
    return () => { cancelled = true; if (unsub) unsub(); };
  }, []);

  // Auth-gate redirect
  React.useEffect(() => {
    if (authReady && !user) {
      try { sessionStorage.setItem('postLoginRedirect', window.location.pathname); } catch (_) {}
      navigate('login');
    }
  }, [authReady, user]);

  // Firestore subscribe — userId == uid, orderBy createdAt desc
  React.useEffect(() => {
    if (!user || !window.firebaseDb || !window.firebaseFs) return;
    setLoading(true);
    setError("");
    const fs = window.firebaseFs;
    const q = fs.query(
      fs.collection(window.firebaseDb, "reservations"),
      fs.where("userId", "==", user.uid),
      fs.orderBy("createdAt", "desc")
    );
    const unsub = fs.onSnapshot(q,
      (snap) => {
        const items = snap.docs.map(d => ({ id: d.id, ...d.data() }));
        setReservations(items);
        setLoading(false);
      },
      (err) => {
        console.error("[my] reservations onSnapshot error", err);
        setError(err?.message || "예약 내역을 불러오지 못했어요.");
        setLoading(false);
      }
    );
    return () => unsub();
  }, [user]);

  const grouped = (r) => STATUS_GROUP[r.status] || "active";
  const filtered = reservations.filter(r => {
    if (filter === "all") return true;
    return grouped(r) === filter;
  });

  const counts = {
    all: reservations.length,
    active: reservations.filter(r => grouped(r) === "active").length,
    transit: reservations.filter(r => grouped(r) === "transit").length,
    delivered: reservations.filter(r => grouped(r) === "delivered").length,
    cancelled: reservations.filter(r => grouped(r) === "cancelled").length,
  };
  // "진행 중" = active + transit
  counts.active = counts.active + counts.transit;

  const handleCancel = async (r) => {
    if (!CANCELLABLE.has(r.status)) return;
    const ok = window.confirm(
      "이 예약을 취소하시겠어요?\n결제 금액은 자동 환불됩니다."
    );
    if (!ok) return;
    setCancellingId(r.id);
    try {
      const callable = window.firebaseHttpsCallable(
        window.firebaseFunctions, "cancelReservation"
      );
      const { data } = await callable({ reservationId: r.id });
      if (data?.ok) {
        // onSnapshot 이 자동 반영
      } else {
        alert(data?.message || "예약을 취소할 수 없어요.");
      }
    } catch (e) {
      console.error("[my] cancelReservation error", e);
      alert(e?.message || "예약 취소 중 오류가 발생했어요.");
    } finally {
      setCancellingId(null);
    }
  };

  if (!authReady || !user) {
    return (
      <main style={{ minHeight: "60vh", display: "grid", placeItems: "center" }}>
        <div style={{ color: "var(--muted)", fontSize: 14 }}>로그인 확인 중…</div>
      </main>
    );
  }

  return (
    <main>
      <div className="my-shell">
        <aside className="my-sidebar">
          <div className="my-profile" style={{ marginBottom: 24 }}>
            <div className="avatar">{(user.displayName || "사")[0]}</div>
            <div>
              <div className="name">{user.displayName || user.email || "사용자"} 님</div>
              <div className="meta">일반회원</div>
            </div>
          </div>

          <ul className="my-nav">
            <li className="active">
              <span className="ic"><Icon name="package" size={16}/></span>
              예약 내역
              <span className="badge">{reservations.length}</span>
            </li>
            <li onClick={() => navigate('track')}>
              <span className="ic"><Icon name="search" size={16}/></span>
              조회 기록
            </li>
            <li onClick={() => navigate('addresses')}>
              <span className="ic"><Icon name="user" size={16}/></span>
              주소록
            </li>
          </ul>
        </aside>

        <section className="my-main">
          <div className="my-head">
            <div>
              <h1>예약 내역</h1>
              <p className="summary">
                {loading ? "예약 내역을 불러오는 중…" : `총 ${reservations.length}건`}
              </p>
            </div>
            <div className="actions">
              <button className="btn btn-primary btn-sm" onClick={() => navigate('reserve')}>
                <Icon name="bolt" size={13}/> 새 예약
              </button>
            </div>
          </div>

          <div className="status-pills">
            {STATUS_FILTERS.map(s => (
              <div key={s.key}
                className={`status-pill ${filter === s.key ? "active" : ""}`}
                onClick={() => setFilter(s.key)}>
                {s.label}
                <span className="count">{counts[s.key] || 0}</span>
              </div>
            ))}
          </div>

          {error && (
            <div style={{
              marginBottom: 16, padding: "12px 14px", borderRadius: 8,
              background: "rgba(220, 38, 38, 0.08)", color: "var(--danger)", fontSize: 13
            }}>
              {error}
            </div>
          )}

          {loading ? (
            <div style={{ padding: "60px 0", textAlign: "center", color: "var(--muted)", fontSize: 13 }}>
              불러오는 중…
            </div>
          ) : filtered.length === 0 ? (
            <div className="empty-state">
              <div className="ic"><Icon name="package" size={28} stroke={1.4}/></div>
              <h3>예약 내역이 없어요</h3>
              <p>첫 예약을 만들어보세요. 30초면 충분해요.</p>
              <button className="btn btn-primary" onClick={() => navigate('reserve')}>
                <Icon name="bolt" size={14}/> 새 예약 만들기
              </button>
            </div>
          ) : (
            <div className="res-list">
              {filtered.map(r => (
                <ResCard
                  key={r.id} r={r}
                  cancelling={cancellingId === r.id}
                  onCancel={() => handleCancel(r)}
                  navigate={navigate}
                />
              ))}
            </div>
          )}
        </section>
      </div>
    </main>
  );
};

const ResCard = ({ r, cancelling, onCancel, navigate }) => {
  const group = STATUS_GROUP[r.status] || "active";
  const isCvs = r.type === "convenience";
  const canCancel = CANCELLABLE.has(r.status);

  return (
    <div className="res-card">
      <div className="res-row-top">
        <div className="left">
          <span className="id">{r.id.slice(0, 8)}</span>
          <span className="date">{fmtTsDate(r.createdAt)} 예약</span>
          <span className="method">
            <Icon name={isCvs ? "warehouse" : "truck"} size={11}/>
            {METHOD_LABEL[r.type] || "택배"}
            {isCvs && r.cvsBrand ? ` · ${r.cvsBrand}` : ""}
          </span>
        </div>
        <span className={`status-badge ${group}`}>
          {group !== "cancelled" && <span className="dot"></span>}
          {STATUS_LABEL[r.status] || r.status}
        </span>
      </div>

      <div className="res-body">
        <div className="res-address">
          <div className="ic"><Icon name="pin" size={14}/></div>
          <div className="text">
            <div className="lbl">보내는 곳</div>
            <div className="who">{r.sndrNm || "—"}</div>
            <div className="addr">{r.sndrBaseAddr || ""} {r.sndrDtlAddr || ""}</div>
          </div>
        </div>

        <div className="res-address">
          <div className="ic"><Icon name="user" size={14}/></div>
          <div className="text">
            <div className="lbl">받는 곳</div>
            <div className="who">{r.rcvrNm || "—"}</div>
            <div className="addr">{r.rcvrBaseAddr || ""} {r.rcvrDtlAddr || ""}</div>
          </div>
        </div>

        <div className="res-meta">
          <div className="price">
            {Number(r.totalFee) > 0
              ? `${Number(r.totalFee).toLocaleString()}원`
              : (group === "cancelled" ? "환불 처리" : "—")}
          </div>
          <div>{boxSummary(r)} · {r.comodityNm || "물품"}</div>
        </div>
      </div>

      <div className="res-foot">
        <div className="res-progress-inline">
          {!isCvs && r.visitDate && (
            <>
              <Icon name="clock" size={14}/>
              <span className="step">방문일 {fmtTsDate(r.visitDate)}</span>
            </>
          )}
          {r.carrierName && (
            <span style={{ color: "var(--muted-2)" }}>· {r.carrierName}</span>
          )}
        </div>

        <div className="res-actions">
          {canCancel && (
            <button className="btn btn-outline btn-sm"
              disabled={cancelling}
              onClick={onCancel}>
              {cancelling ? "취소 중…" : "예약 취소"}
            </button>
          )}
          {group === "delivered" && (
            <button className="btn btn-primary btn-sm"
              onClick={() => navigate('reserve')}>
              <Icon name="bolt" size={13}/> 같은 곳에 다시
            </button>
          )}
          {group === "cancelled" && (
            <button className="btn btn-outline btn-sm"
              onClick={() => navigate('reserve')}>
              다시 예약
            </button>
          )}
        </div>
      </div>
    </div>
  );
};

window.MyReservations = MyReservations;
