﻿/* =========================================================
   pages_booking.jsx — Book, My Bookings, Booking detail
   ========================================================= */

/* ---------------- helpers ---------------- */

/* ---------------- book page ---------------- */
function BookPage({ hotelId, roomIdx=0 }){
  const { wallet, createBooking } = useStore();
  const hotel = getHotel(hotelId);
  const availableRooms = hotel ? hotel.rooms.filter(r => r.isAvailable !== false) : [];
  const r0 = availableRooms[roomIdx] || availableRooms[0];
  const addDays=(iso,n)=>{ const d=new Date(iso); d.setDate(d.getDate()+n); return d.toISOString().slice(0,10); };
  const [checkIn, setCheckIn] = useState(()=> r0?.availFrom || isoPlusDays(14));
  const [checkOut, setCheckOut] = useState(()=> r0?.availFrom ? addDays(r0.availFrom,2) : isoPlusDays(17));
  const [guests, setGuests] = useState(2);
  const [guestName, setGuestName] = useState("");
  const [guestPhone, setGuestPhone] = useState("");
  const [guestEmail, setGuestEmail] = useState("");
  const [request, setRequest] = useState("");
  const [busy, setBusy] = useState(false);

  if(!hotel) return <div className="wrap" style={{padding:80}}>호텔을 찾을 수 없습니다.</div>;
  if(!wallet) return <ConnectGate title="예약하려면 지갑을 연결하세요" sub="예약금은 회원님 지갑에서 직접 맡겨집니다." />;

  const room = availableRooms[roomIdx] || availableRooms[0];
  const price = +room.price;
  const nights = nightsBetween(checkIn, checkOut);
  const amount = price * nights;
  const fee = amount * FEE_RATE;
  const total = amount + fee;
  const collateral = amount * hotel.depositRatio / 100;
  const ref = refundSchedule(checkIn);
  const infoOk = guestName.trim() && guestPhone.trim();
  const enough = wallet.balance >= total;
  // date validation against sales window + already-booked ranges
  const winFrom = room.availFrom, winTo = room.availTo;
  const inWindow = (!winFrom || checkIn >= winFrom) && (!winTo || checkOut <= winTo);
  const conflict = roomHasConflict(room, new Date(checkIn).toISOString(), new Date(checkOut).toISOString());
  const datesOk = inWindow && !conflict && nights>=1;
  const hasRoomAddress = !!(room && room.roomAddress);
  const canSubmit = infoOk && enough && datesOk && hasRoomAddress && !busy;

  async function confirm(){
    setBusy(true);
    try{
      const b = await createBooking({
        hotelId:hotel.id, roomName:room.name,
        roomAddress: room.roomAddress || null,
        checkIn:new Date(checkIn).toISOString(),
        checkOut:new Date(checkOut).toISOString(), nights, guests,
        guestName:guestName.trim(), guestPhone:guestPhone.trim(), guestEmail:guestEmail.trim(), request:request.trim(),
        pricePerNight:price, amountEth:amount, feeEth:fee, depositRatio:hotel.depositRatio, collateralEth:collateral,
      });
      navigate(`/bookings`);
    } finally { setBusy(false); }
  }

  return (
    <div className="page wrap" style={{maxWidth:980, padding:"30px 28px 70px"}}>
      <button className="btn btn-line btn-sm" onClick={()=>navigate(`/hotels/${hotel.id}`)} style={{marginBottom:18}}><Icon name="chevron" size={15} style={{transform:"rotate(180deg)"}}/>호텔로 돌아가기</button>
      <div style={{textAlign:"center",marginBottom:26}}>
        <FlowSteps step={0} />
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1fr 360px", gap:30, alignItems:"start"}}>
        {/* left form */}
        <div className="col gap-20">
          <div className="card card-pad row gap-14">
            <Photo seed={hotel.photos[0]} src={room.image||hotel.image} w={300} h={240} rounded={12} style={{width:96,height:80,flex:"none"}} />
            <div className="grow">
              <div className="row gap-8"><b>{hotel.name}</b><TierChip ratio={hotel.depositRatio}/></div>
              <div className="muted xs row gap-6" style={{marginTop:4}}><Icon name="mapPin" size={13}/>{hotel.city}</div>
              <div className="small" style={{marginTop:6}}>{room.name} · <span className="muted">{room.beds} · {room.size}</span></div>
            </div>
          </div>

          <div className="card card-pad col gap-16">
            <div className="row between">
              <b className="row gap-8"><Icon name="calendar" size={17} style={{color:"var(--clay)"}}/>날짜 선택</b>
              {winFrom && <span className="xs muted">판매 기간 {fmtDate(winFrom)} – {fmtDate(winTo)}</span>}
            </div>
            <div className="row gap-12">
              <div className="field grow"><label>체크인</label>
                <input className="input" type="date" value={checkIn} min={winFrom} max={winTo} onChange={e=>{setCheckIn(e.target.value); if(e.target.value>=checkOut){const d=new Date(e.target.value);d.setDate(d.getDate()+1);setCheckOut(d.toISOString().slice(0,10));}}} />
              </div>
              <div className="field grow"><label>체크아웃</label>
                <input className="input" type="date" value={checkOut} min={checkIn} max={winTo} onChange={e=>setCheckOut(e.target.value)} />
              </div>
            </div>
            {(room.bookedRanges||[]).length>0 && (
              <div className="col gap-6">
                <span className="xs muted row gap-6"><Icon name="info" size={13}/>이미 예약된 날짜는 선택할 수 없어요</span>
                <div className="chip-row">
                  {room.bookedRanges.map((r,i)=>(
                    <span key={i} className="tag" style={{color:"var(--muted)",textDecoration:"line-through"}}>{fmtDate(r.from)} – {fmtDate(r.to)}</span>
                  ))}
                </div>
              </div>
            )}
            {!inWindow && <div className="panel row gap-8" style={{padding:"10px 12px",borderColor:"oklch(0.585 0.16 28 / .35)"}}><Icon name="alert" size={15} style={{color:"var(--red)",flex:"none"}}/><span className="xs" style={{color:"var(--red)"}}>판매 기간({fmtDate(winFrom)} – {fmtDate(winTo)}) 안의 날짜를 선택해 주세요.</span></div>}
            {inWindow && conflict && <div className="panel row gap-8" style={{padding:"10px 12px",borderColor:"oklch(0.585 0.16 28 / .35)"}}><Icon name="alert" size={15} style={{color:"var(--red)",flex:"none"}}/><span className="xs" style={{color:"var(--red)"}}>선택하신 날짜에 이미 예약이 있어요. 다른 날짜를 골라주세요.</span></div>}
            <div className="field">
              <label>인원</label>
              <div className="row gap-12">
                <button className="btn btn-line btn-sm" onClick={()=>setGuests(g=>Math.max(1,g-1))}><Icon name="minus" size={14}/></button>
                <b className="tnum" style={{minWidth:24,textAlign:"center"}}>{guests}명</b>
                <button className="btn btn-line btn-sm" onClick={()=>setGuests(g=>Math.min(room.cap,g+1))}><Icon name="plus" size={14}/></button>
                <span className="xs muted">최대 {room.cap}인</span>
              </div>
            </div>
          </div>

          {/* guest info */}
          <div className="card card-pad col gap-16">
            <div className="row between">
              <b className="row gap-8"><Icon name="user" size={17} style={{color:"var(--clay)"}}/>예약자 정보</b>
              <span className="xs muted"><span style={{color:"var(--clay-ink)"}}>*</span> 필수 입력</span>
            </div>
            <div className="row gap-12 wrap-row">
              <div className="field grow" style={{minWidth:180}}><label>예약자 이름 <span style={{color:"var(--clay-ink)"}}>*</span></label>
                <input className="input" placeholder="예: 홍길동" value={guestName} onChange={e=>setGuestName(e.target.value)} />
              </div>
              <div className="field grow" style={{minWidth:180}}><label>연락처 <span style={{color:"var(--clay-ink)"}}>*</span></label>
                <input className="input" placeholder="예: 010-1234-5678" value={guestPhone} onChange={e=>setGuestPhone(e.target.value)} />
              </div>
            </div>
            <div className="field"><label>이메일 <span className="muted xs">(선택)</span></label>
              <input className="input" type="email" placeholder="예약 확인 메일을 받을 주소" value={guestEmail} onChange={e=>setGuestEmail(e.target.value)} />
            </div>
            <div className="field"><label>요청 사항 <span className="muted xs">(선택)</span></label>
              <textarea className="input" rows={2} style={{resize:"vertical",lineHeight:1.5}} placeholder="예: 늦은 체크인 예정, 고층 객실 희망 등" value={request} onChange={e=>setRequest(e.target.value)} />
            </div>
          </div>

          {/* refund policy */}
          <div className="card card-pad col gap-12">
            <b className="row gap-8"><Icon name="info" size={17} style={{color:"var(--clay)"}}/>취소 환불 정책</b>
            <div className="row gap-8 wrap-row">
              {REFUND_RULES.map(r=>(
                <div key={r.k} className="panel" style={{padding:"9px 13px",flex:1,minWidth:110,textAlign:"center"}}>
                  <div className="serif" style={{fontSize:20,fontWeight:700,color:r.v==="0%"?"var(--muted)":"var(--green-deep)"}}>{r.v}</div>
                  <div className="xs muted">{r.k}</div>
                </div>
              ))}
            </div>
            <div className="row gap-8 xs muted"><Icon name="check" size={14} style={{color:"var(--green)"}}/>선택하신 체크인 기준 현재 <b style={{color:"var(--green-deep)"}}>D-{ref.days} · 환불 {ref.pct}%</b> 구간입니다.</div>
          </div>
        </div>

        {/* right: payment summary */}
        <aside className="card card-pad col gap-14" style={{position:"sticky",top:"calc(var(--header-h) + 20px)"}}>
          <b>결제 요약</b>
          <div className="kvs">
            <div className="kv"><span className="k">{fmtEth(price)} ETH × {nights}박</span><span className="v mono">{fmtEth(amount)} ETH</span></div>
            <div className="kv"><span className="k">프로토콜 수수료 (0.5%)</span><span className="v mono">{fmtEth(fee)} ETH</span></div>
            <div className="kv"><span className="k row gap-6" style={{color:"var(--ink)"}}><b>예치 합계</b></span><span className="v mono serif" style={{fontSize:18}}>{fmtEth(total)} ETH</span></div>
          </div>

          <div className="panel" style={{padding:14}}>
            <div className="row gap-8 xs" style={{fontWeight:700,color:"var(--green-deep)",marginBottom:10,whiteSpace:"nowrap"}}><Icon name="shieldCheck" size={14}/>보증금 보관 내역</div>
            <DepositViz ratio={hotel.depositRatio} amount={amount} />
          </div>

          <div className="row between xs muted">
            <span>지갑 잔액</span>
            <span className="mono" style={{color:enough?"var(--ink-2)":"var(--red)"}}>{fmtEth(wallet.balance)} ETH</span>
          </div>

          <button className="btn btn-primary btn-lg btn-block" disabled={!canSubmit} onClick={confirm}>
            {busy? <span className="spin" style={{borderTopColor:"#fff",borderColor:"oklch(1 0 0 /.4)"}}></span> : <Icon name="wallet" size={18}/>}
            {!hasRoomAddress? "온체인 객실이 아닙니다" : !datesOk? "예약 가능한 날짜를 선택하세요" : !enough? "잔액 부족" : !infoOk? "예약자 정보를 입력하세요" : `예약하고 결제 · ${fmtEth(total)} ETH`}
          </button>
          <div className="xs muted center" style={{textAlign:"center",lineHeight:1.5}}>
            <Icon name="lock" size={12}/> 예약을 확정하면 예약금이 이용 전까지 안전하게 보관됩니다.
          </div>
        </aside>
      </div>
    </div>
  );
}

/* ---------------- my bookings ---------------- */
function MyBookingsPage(){
  const { wallet, bookings } = useStore();
  const [tab, setTab] = useState("all");
  if(!wallet) return <ConnectGate />;

  const tabs = [["all","전체"],["booked","예약중"],["checkedin","체크인"],["completed","완료"],["cancelled","취소/보상"]];
  const filtered = bookings.filter(b=>{
    if(tab==="all") return true;
    if(tab==="cancelled") return b.status==="cancelled"||b.status==="disputed";
    return b.status===tab;
  });

  return (
    <div className="page wrap" style={{maxWidth:920, padding:"34px 28px 64px"}}>
      <div className="row between wrap-row gap-12" style={{marginBottom:8}}>
        <div>
          <span className="eyebrow">My Bookings</span>
          <h1 className="display d2" style={{marginTop:6}}>내 예약</h1>
        </div>
        <div className="panel row gap-8" style={{padding:"8px 13px"}}>
          <span className="avatar" style={{width:22,height:22}}></span>
          <span className="mono small">{shortAddr(wallet.address)}</span>
          <span className="muted xs">기준 조회</span>
        </div>
      </div>

      <div className="seg" style={{maxWidth:560,margin:"18px 0 22px"}}>
        {tabs.map(([k,l])=> <button key={k} className={tab===k?"on":""} onClick={()=>setTab(k)}>{l}</button>)}
      </div>

      {filtered.length===0 ? (
        <div className="card card-pad center col gap-12" style={{padding:60,textAlign:"center"}}>
          <Icon name="calendar" size={32} style={{color:"var(--faint)"}}/>
          <div className="muted">해당하는 예약이 없습니다.</div>
          <button className="btn btn-soft btn-sm" onClick={()=>navigate("/hotels")}>호텔 찾아보기</button>
        </div>
      ) : (
        <div className="col gap-14">
          {filtered.map(b=> <BookingRow key={b.id} b={b} />)}
        </div>
      )}
    </div>
  );
}

function BookingRow({ b }){
  const hotel = getHotel(b.hotelId);
  return (
    <button className="card fade-in" onClick={()=>navigate(`/bookings/${b.id}`)}
      style={{display:"flex",gap:18,padding:14,textAlign:"left",alignItems:"center",cursor:"pointer"}}>
      <Photo seed={hotel?hotel.photos[0]:b.hotelId} src={hotel?hotel.image:""} w={300} h={240} rounded={12} style={{width:120,height:92,flex:"none"}} />
      <div className="grow col gap-6">
        <div className="row gap-10"><StatusBadge status={b.status}/><span className="mono xs muted">{b.id}</span></div>
        <div className="h-md">{hotelName(b.hotelId)}</div>
        <div className="row gap-12 muted xs">
          <span className="row gap-4"><Icon name="calendar" size={13}/>{fmtDate(b.checkIn)} – {fmtDate(b.checkOut)} · {b.nights}박</span>
          <span className="row gap-4"><Icon name="user" size={13}/>{b.guests}명</span>
        </div>
      </div>
      <div className="col" style={{textAlign:"right",alignItems:"flex-end",gap:6}}>
        <div><b className="mono">{fmtEth(b.amountEth)}</b> <span className="xs muted">ETH</span></div>
        <span className="badge badge-green xs"><Icon name="shieldCheck" size={12}/>보증 {b.depositRatio}%</span>
        <Icon name="chevron" size={16} style={{color:"var(--faint)"}}/>
      </div>
    </button>
  );
}

/* ---------------- booking detail + actions ---------------- */
function BookingDetailPage({ id }){
  const { wallet, bookings, checkIn:doCheckIn, checkout, reportIssue, cancelByGuest } = useStore();
  const [modal, setModal] = useState(null); // 'cancel' | 'report'
  if(!wallet) return <ConnectGate />;
  const b = bookings.find(x=>x.id===id);
  if(!b) return <div className="wrap" style={{padding:80}}>예약을 찾을 수 없습니다. <a className="link-clay" onClick={()=>navigate("/my-bookings")} style={{cursor:"pointer"}}>내 예약으로</a></div>;
  const hotel = getHotel(b.hotelId);
  const ref = refundSchedule(b.checkIn);
  const refundEth = +(b.amountEth*ref.pct/100).toFixed(4);

  return (
    <div className="page wrap" style={{maxWidth:1000, padding:"24px 28px 70px"}}>
      <button className="btn btn-line btn-sm" onClick={()=>navigate("/my-bookings")} style={{marginBottom:16}}><Icon name="chevron" size={15} style={{transform:"rotate(180deg)"}}/>내 예약</button>

      {/* header banner */}
      <div className="card" style={{padding:0,overflow:"hidden",marginBottom:22}}>
        <div style={{position:"relative",height:170}}>
          <Photo seed={hotel?hotel.photos[0]:b.hotelId} src={hotel?hotel.image:""} w={1400} h={500} style={{position:"absolute",inset:0}} />
          <div style={{position:"absolute",inset:0,background:"linear-gradient(90deg, oklch(0.24 0.05 266 / .78), oklch(0.28 0.05 262 / .25))"}}></div>
          <div className="col gap-8" style={{position:"relative",padding:"22px 26px",color:"#fff",height:"100%",justifyContent:"flex-end"}}>
            <div className="row gap-10"><StatusBadge status={b.status}/><span className="mono small" style={{color:"oklch(0.92 0.015 250)"}}>{b.id}</span></div>
            <div className="display d3" style={{color:"#fff"}}>{hotelName(b.hotelId)}</div>
            <div className="row gap-12 small" style={{color:"oklch(0.92 0.015 250)"}}>
              <span className="row gap-6"><Icon name="calendar" size={14}/>{fmtDateFull(b.checkIn)} → {fmtDateFull(b.checkOut)}</span>
            </div>
          </div>
        </div>
      </div>

      <div style={{display:"grid",gridTemplateColumns:"1fr 360px",gap:30,alignItems:"start"}}>
        {/* left: info + escrow + timeline */}
        <div className="col gap-20">
          {b.status==="checkedin" && <TimeoutBanner b={b} />}

          <div className="card card-pad">
            <b className="row gap-8" style={{marginBottom:14}}><Icon name="info" size={17} style={{color:"var(--clay)"}}/>예약 정보</b>
            <div className="kvs">
              <div className="kv"><span className="k">객실</span><span className="v">{b.roomName}</span></div>
              <div className="kv"><span className="k">체크인 / 체크아웃</span><span className="v">{fmtDate(b.checkIn)} → {fmtDate(b.checkOut)}</span></div>
              <div className="kv"><span className="k">숙박</span><span className="v">{b.nights}박 · {b.guests}명</span></div>
              {b.guestName && <div className="kv"><span className="k">예약자</span><span className="v">{b.guestName}{b.guestPhone? ` · ${b.guestPhone}`:""}</span></div>}
              {b.request && <div className="kv"><span className="k">요청 사항</span><span className="v allow-wrap" style={{maxWidth:280}}>{b.request}</span></div>}
              <div className="kv"><span className="k">예약 생성</span><span className="v">{fmtAgo(b.createdAt)}</span></div>
            </div>
          </div>

          {/* escrow vault */}
          <div className="card card-pad">
            <div className="row between" style={{marginBottom:14}}>
              <b className="row gap-8"><Icon name="lock" size={17} style={{color:"var(--green-deep)"}}/>보증금 보관 현황</b>
              <span className="badge badge-green"><Icon name="shieldCheck" size={13}/>{trustTier(b.depositRatio).label}</span>
            </div>
            <div className="row gap-22 wrap-row" style={{alignItems:"center"}}>
              <TrustMeter ratio={b.depositRatio} size={120}/>
              <div className="grow" style={{minWidth:230}}><DepositViz ratio={b.depositRatio} amount={b.amountEth} /></div>
            </div>
            <hr className="hairline" style={{margin:"16px 0"}}/>
            <div className="kvs">
              <div className="kv"><span className="k">회원 예약금</span><span className="v mono">{fmtEth(b.amountEth)} ETH</span></div>
              <div className="kv"><span className="k">호텔 보증금 (담보)</span><span className="v mono" style={{color:"var(--green-deep)"}}>{fmtEth(b.collateralEth)} ETH</span></div>
              <div className="kv"><span className="k">분쟁 시 최대 보상</span><span className="v mono"><b>{fmtEth(b.amountEth+b.collateralEth)} ETH</b></span></div>
            </div>
          </div>

          {/* timeline */}
          <BookingTimeline b={b} />
        </div>

        {/* right: action panel */}
        <aside className="card card-pad col gap-14" style={{position:"sticky",top:"calc(var(--header-h)+20px)"}}>
          <ActionPanel b={b} ref0={ref} refundEth={refundEth}
            onCheckIn={()=>doCheckIn(b.id)}
            onCheckout={()=>checkout(b.id)}
            onReport={()=>setModal("report")}
            onCancel={()=>setModal("cancel")}
          />
          <hr className="hairline"/>
          <a className="link-clay xs row gap-6" href={`https://sepolia.etherscan.io/tx/${b.txHash}`} target="_blank" rel="noreferrer">
            <Icon name="external" size={13}/>거래 내역 확인 · {shortHash(b.txHash)}
          </a>
        </aside>
      </div>

      {modal==="cancel" && (
        <Modal onClose={()=>setModal(null)}>
          <div className="card-pad col gap-16">
            <div className="row gap-10"><span className="logo-mark" style={{background:"var(--amber-soft)"}}><Icon name="info" size={18} style={{color:"var(--amber-deep)"}}/></span><div className="h-md">예약을 취소할까요?</div></div>
            <div className="panel" style={{padding:14}}>
              <div className="row between"><span className="muted small">현재 구간</span><b className="small">{ref.tierLabel} · D-{ref.days}</b></div>
              <hr className="hairline" style={{margin:"10px 0"}}/>
              <div className="row between"><span className="muted small">환불 비율</span><b className="serif" style={{fontSize:20,color:ref.pct?"var(--green-deep)":"var(--muted)"}}>{ref.pct}%</b></div>
              <div className="row between" style={{marginTop:6}}><span className="muted small">환급 예정액</span><b className="mono">{fmtEth(refundEth)} ETH</b></div>
            </div>
            <div className="chip-row">
              {REFUND_RULES.map(r=> <span key={r.k} className={"tag "+(r.k===ref.tierLabel?"":"")} style={r.k===ref.tierLabel?{borderColor:"var(--clay)",color:"var(--clay-ink)",fontWeight:700}:{}}>{r.k} {r.v}</span>)}
            </div>
            <div className="row gap-10">
              <button className="btn btn-line grow" onClick={()=>setModal(null)}>돌아가기</button>
              <button className="btn btn-danger grow" onClick={async()=>{setModal(null); await cancelByGuest(b.id, ref.pct, refundEth);}}>예약 취소하기</button>
            </div>
          </div>
        </Modal>
      )}

      {modal==="report" && (
        <Modal onClose={()=>setModal(null)}>
          <div className="card-pad col gap-16">
            <div className="row gap-10"><span className="logo-mark" style={{background:"var(--red-soft)"}}><Icon name="alert" size={18} style={{color:"var(--red)"}}/></span><div className="h-md">호텔 귀책 문제를 신고할까요?</div></div>
            <p className="small muted" style={{lineHeight:1.6}}>오버부킹, 시설 미제공 등 호텔 귀책 사유 발생 시 사용하세요. 신고가 서명되면 <b style={{color:"var(--ink)"}}>예약금과 호텔 보증금 전액</b>이 사람의 승인 없이 즉시 회원님 지갑으로 이체됩니다.</p>
            <div className="vault row between" style={{alignItems:"center"}}>
              <div><div className="xs muted">즉시 보상 금액</div><div className="mono serif" style={{fontSize:24,fontWeight:700}}>{fmtEth(b.amountEth+b.collateralEth)} ETH</div></div>
              <Icon name="bolt" size={30} style={{color:"var(--clay)"}}/>
            </div>
            <div className="row gap-10">
              <button className="btn btn-line grow" onClick={()=>setModal(null)}>돌아가기</button>
              <button className="btn btn-primary grow" onClick={async()=>{setModal(null); await reportIssue(b.id);}}>문제 신고하기</button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}

/* action buttons by status */
function ActionPanel({ b, ref0, refundEth, onCheckIn, onCheckout, onReport, onCancel }){
  if(b.status==="booked"){
    return (
      <>
        <b>예약 액션</b>
        <div className="panel" style={{padding:"11px 13px"}}><div className="row gap-8 xs muted"><Icon name="info" size={14}/>호텔 도착 후 체크인을 기록하세요.</div></div>
        <button className="btn btn-green btn-lg btn-block" onClick={onCheckIn}><Icon name="key" size={18}/>체크인 완료</button>
        <button className="btn btn-danger btn-block" onClick={onCancel}><Icon name="x" size={16}/>예약 취소 · 환불 {ref0.pct}%</button>
      </>
    );
  }
  if(b.status==="checkedin"){
    return (
      <>
        <b>이용 중 액션</b>
        <div className="panel" style={{padding:"11px 13px"}}><div className="row gap-8 xs muted"><Icon name="info" size={14}/>정상 이용 후 체크아웃 서명, 문제 발생 시 신고하세요.</div></div>
        <button className="btn btn-primary btn-lg btn-block" onClick={onCheckout}><Icon name="check" size={18}/>체크아웃 완료 · 호텔 송금</button>
        <button className="btn btn-danger btn-block" onClick={onReport}><Icon name="alert" size={16}/>문제 발생 신고</button>
      </>
    );
  }
  // terminal states
  const map = {
    completed:["이용이 정상 완료되었습니다","호텔로 예약금이 송금되고 보증금이 반환되었습니다.","badge-green","check"],
    cancelled:["예약이 취소되었습니다",`환불 ${b.refundPct??0}% · ${fmtEth(b.refundEth||0)} ETH 가 환급되었습니다.`,"badge-gray","x"],
    disputed:["보상이 집행되었습니다",`예약금+보증금 ${fmtEth(b.refundEth||0)} ETH 가 회원님 지갑으로 이체되었습니다.`,"badge-red","bolt"],
  }[b.status];
  return (
    <>
      <b>처리 완료</b>
      <div className="vault col gap-10" style={{alignItems:"center",textAlign:"center"}}>
        <span className="logo-mark" style={{width:46,height:46,borderRadius:14,background:"var(--green)"}}><Icon name={map[3]} size={22} style={{color:"#fff"}}/></span>
        <b>{map[0]}</b>
        <div className="small muted" style={{lineHeight:1.5}}>{map[1]}</div>
      </div>
      <button className="btn btn-soft btn-block" onClick={()=>navigate("/hotels")}>다른 호텔 둘러보기</button>
    </>
  );
}

/* 24h timeout countdown after checkout date */
function TimeoutBanner({ b }){
  const deadline = new Date(b.checkOut).getTime() + 86400000;
  const [now, setNow] = useState(Date.now());
  useEffect(()=>{ const t=setInterval(()=>setNow(Date.now()),1000); return ()=>clearInterval(t); },[]);
  const rem = deadline - now;
  const past = rem<=0;
  const h = Math.max(0,Math.floor(rem/3600000));
  const m = Math.max(0,Math.floor((rem%3600000)/60000));
  const s = Math.max(0,Math.floor((rem%60000)/1000));
  return (
    <div className="card card-pad" style={{borderColor:past?"oklch(0.585 0.16 28 / .4)":"var(--line)", background:past?"var(--red-soft)":"linear-gradient(165deg,var(--clay-soft),var(--surface))"}}>
      <div className="row between wrap-row gap-12">
        <div className="col gap-4">
          <div className="row gap-8"><span className="live-dot"></span><b className="small" style={{whiteSpace:"nowrap"}}>{past?"타임아웃 경과":"체크아웃 타임아웃"}</b></div>
          <div className="xs muted" style={{maxWidth:300}}>{past? "체크아웃을 누르지 않아, 24시간이 지나 자동으로 정산될 수 있어요." : "체크아웃을 누르지 않으면 24시간 뒤 자동으로 정산돼요."}</div>
        </div>
        <div className="mono" style={{fontSize:26,fontWeight:600,letterSpacing:".02em",color:past?"var(--red)":"var(--clay-ink)"}}>
          {past? "00:00:00" : `${String(h).padStart(2,"0")}:${String(m).padStart(2,"0")}:${String(s).padStart(2,"0")}`}
        </div>
      </div>
    </div>
  );
}

/* on-chain style timeline */
function BookingTimeline({ b }){
  const events = [
    { t:"예약 결제 완료", fn:"createBooking()", at:b.createdAt, done:true },
    { t:"체크인 기록", fn:"checkIn()", at:b.checkinAt, done:!!b.checkinAt },
  ];
  if(b.status==="completed") events.push({ t:"체크아웃 정산", fn:"checkout()", at:b.checkoutAt, done:true });
  if(b.status==="disputed") events.push({ t:"문제 신고 · 보상 집행", fn:"reportIssue()", at:b.checkoutAt, done:true, warn:true });
  if(b.status==="cancelled") events.push({ t:"예약 취소 · 환불", fn:"cancelByGuest()", at:Date.now(), done:true });
  return (
    <div className="card card-pad">
      <b className="row gap-8" style={{marginBottom:14}}><Icon name="clock" size={17} style={{color:"var(--clay)"}}/>예약 진행 내역</b>
      <div>
        {events.map((e,i)=>(
          <div key={i}>
            <div className="row gap-12" style={{padding:"6px 0"}}>
              <span className="txdot" style={{width:28,height:28,background:e.done?(e.warn?"var(--red)":"var(--green)"):"var(--surface-3)",borderColor:e.done?(e.warn?"var(--red)":"var(--green)"):"var(--line-2)",color:e.done?"#fff":"var(--muted)"}}>
                {e.done? <Icon name={e.warn?"bolt":"check"} size={14}/> : i+1}
              </span>
              <div className="grow row between">
                <div><div style={{fontWeight:600,fontSize:14}}>{e.t}</div></div>
                <div className="xs muted">{e.at? fmtAgo(e.at):"대기 중"}</div>
              </div>
            </div>
            {i<events.length-1 && <div style={{width:1,height:16,background:"var(--line-2)",marginLeft:14}}></div>}
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { BookPage, MyBookingsPage, BookingDetailPage });
