import type { RegisterHotelStaffDto, StaffAccess } from "@/lib/types"; const API_ROOT = "/api"; let getPropertyId: () => string | null = () => null; /** Register property scope for hotel auth-API paths (e.g. staff management). */ export function registerHotelAuthApiContext(ctx: { getPropertyId: () => string | null; }) { getPropertyId = ctx.getPropertyId; } function shouldRewriteForHotel(path: string): boolean { const first = path.split("?")[0]; if (first.startsWith("/auth")) return false; if (first.startsWith("/properties")) return false; if (first.startsWith("/admin")) return false; return true; } function rewriteHotelPath(path: string): string { const pid = getPropertyId(); if (!pid || !shouldRewriteForHotel(path)) return path; const [pathname, query] = path.split("?"); const q = query ? `?${query}` : ""; return `/properties/${pid}/hotel${pathname}${q}`; } function apiUrl(path: string): string { const base = import.meta.env.VITE_API_BASE_URL ?? ""; const resolved = rewriteHotelPath(path); return `${base}${API_ROOT}${resolved}`; } export async function parseApiError(res: Response): Promise { const t = await res.text(); try { const j = JSON.parse(t) as { message?: string | string[]; error?: string }; if (Array.isArray(j.message)) return j.message.join(", "); if (typeof j.message === "string") return j.message; if (j.error) return j.error; } catch { /* ignore */ } return t || res.statusText; } export type AuthUser = { id: string; name: string; email?: string | null; phone?: string | null; role: string; status?: string; propertyId?: string | null; }; export async function postLogin(identifier: string, password: string) { const res = await fetch(apiUrl("/auth/login"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ identifier, password }), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise<{ access_token: string; user: AuthUser }>; } export async function postLoginPhoneRequest(phone: string) { const res = await fetch(apiUrl("/auth/login-phone-request"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ phone }), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise<{ message: string; loginRequestToken?: string; }>; } export async function postLoginPhoneVerify(loginRequestToken: string, otp: string) { const res = await fetch(apiUrl("/auth/login-phone-verify"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ loginRequestToken, otp }), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise<{ access_token: string; user: AuthUser }>; } export async function postSendOtp(identifier: string) { const res = await fetch(apiUrl("/auth/sendOtp"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ identifier: identifier.trim() }), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise<{ message: string }>; } export async function postHotelGuestLoginEmailOtp(email: string, otp: string) { const res = await fetch(apiUrl("/auth/hotel-user/login-email-otp"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: email.trim().toLowerCase(), otp: otp.trim() }), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise<{ access_token: string; user: AuthUser }>; } export type PropertyRow = { id: string; name: string; accommodationMode?: string; }; export async function getProfile(token: string) { const res = await fetch(apiUrl("/auth/profile"), { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise>; } export async function getProperties(token: string) { const res = await fetch(apiUrl("/properties/hotels"), { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise; } export async function getStaffAccess(token: string) { const res = await fetch(apiUrl("/staff-access"), { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) throw new Error(await parseApiError(res)); const data = await res.json(); return data.data || data as StaffAccess[]; } export async function postStaff(token: string, dto: RegisterHotelStaffDto) { const res = await fetch(apiUrl("/staff"), { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify(dto), }); if (!res.ok) throw new Error(await parseApiError(res)); return res.json() as Promise; } export async function deleteStaffAccess(token: string, accessId: string) { const res = await fetch(apiUrl(`/staff-access/${accessId}`), { method: "DELETE", headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) throw new Error(await parseApiError(res)); return; }