import { defaultState, saveState } from "./state.js";
import { refreshOffers } from "./conveyor.js";
import { render } from "./ui.js";
import { startGameLoop } from "./game-loop.js";
import { playSound, setMusicEnabled, setMusicGetState } from "./audio.js";
import { resolveIncident, INCIDENT_EMOJI } from "./visitor-incidents.js";
import { getAttractionCenter, getVisitorPosition } from "./visitor-attraction.js";
import { incidentLabel, incidentBubbleAria } from "./texts-fr.js";
import { getApiBase, loadZoos, saveMyZoo, setApiBaseUrl } from "./api-client.js";
import { bootstrapFromApi, applyWorldZoos } from "./main-bootstrap.js";

const root = document.getElementById("root");
if (!root) throw new Error("Missing #root");

let state = null;
let myZooId = null;

function setMyZooId(id) {
  myZooId = id;
}

async function runBootNoBase(rootEl) {
  rootEl.innerHTML = "<div class=\"boot-panel\"><h1>Construis un zoo</h1>" +
    "<p>Connectez-vous à un serveur pour jouer (compte et sauvegarde en base).</p>" +
    "<div style=\"margin-top: 1rem;\"><label for=\"boot-api-url\">URL du serveur</label><input id=\"boot-api-url\" type=\"text\" placeholder=\"https://...\" style=\"display:block;margin-top:4px;width:100%;\" /></div>" +
    "<button id=\"boot-connect\" type=\"button\" style=\"margin-top: 8px;\">Se connecter</button>" +
    "<p id=\"boot-err\" class=\"boot-err\"></p></div>";
  const urlInput = document.getElementById("boot-api-url");
  try {
    const stored = localStorage.getItem("builazoo_api_url");
    if (stored) urlInput.value = stored;
  } catch (_) {
    // ignore localStorage
  }
  const errEl = document.getElementById("boot-err");
  await new Promise((resolve) => {
    document.getElementById("boot-connect").addEventListener("click", () => {
      const url = urlInput.value.trim();
      if (!url) {
        errEl.textContent = "Indiquez l'URL du serveur.";
        return;
      }
      setApiBaseUrl(url);
      resolve();
    });
  });
  rootEl.innerHTML = "";
}

async function runBootWithBase(rootEl) {
  rootEl.innerHTML = "<div class=\"boot-panel\"><p>Chargement…</p></div>";
  while (true) {
    try {
      state = await bootstrapFromApi(setMyZooId, rootEl);
      break;
    } catch (e) {
      console.error("bootstrapFromApi failed", e);
      rootEl.innerHTML = "<div class=\"boot-panel\"><h1>Construis un zoo</h1><p class=\"boot-err\">Erreur de connexion au serveur.</p><button id=\"boot-retry\" type=\"button\">Réessayer</button></div>";
      const errP = rootEl.querySelector(".boot-err");
      if (errP && e && e.message) errP.textContent = e.message;
      await new Promise((resolve) => {
        document.getElementById("boot-retry").addEventListener("click", () => resolve());
      });
    }
  }
  rootEl.innerHTML = "";
}

(async () => {
  let base = getApiBase();
  if (!base) {
    await runBootNoBase(root);
    base = getApiBase();
  }
  if (base) {
    await runBootWithBase(root);
  }
  if (state) {

  try {
    if (localStorage.getItem("builazoo_music") === "1") setMusicEnabled(true);
  } catch (_) {
    // ignore localStorage
  }

  let lastHatched = [];
  let fullRender = () => {};
  function getState() {
    return state;
  }
  function doRestart() {
    state = defaultState();
    const nowUnix = Math.floor(Date.now() / 1000);
    refreshOffers(state, nowUnix);
    saveState(state);
    fullRender();
  }
  fullRender = render(root, {
    state: getState(),
    setState: () => fullRender(),
    getLastHatched: () => lastHatched,
    onRestart: doRestart,
    updateState: (partial) => {
      Object.assign(state, partial);
      fullRender();
    },
  });

  let lastApiSaveAt = 0;
  const MIN_API_SAVE_INTERVAL_MS = 5000;
  function saveStateFn(s) {
    saveState(s);
    if (getApiBase()) {
      const now = Date.now();
      if (now - lastApiSaveAt >= MIN_API_SAVE_INTERVAL_MS) {
        lastApiSaveAt = now;
        saveMyZoo(s).catch((e) => console.warn("saveMyZoo failed", e));
      }
    }
  }

  setMusicGetState(getState);
  startGameLoop(getState, (s, payload) => {
    if (payload?.lastHatched?.length) {
      lastHatched = payload.lastHatched;
      playSound("hatch");
    }
    fullRender();
    setTimeout(() => { lastHatched = []; fullRender(); }, 1800);
  }, saveStateFn);

  const ZOOS_REFETCH_INTERVAL_MS = 30 * 1000;
  setInterval(() => {
    loadZoos().then((zoosData) => {
      applyWorldZoos(state, { zoosData, playerZooId: state.myZooId ?? myZooId, playerName: state.playerName ?? "Mon zoo", playerX: state.playerX ?? 25, playerY: state.playerY ?? 50 });
      fullRender();
    }).catch(() => {});
  }, ZOOS_REFETCH_INTERVAL_MS);

  let visitorAnimTime = 0;
  function syncVisitorBubble(el, visitor, index) {
    const incidentType = visitor && (visitor.incidentType === null || visitor.incidentType === undefined)
      ? null
      : (visitor && visitor.incidentType);
    let bubble = el.querySelector(".visitor-incident-bubble");
    if (incidentType) {
      if (!bubble) {
        bubble = document.createElement("span");
        bubble.className = "visitor-incident-bubble";
        bubble.setAttribute("role", "button");
        bubble.setAttribute("tabindex", "0");
        bubble.setAttribute("aria-label", incidentBubbleAria);
        bubble.addEventListener("click", () => {
          if (resolveIncident(getState(), index)) fullRender();
        });
        el.appendChild(bubble);
      }
      bubble.textContent = INCIDENT_EMOJI[incidentType] ?? "❓";
      bubble.title = incidentLabel[incidentType] ?? incidentType;
    } else if (bubble) {
      bubble.remove();
    }
  }
  function updateVisitors() {
    const layer = root.querySelector(".visitors-layer");
    if (!layer) {
      requestAnimationFrame(updateVisitors);
      return;
    }
    const currentState = getState();
    const arrivals = currentState.visitorArrivals ?? [];
    const n = arrivals.length;
    const w = currentState.grid.width;
    const h = currentState.grid.height;
    while (layer.children.length < n) {
      const el = document.createElement("div");
      el.className = "visitor-sprite";
      el.setAttribute("aria-hidden", "true");
      el.textContent = "👤";
      layer.appendChild(el);
    }
    while (layer.children.length > n) {
      const last = layer.lastChild;
      if (last) last.remove();
    }
    const { centerX, centerY } = getAttractionCenter(currentState, w, h);
    for (let i = 0; i < n; i++) {
      const el = layer.children[i];
      const { px, py } = getVisitorPosition({
        i, n, t: visitorAnimTime, centerX, centerY, gridWidth: w, gridHeight: h,
      });
      el.style.left = `${px}px`;
      el.style.top = `${py}px`;
      syncVisitorBubble(el, arrivals[i], i);
    }
    visitorAnimTime += 0.016;
    requestAnimationFrame(updateVisitors);
  }
  requestAnimationFrame(updateVisitors);
  }
})();
