/* ============================================================
   RESERVAS — disponibilidad por franja horaria
   Combina cupo automático (máx. personas/hora) + bloqueos manuales
   del administrador (día completo o franja puntual).
   Todo se guarda en este dispositivo (localStorage).
   ============================================================ */
const { HOURS: RES_HOURS } = window;

const RES_CAP_KEY = "do_res_capacity";
const RES_LIST_KEY = "do_reservations";
const RES_BLOCKS_KEY = "do_res_blocks";
const DEFAULT_CAPACITY = 15; // personas por franja horaria

function loadCapacity() {
  const n = parseInt(localStorage.getItem(RES_CAP_KEY), 10);
  return Number.isFinite(n) && n > 0 ? n : DEFAULT_CAPACITY;
}
function saveCapacity(n) { localStorage.setItem(RES_CAP_KEY, String(n)); }

function loadReservations() {
  try { return JSON.parse(localStorage.getItem(RES_LIST_KEY) || "[]"); } catch (e) { return []; }
}
function saveReservations(list) { localStorage.setItem(RES_LIST_KEY, JSON.stringify(list)); }

function loadBlocks() {
  try {
    const b = JSON.parse(localStorage.getItem(RES_BLOCKS_KEY) || "null");
    if (b && typeof b === "object") return { days: b.days || [], slots: b.slots || [] };
  } catch (e) {}
  return { days: [], slots: [] };
}
function saveBlocks(b) { localStorage.setItem(RES_BLOCKS_KEY, JSON.stringify(b)); }

// Franjas horarias del día (cada hora, dentro del horario de atención)
function getHourSlots() {
  const start = Math.ceil(RES_HOURS.open);
  const end = Math.floor(RES_HOURS.close);
  const out = [];
  for (let h = start; h < end; h++) {
    const period = h >= 12 ? "pm" : "am";
    const h12 = h > 12 ? h - 12 : h;
    out.push({ value: String(h).padStart(2, "0") + ":00", label: h12 + ":00 " + period });
  }
  return out;
}

function bookedCount(reservations, date, time) {
  return reservations
    .filter(r => r.date === date && r.time === time && r.status !== "cancelada")
    .reduce((s, r) => s + (r.people || 0), 0);
}

function slotStatus(date, time, reservations, blocks, capacity) {
  const dayBlocked = blocks.days.includes(date);
  const slotBlocked = blocks.slots.includes(date + "|" + time);
  const booked = bookedCount(reservations, date, time);
  const full = booked >= capacity;
  return { available: !dayBlocked && !slotBlocked && !full, dayBlocked, slotBlocked, full, booked, capacity };
}

/* ---- Selector de franja horaria (para el cliente) ---- */
function SlotPicker({ date, time, onPick }) {
  const [, force] = useState(0);
  useEffect(() => {
    const onStorage = () => force(x => x + 1);
    window.addEventListener("storage", onStorage);
    return () => window.removeEventListener("storage", onStorage);
  }, []);
  if (!date) return <p className="slot-hint">Elige primero una fecha para ver las horas disponibles.</p>;
  const reservations = loadReservations();
  const blocks = loadBlocks();
  const capacity = loadCapacity();
  const slots = getHourSlots();
  const dayFull = blocks.days.includes(date);
  return (
    <div className="slotgrid">
      {dayFull && <p className="slot-hint slot-hint-warn">No hay disponibilidad este día. Elige otra fecha.</p>}
      {!dayFull && slots.map(s => {
        const st = slotStatus(date, s.value, reservations, blocks, capacity);
        return (
          <button type="button" key={s.value}
            className={"slot-opt " + (time === s.value ? "on" : "") + (!st.available ? " off" : "")}
            disabled={!st.available}
            onClick={() => onPick(s.value)}>
            {s.label}
          </button>
        );
      })}
    </div>
  );
}

/* ---- Panel de administración de reservas ---- */
function ReservationsAdmin() {
  const [list, setList] = useState(loadReservations);
  const [blocks, setBlocks] = useState(loadBlocks);
  const [capacity, setCapacity] = useState(loadCapacity);
  const [blockDate, setBlockDate] = useState("");
  const [blockSlotDate, setBlockSlotDate] = useState("");
  const [blockSlotTime, setBlockSlotTime] = useState(getHourSlots()[0].value);

  function updateList(next) { setList(next); saveReservations(next); }
  function updateBlocks(next) { setBlocks(next); saveBlocks(next); }
  function updateCapacity(n) { setCapacity(n); saveCapacity(n); }

  function setStatus(id, status) {
    updateList(list.map(r => r.id === id ? { ...r, status } : r));
  }
  function addDayBlock() {
    if (!blockDate || blocks.days.includes(blockDate)) return;
    updateBlocks({ ...blocks, days: [...blocks.days, blockDate].sort() });
    setBlockDate("");
  }
  function removeDayBlock(d) { updateBlocks({ ...blocks, days: blocks.days.filter(x => x !== d) }); }
  function addSlotBlock() {
    const key = blockSlotDate + "|" + blockSlotTime;
    if (!blockSlotDate || blocks.slots.includes(key)) return;
    updateBlocks({ ...blocks, slots: [...blocks.slots, key].sort() });
    setBlockSlotDate("");
  }
  function removeSlotBlock(k) { updateBlocks({ ...blocks, slots: blocks.slots.filter(x => x !== k) }); }

  const upcoming = list
    .filter(r => r.status !== "cancelada")
    .sort((a, b) => (a.date + a.time).localeCompare(b.date + b.time));
  const slots = getHourSlots();

  return (
    <div className="res-admin">
      <div className="admin-card">
        <span className="block-label" style={{ margin: 0 }}>Cupo por franja horaria</span>
        <div className="cap-row">
          <input type="number" min={1} max={200} value={capacity}
            onChange={(e) => updateCapacity(Math.max(1, parseInt(e.target.value, 10) || 1))} />
          <span>personas por hora, máximo</span>
        </div>
      </div>

      <div className="admin-card">
        <span className="block-label" style={{ margin: 0 }}>Bloquear un día completo</span>
        <div className="cap-row">
          <input type="date" value={blockDate} onChange={(e) => setBlockDate(e.target.value)} />
          <button className="btn-add small" onClick={addDayBlock}>Bloquear</button>
        </div>
        {blocks.days.length > 0 && (
          <div className="chips block-chips">
            {blocks.days.map(d => (
              <span key={d} className="chip chip-x">{d} <button onClick={() => removeDayBlock(d)} aria-label="Quitar bloqueo"><Icon d={I.close} size={12} /></button></span>
            ))}
          </div>
        )}
      </div>

      <div className="admin-card">
        <span className="block-label" style={{ margin: 0 }}>Bloquear una franja puntual</span>
        <div className="cap-row">
          <input type="date" value={blockSlotDate} onChange={(e) => setBlockSlotDate(e.target.value)} />
          <select value={blockSlotTime} onChange={(e) => setBlockSlotTime(e.target.value)}>
            {slots.map(s => <option key={s.value} value={s.value}>{s.label}</option>)}
          </select>
          <button className="btn-add small" onClick={addSlotBlock}>Bloquear</button>
        </div>
        {blocks.slots.length > 0 && (
          <div className="chips block-chips">
            {blocks.slots.map(k => (
              <span key={k} className="chip chip-x">{k.replace("|", " · ")} <button onClick={() => removeSlotBlock(k)} aria-label="Quitar bloqueo"><Icon d={I.close} size={12} /></button></span>
            ))}
          </div>
        )}
      </div>

      <div className="admin-avail-head">
        <span className="block-label" style={{ margin: 0 }}>Reservas de clientes</span>
        <span className="admin-count">{upcoming.length} activa(s)</span>
      </div>
      <div className="admin-list res-list">
        {upcoming.length === 0 && <p className="slot-hint">Aún no hay reservas registradas desde la carta.</p>}
        {upcoming.map(r => (
          <div key={r.id} className={"res-row res-" + r.status}>
            <div className="res-row-main">
              <b>{r.name}</b>
              <span>{r.date} · {r.time} · {r.people} pers.</span>
              {r.notes && <em>“{r.notes}”</em>}
            </div>
            <div className="res-row-actions">
              <span className={"res-status-pill " + r.status}>{r.status}</span>
              {r.status !== "cumplida" && <button className="link" onClick={() => setStatus(r.id, "cumplida")}>Cumplida</button>}
              {r.status !== "cancelada" && <button className="link warn" onClick={() => setStatus(r.id, "cancelada")}>Cancelar</button>}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function addReservation(rec) {
  const list = loadReservations();
  const next = [...list, { ...rec, id: "R" + Date.now() + Math.random().toString(36).slice(2, 6), status: "pendiente" }];
  saveReservations(next);
  return next;
}

Object.assign(window, {
  loadCapacity, saveCapacity, loadReservations, saveReservations, loadBlocks, saveBlocks,
  getHourSlots, bookedCount, slotStatus, SlotPicker, ReservationsAdmin, addReservation,
});
