




window.RailBookStore = (function () {
const KEY = "railbook-v2";
function defaultState() {
return {
coaches: window.RailBookData.generateCoaches(),
recent: [],
selection:
};
}
function load() {
try {
const raw = localStorage.getItem(KEY);
if (!raw) return defaultState();
const parsed = JSON.parse(raw);
const base = defaultState();
const coaches = parsed.coaches;
const firstCoach = coaches && coaches.C1;
const valid =
coaches &&
firstCoach &&
Array.isArray(firstCoach) &&
firstCoach.length === window.RailBookData.SEATS_PER_COACH;
return {
...base,
recent: parsed.recent || [],
selection: parsed.selection || base.selection,
coaches: valid ? coaches : base.coaches
};
} catch {
return defaultState();
}
}
function save(state) {
localStorage.setItem(KEY, JSON.stringify(state));
}
function getCoach(state, coachId) {
return state.coaches[coachId] || null;
}
function updateCoach(state, coachId, mutator) {
const seats = state.coaches[coachId];
if (!seats) return false;
mutator(seats);
return true;
}
function getTotals(state) {
const all = window.RailBookData.COACH_IDS.flatMap((id) => state.coaches[id]);
const booked = all.filter((s) => s.status === "booked").length;
const seniorHeld = all.filter((s) => s.seniorReserved && s.status === "available").length;
return {
total: all.length,
booked,
available: all.length - booked - seniorHeld
};
}
function findSeatByTicket(state, ticketId) {
const id = ticketId.trim().toUpperCase();
for (const coachId of window.RailBookData.COACH_IDS) {
const seat = state.coaches[coachId].find(
(s) => s.ticketId && s.ticketId.toUpperCase() === id
);
if (seat) return { coachId, seat };
}
return null;
}
function makeTicketId() {
return TKT-${Date.now().toString(36).toUpperCase().slice(-8)};
}
function reset() {
localStorage.removeItem(KEY);
return defaultState();
}
return {
KEY,
defaultState,
load,
save,
getCoach,
updateCoach,
getTotals,
findSeatByTicket,
makeTicketId,
reset
};
})();