// data.jsx — plan catalog (fetched from /api/plans) + shared API client + Store

// ── API client ────────────────────────────────────────────────────────────────
const API = {
  async get(path) {
    const res = await fetch(path, { credentials: "include" });
    const data = await res.json().catch(() => null);
    if (!res.ok) throw Object.assign(new Error(data?.error || path), { status: res.status, data });
    return data;
  },
  async post(path, body) {
    const res = await fetch(path, {
      method: "POST",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    const data = await res.json().catch(() => null);
    if (!res.ok) throw Object.assign(new Error(data?.error || path), { status: res.status, data });
    return data;
  },
};

// ── Auth store ────────────────────────────────────────────────────────────────
// Replaces localStorage; auth is now a real server session.
const Store = {
  _user: null,
  _esims: [],

  getAuth() { return this._user; },
  getEsims() { return this._esims; },

  async fetchMe() {
    try {
      this._user = await API.get("/api/me");
    } catch (_) {
      this._user = null;
    }
    window.dispatchEvent(new Event("journey-store"));
    return this._user;
  },

  async fetchEsims() {
    if (!this._user) { this._esims = []; return []; }
    try {
      this._esims = await API.get("/api/my-esims");
    } catch (_) {
      this._esims = [];
    }
    window.dispatchEvent(new Event("journey-store"));
    return this._esims;
  },

  async logout() {
    try { await API.post("/auth/logout", {}); } catch (_) {}
    this._user = null;
    this._esims = [];
    window.dispatchEvent(new Event("journey-store"));
  },

  async addEsim(plan) {
    const { esim } = await API.post("/api/purchase", { planId: plan.id });
    this._esims = [esim, ...this._esims];
    window.dispatchEvent(new Event("journey-store"));
    return esim;
  },

  async activateEsim(uid) {
    const { esim } = await API.post(`/api/activate/${uid}`, {});
    this._esims = this._esims.map(e => e.uid === uid ? esim : e);
    window.dispatchEvent(new Event("journey-store"));
    return esim;
  },

  async refreshEsimUsage(uid) {
    const { esim } = await API.post(`/api/esims/${uid}/refresh-usage`, {});
    this._esims = this._esims.map(e => e.uid === uid ? esim : e);
    window.dispatchEvent(new Event("journey-store"));
    return esim;
  },
};

// ── Plan catalog ──────────────────────────────────────────────────────────────
// Loaded lazily from /api/plans when the Marketplace route is opened.
// Until then, arrays stay empty so the home page avoids the full catalog payload.
let ESIM_PLANS = [];
let ESIM_BUNDLES = [];
let PLANS_LOADING = false;
let PLANS_LOADED = false;
let PLAN_CATALOG_META = { isLive: false, source: "loading", notice: "Loading plans" };
let PLAN_FILTERS = { types: [], regions: [], dataOptions: [], durations: [] };
let REGIONS = ["All", "Popular", "Europe", "Asia", "Americas", "Oceania", "Mideast", "Africa"];
const PLAN_SESSION_CACHE_KEY = "journey-plan-catalog-v6-retail";
const PLAN_SESSION_CACHE_TTL_MS = 10 * 60 * 1000;

const FEATURED_PLANS = [
  { id: "jp", country: "Japan", flag: "🇯🇵", region: "Asia", lat: 35.7, lng: 139.7, data: "1 GB", days: 7, price: 5.41, popular: true, net: "4G/5G", carriers: "Tokyo · Osaka · Kyoto", type: "country", source: "featured" },
  { id: "us", country: "United States", flag: "🇺🇸", region: "Americas", lat: 38.9, lng: -77.0, data: "1 GB", days: 7, price: 5.63, popular: true, net: "4G/5G", carriers: "Nationwide coverage", type: "country", source: "featured" },
  { id: "br", country: "Brazil", flag: "🇧🇷", region: "Americas", lat: -22.9, lng: -43.2, data: "1 GB", days: 7, price: 3.00, popular: true, net: "4G/5G", carriers: "Rio · Sao Paulo coverage", type: "country", source: "featured" },
  { id: "ar", country: "Argentina", flag: "🇦🇷", region: "Americas", lat: -34.6, lng: -58.4, data: "1 GB", days: 7, price: 3.00, popular: false, net: "4G/5G", carriers: "Buenos Aires coverage", type: "country", source: "featured" },
  { id: "uk", country: "United Kingdom", flag: "🇬🇧", region: "Europe", lat: 51.5, lng: -0.1, data: "1 GB", days: 7, price: 5.17, popular: true, net: "4G/5G", carriers: "London · UK coverage", type: "country", source: "featured" },
  { id: "fr", country: "France", flag: "🇫🇷", region: "Europe", lat: 48.85, lng: 2.35, data: "1 GB", days: 7, price: 5.17, popular: false, net: "4G/5G", carriers: "Paris · France coverage", type: "country", source: "featured" },
  { id: "de", country: "Germany", flag: "🇩🇪", region: "Europe", lat: 52.5, lng: 13.4, data: "1 GB", days: 7, price: 5.17, popular: false, net: "4G/5G", carriers: "Berlin · Germany coverage", type: "country", source: "featured" },
  { id: "it", country: "Italy", flag: "🇮🇹", region: "Europe", lat: 41.9, lng: 12.5, data: "1 GB", days: 7, price: 5.17, popular: false, net: "4G/5G", carriers: "Rome · Italy coverage", type: "country", source: "featured" },
  { id: "es", country: "Spain", flag: "🇪🇸", region: "Europe", lat: 40.4, lng: -3.7, data: "1 GB", days: 7, price: 5.17, popular: false, net: "4G/5G", carriers: "Madrid · Spain coverage", type: "country", source: "featured" },
  { id: "th", country: "Thailand", flag: "🇹🇭", region: "Asia", lat: 13.7, lng: 100.5, data: "1 GB", days: 7, price: 5.41, popular: true, net: "4G/5G", carriers: "Bangkok · Islands", type: "country", source: "featured" },
  { id: "sg", country: "Singapore", flag: "🇸🇬", region: "Asia", lat: 1.35, lng: 103.8, data: "1 GB", days: 7, price: 5.41, popular: false, net: "4G/5G", carriers: "Singapore coverage", type: "country", source: "featured" },
  { id: "kr", country: "South Korea", flag: "🇰🇷", region: "Asia", lat: 37.5, lng: 127.0, data: "1 GB", days: 7, price: 5.41, popular: true, net: "4G/5G", carriers: "Seoul · Korea coverage", type: "country", source: "featured" },
  { id: "au", country: "Australia", flag: "🇦🇺", region: "Oceania", lat: -33.8, lng: 151.2, data: "1 GB", days: 7, price: 5.41, popular: false, net: "4G/5G", carriers: "Sydney · Australia coverage", type: "country", source: "featured" },
  { id: "za", country: "South Africa", flag: "🇿🇦", region: "Africa", lat: -33.9, lng: 18.4, data: "1 GB", days: 7, price: 3.00, popular: true, net: "4G/5G", carriers: "Cape Town · Johannesburg coverage", type: "country", source: "featured" },
  { id: "ke", country: "Kenya", flag: "🇰🇪", region: "Africa", lat: -1.3, lng: 36.8, data: "1 GB", days: 7, price: 7.50, popular: false, net: "4G/5G", carriers: "Nairobi coverage", type: "country", source: "featured" },
  { id: "ma", country: "Morocco", flag: "🇲🇦", region: "Africa", lat: 31.6, lng: -7.9, data: "1 GB", days: 7, price: 3.00, popular: false, net: "4G/5G", carriers: "Marrakesh · Casablanca coverage", type: "country", source: "featured" },
  { id: "eu-reg", country: "Europe", flag: "🇪🇺", region: "Bundles", countries: ["Europe"], data: "1 GB", days: 7, price: 5.17, popular: true, net: "4G/5G", carriers: "Multi-country Europe", type: "regional", source: "featured", lat: 48.8, lng: 8.0 },
];

function applyPlanPayload(payload) {
  const all = (Array.isArray(payload) ? payload : (payload.plans || [])).map(plan => ({
    ...plan,
    net: /^4g\/5g$/i.test(String(plan.net || "").trim()) ? "" : plan.net,
  }));
  PLAN_CATALOG_META = Array.isArray(payload)
    ? { isLive: false, source: "legacy", notice: "Legacy catalog response" }
    : (payload.meta || PLAN_CATALOG_META);
  PLAN_FILTERS = Array.isArray(payload)
    ? { types: [], regions: [], dataOptions: [], durations: [] }
    : (payload.filters || PLAN_FILTERS);
  ESIM_BUNDLES = all.filter(p => p.region === "Bundles");
  ESIM_PLANS   = all.filter(p => p.region !== "Bundles");
  REGIONS = ["All", "Popular", ...PLAN_FILTERS.regions.filter(r => r !== "Bundles")];
  Object.assign(window, { ESIM_PLANS, ESIM_BUNDLES, PLAN_CATALOG_META, PLAN_FILTERS, REGIONS });
  window.dispatchEvent(new Event("journey-plans-loaded"));
}

function readPlanSessionCache() {
  try {
    const cached = JSON.parse(sessionStorage.getItem(PLAN_SESSION_CACHE_KEY) || "null");
    if (cached?.payload?.meta?.parserVersion !== 2) return null;
    if (cached?.payload && Date.now() - cached.cachedAt < PLAN_SESSION_CACHE_TTL_MS) return cached.payload;
  } catch (_) {}
  return null;
}

function writePlanSessionCache(payload) {
  try {
    sessionStorage.setItem(PLAN_SESSION_CACHE_KEY, JSON.stringify({ cachedAt: Date.now(), payload }));
  } catch (_) {}
}

async function loadPlans() {
  if (PLANS_LOADED || PLANS_LOADING) return;
  PLANS_LOADING = true;
  try {
    const cached = readPlanSessionCache();
    if (cached) {
      applyPlanPayload(cached);
      PLANS_LOADED = true;
      return;
    }

    const payload = await API.get("/api/plans");
    writePlanSessionCache(payload);
    applyPlanPayload(payload);
    PLANS_LOADED = true;
  } catch (e) {
    console.warn("[journey] Could not load plans from API:", e.message);
  } finally {
    PLANS_LOADING = false;
  }
}

// ── Travel poster art ─────────────────────────────────────────────────────────
const DESTINATION_ART = {
  jp:        { landmark: "Mt. Fuji · Tokyo",         sky: ["#ffb3c6", "#3a2c6e"], sun: "#fff0f3" },
  us:        { landmark: "Manhattan · New York",     sky: ["#ff9e7a", "#2b2d6b"], sun: "#ffe7c2" },
  uk:        { landmark: "Westminster · London",     sky: ["#cdd6e8", "#56678c"], sun: "#eef3ff" },
  fr:        { landmark: "Eiffel Tower · Paris",     sky: ["#f7c9a0", "#5d6ea8"], sun: "#fff3e0" },
  de:        { landmark: "Brandenburg · Berlin",     sky: ["#b3c6e0", "#2b3a6e"], sun: "#e8f0ff" },
  it:        { landmark: "Amalfi Coast · Rome",      sky: ["#ffb27a", "#2c6fb0"], sun: "#ffe9c9" },
  es:        { landmark: "Sagrada · Barcelona",      sky: ["#ffcaa3", "#bd553c"], sun: "#ffeccf" },
  th:        { landmark: "Phi Phi · Phuket",         sky: ["#ffd089", "#1f8e87"], sun: "#fff6d6" },
  sg:        { landmark: "Marina Bay · Singapore",   sky: ["#7ad0ff", "#2a2d6b"], sun: "#e8f6ff" },
  kr:        { landmark: "Gangnam · Seoul",          sky: ["#c9b3ff", "#352c6b"], sun: "#f0e8ff" },
  au:        { landmark: "Harbour · Sydney",         sky: ["#7be0d0", "#ff8c6b"], sun: "#fff0e0" },
  in:        { landmark: "Amber Fort · Jaipur",      sky: ["#ffb27a", "#a8453c"], sun: "#ffe0c2" },
  ae:        { landmark: "Burj Khalifa · Dubai",     sky: ["#ffd9a0", "#a8553c"], sun: "#fff1d6" },
  tr:        { landmark: "Bosphorus · Istanbul",     sky: ["#ffce8a", "#723b66"], sun: "#fff0d6" },
  ca:        { landmark: "Banff · Toronto",          sky: ["#a0e0d0", "#3a6b8c"], sun: "#e8fff8" },
  mx:        { landmark: "Cenotes · Tulum",          sky: ["#ffd089", "#d8603c"], sun: "#fff2cf" },
  br:        { landmark: "Copacabana · Rio",         sky: ["#ffcf6b", "#1f9e8a"], sun: "#fff6cf" },
  za:        { landmark: "Table Mountain · Cape Town",sky: ["#ffc46b", "#3a6ea8"], sun: "#ffeccf" },
  gr:        { landmark: "Santorini · Athens",       sky: ["#ffd6e0", "#2c6fb0"], sun: "#fff5f8" },
  pt:        { landmark: "Alfama · Lisbon",          sky: ["#ffcf9a", "#1a5e8c"], sun: "#fff3e0" },
  nl:        { landmark: "Canals · Amsterdam",       sky: ["#b3d4f0", "#2b4e8c"], sun: "#e8f4ff" },
  "eu-reg":      { landmark: "39 countries · one plan",  sky: ["#ffd089", "#56678c"], sun: "#fff2cf" },
  "asia-reg":    { landmark: "10 countries · one plan",  sky: ["#ff9ec0", "#2a6b8c"], sun: "#ffe6f0" },
  "ame-reg":     { landmark: "USA · Canada · Mexico",    sky: ["#ffce8a", "#1f9e8a"], sun: "#fff2cf" },
  "me-reg":      { landmark: "9 countries · Mideast",    sky: ["#ffd9a0", "#8c3a2a"], sun: "#fff5e0" },
  "latam-reg":   { landmark: "17 countries · Americas",  sky: ["#ffcf6b", "#2a8c6e"], sun: "#fff6cf" },
  "global-reg":  { landmark: "102 countries",            sky: ["#7ad0ff", "#54388c"], sun: "#e8f6ff" },
  "world-reg":   { landmark: "150+ countries",           sky: ["#c0e8ff", "#1a2a6c"], sun: "#e0f0ff" },
};
function destArt(id) {
  return DESTINATION_ART[id] || { landmark: "Worldwide", sky: ["#7ad0ff", "#54388c"], sun: "#e8f6ff" };
}

// ── Destination photos (Unsplash) ─────────────────────────────────────────────
const DESTINATION_PHOTOS = {
  jp: "1540959733332-eab4deabeeaf", us: "1496442226666-8d4d0e62e6e9",
  uk: "1513635269975-59663e0ac1ad", fr: "1502602898657-3e91760cbb34",
  de: "1570862687812-8b841fad0733", it: "1552832230-c0197dd311b5",
  es: "1583422409516-2895a77efded", th: "1528181304800-259b08848526",
  sg: "1525625293386-3f8f99389edd", kr: "1538485399081-7191377e8241",
  au: "1506973035872-a4ec16b8e8d9", in: "1524492412937-b28074a5d7da",
  ae: "1512453979798-5ea266f8880c", tr: "1541432901042-2d8bd64b4a9b",
  ca: "1517935706615-2717063c2225", mx: "1518638150340-f706e86654de",
  br: "1483729558449-99ef09a8c325", za: "1580060839134-75a5edca2e99",
  gr: "1570077188670-e3a8d69ac5ff", pt: "1746485415555-4188d435c8ff",
  nl: "1744072837147-7b142f6f3aaf",
  ar: "1589909202802-8f4aadce1849", ma: "1597212618440-806262de4f6b",
  ke: "1547471080-7cc2caa01a7e",
  "eu-reg":     "1471623320832-752e8bbf8413",
  "asia-reg":   "1535139262971-c51845709a48",
  "ame-reg":    "1485871981521-5b1fd3805eee",
  "me-reg":     "1512632578888-169bbbc64f33",
  "latam-reg":  "1483729558449-99ef09a8c325",
  "global-reg": "1451187580459-43490279c0fa",
  "world-reg":  "1451187580459-43490279c0fa",
};
function destPhoto(id, w = 600) {
  const pid = DESTINATION_PHOTOS[id];
  return pid ? `https://images.unsplash.com/photo-${pid}?w=${w}&q=80&auto=format&fit=crop` : null;
}

Object.assign(window, {
  API, Store, ESIM_PLANS, ESIM_BUNDLES, FEATURED_PLANS, REGIONS, loadPlans,
  DESTINATION_ART, destArt, DESTINATION_PHOTOS, destPhoto,
});
