const SwalTZ = Swal.mixin({
  buttonsStyling: false,
  customClass: {
    popup: 'tz-popup',
    title: 'tz-title',
    htmlContainer: 'tz-html',
    confirmButton: 'tz-btn tz-btn-primary',
    cancelButton: 'tz-btn',
    denyButton: 'tz-btn tz-btn-ghost',
    input: 'tz-input'
  }
});

async function apiGet(action, params = {}) {
  const url = new URL('api.php', window.location.href);
  url.searchParams.set('action', action);
  for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
  const res = await fetch(url.toString(), { credentials: 'same-origin' });
  const json = await res.json();
  if (!json.success) throw new Error(json.error || 'Request failed');
  return json.data;
}

async function apiPost(action, payload = {}) {
  const url = new URL('api.php', window.location.href);
  url.searchParams.set('action', action);
  const res = await fetch(url.toString(), {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'same-origin',
    body: JSON.stringify(payload)
  });
  const json = await res.json();
  if (!json.success) throw new Error(json.error || 'Request failed');
  return json.data;
}

function escapeHtml(s) {
  return String(s)
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

let session = { logged_in: false, user: null };
let lastBusinesses = [];

async function refreshSession() {
  session = await apiGet('session');
  return session;
}

async function showLogin() {
  const html = `
    <form class="tz-form" id="tzAdminLoginForm">
      <input class="tz-input" type="email" name="email" placeholder="Email" autocomplete="email" required />
      <input class="tz-input" type="password" name="password" placeholder="Password" autocomplete="current-password" required />
      <div class="tz-muted" style="font-size:12px;">To become admin: sign up, then set your user row's role to <b>admin</b> in data/users.csv.</div>
    </form>
  `;

  const result = await SwalTZ.fire({
    title: 'Admin login',
    html,
    showCancelButton: true,
    focusConfirm: false,
    preConfirm: async () => {
      const form = document.getElementById('tzAdminLoginForm');
      const data = Object.fromEntries(new FormData(form).entries());
      if (!data.email || !data.password) {
        Swal.showValidationMessage('Enter email and password');
        return;
      }
      try {
        await apiPost('login', data);
      } catch (e) {
        Swal.showValidationMessage(e.message);
        return;
      }
      return true;
    }
  });

  if (result.isConfirmed) {
    await refreshSession();
  }
}

function renderNotAdmin() {
  document.getElementById('adminBody').innerHTML = `
    <div class="tz-muted">
      You are logged in, but not an admin.<br />
      Open <b>data/users.csv</b> and set your row's <b>role</b> to <b>admin</b>.
    </div>
  `;
}

function renderLoggedOut() {
  document.getElementById('adminBody').innerHTML = `
    <div class="tz-muted">Please log in to access business CRUD.</div>
  `;
}

function renderTable(businesses) {
  lastBusinesses = Array.isArray(businesses) ? businesses : [];
  const rows = businesses.map((b) => {
    return `
      <tr>
        <td>${escapeHtml(b.id || '')}</td>
        <td>${escapeHtml(b.name || '')}</td>
        <td>${escapeHtml(b.address || '')}</td>
        <td class="tz-muted">${escapeHtml(b.lat || '')}, ${escapeHtml(b.lng || '')}</td>
        <td>${escapeHtml(b.avg_rating || '')}</td>
        <td><span class="tz-muted">${escapeHtml(b.pin_color || '')}</span></td>
        <td>${escapeHtml(b.login_email || '')}</td>
        <td style="white-space:nowrap;">
          <button class="tz-btn" data-action="edit" data-id="${escapeHtml(b.id || '')}">Edit</button>
          <button class="tz-btn tz-danger" data-action="delete" data-id="${escapeHtml(b.id || '')}">Delete</button>
        </td>
      </tr>
    `;
  }).join('');

  document.getElementById('adminBody').innerHTML = `
    <table class="tz-table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Address</th>
          <th>Coordinates</th>
          <th>Avg rating</th>
          <th>Pin color</th>
          <th>Login email</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody>
        ${rows || `<tr><td colspan="8" class="tz-muted">No businesses yet.</td></tr>`}
      </tbody>
    </table>
  `;

  document.querySelectorAll('[data-action="edit"]').forEach((btn) => {
    btn.addEventListener('click', () => openEdit(btn.getAttribute('data-id')));
  });
  document.querySelectorAll('[data-action="delete"]').forEach((btn) => {
    btn.addEventListener('click', () => deleteBusiness(btn.getAttribute('data-id')));
  });
}

async function loadBusinesses() {
  const data = await apiGet('admin_business_list');
  renderTable(data.businesses || []);
}

function businessFormHtml(b = {}) {
  return `
    <form class="tz-form" id="tzBizForm">
      <input class="tz-input" name="name" placeholder="Name" value="${escapeHtml(b.name || '')}" required />
      <input class="tz-input" name="address" placeholder="Address" value="${escapeHtml(b.address || '')}" required />
      <textarea class="tz-textarea" name="description" placeholder="Description" rows="4" required>${escapeHtml(b.description || '')}</textarea>
      <div class="tz-row">
        <input class="tz-input" name="lat" placeholder="Latitude" value="${escapeHtml(b.lat || '')}" required />
        <input class="tz-input" name="lng" placeholder="Longitude" value="${escapeHtml(b.lng || '')}" required />
      </div>
      <div class="tz-row">
        <input class="tz-input" name="avg_rating" placeholder="Avg rating (e.g. 4.5)" value="${escapeHtml(b.avg_rating || '0')}" />
        <input class="tz-input" name="pin_color" placeholder="Pin color (hex, e.g. #2e9b4a)" value="${escapeHtml(b.pin_color || '')}" />
      </div>
      <input class="tz-input" name="icon_url" placeholder="Business icon URL (shows on the pin)" value="${escapeHtml(b.icon_url || '')}" />
      <input class="tz-input" name="image_url" placeholder="Image URL" value="${escapeHtml(b.image_url || '')}" />

      <div class="tz-row">
        <input class="tz-input" type="email" name="login_email" placeholder="Business login email" value="${escapeHtml(b.login_email || '')}" />
        <input class="tz-input" type="password" name="login_password" placeholder="Business login password (leave blank to keep)" autocomplete="new-password" />
      </div>
      <div class="tz-muted" style="font-size:12px;">Coordinates are used to place the pin on the map.</div>
    </form>
  `;
}

async function openAdd() {
  const result = await SwalTZ.fire({
    title: 'Add business',
    html: businessFormHtml(),
    showCancelButton: true,
    focusConfirm: false,
    preConfirm: async () => {
      const form = document.getElementById('tzBizForm');
      const data = Object.fromEntries(new FormData(form).entries());
      if (!data.name || !data.address || !data.description || !data.lat || !data.lng) {
        Swal.showValidationMessage('Fill in all required fields');
        return;
      }
      if (!data.login_email || !data.login_password) {
        Swal.showValidationMessage('Business login email + password are required');
        return;
      }
      try {
        await apiPost('admin_business_create', data);
      } catch (e) {
        Swal.showValidationMessage(e.message);
        return;
      }
      return true;
    }
  });

  if (result.isConfirmed) {
    await loadBusinesses();
    await SwalTZ.fire({ title: 'Created', icon: 'success', timer: 900, showConfirmButton: false });
  }
}

async function openEdit(id) {
  if (!id) return;
  // We can reuse business_get for fields (admin gets same data)
  const bData = await apiGet('business_get', { id });
  const b = bData.business;
  const fromList = lastBusinesses.find((x) => String(x.id) === String(id)) || {};
  b.login_email = fromList.login_email || '';

  const result = await SwalTZ.fire({
    title: 'Edit business',
    html: businessFormHtml(b),
    showCancelButton: true,
    focusConfirm: false,
    confirmButtonText: 'Save',
    preConfirm: async () => {
      const form = document.getElementById('tzBizForm');
      const data = Object.fromEntries(new FormData(form).entries());
      data.id = id;
      if (!data.name || !data.address || !data.description || !data.lat || !data.lng) {
        Swal.showValidationMessage('Fill in all required fields');
        return;
      }
      try {
        await apiPost('admin_business_update', data);
      } catch (e) {
        Swal.showValidationMessage(e.message);
        return;
      }
      return true;
    }
  });

  if (result.isConfirmed) {
    await loadBusinesses();
    await SwalTZ.fire({ title: 'Saved', icon: 'success', timer: 900, showConfirmButton: false });
  }
}

async function deleteBusiness(id) {
  if (!id) return;
  const res = await SwalTZ.fire({
    title: 'Delete business?',
    text: 'This will remove it from the map and unsubscribe all users from it.',
    icon: 'warning',
    showCancelButton: true,
    confirmButtonText: 'Delete'
  });
  if (!res.isConfirmed) return;

  try {
    await apiPost('admin_business_delete', { id });
    await loadBusinesses();
    await SwalTZ.fire({ title: 'Deleted', icon: 'success', timer: 900, showConfirmButton: false });
  } catch (e) {
    await SwalTZ.fire({ title: 'Error', text: e.message, icon: 'error' });
  }
}

async function render() {
  await refreshSession();

  const btnLogin = document.getElementById('btnAdminLogin');
  const btnLogout = document.getElementById('btnAdminLogout');
  const btnAdd = document.getElementById('btnAddBusiness');
  const adminSub = document.getElementById('adminSub');

  btnLogin.addEventListener('click', async () => {
    await showLogin();
    await render();
  });

  btnLogout.addEventListener('click', async () => {
    await apiPost('logout');
    await render();
  });

  btnAdd.addEventListener('click', async () => {
    await openAdd();
  });

  if (!session.logged_in) {
    adminSub.textContent = 'Log in as an admin to manage businesses.';
    btnAdd.style.display = 'none';
    btnLogout.style.display = 'none';
    renderLoggedOut();
    return;
  }

  adminSub.textContent = `Logged in as ${session.user.email} (${session.user.role || 'user'})`;

  if (String(session.user.role || '').toLowerCase() !== 'admin') {
    btnAdd.style.display = 'none';
    btnLogout.style.display = '';
    renderNotAdmin();
    return;
  }

  btnAdd.style.display = '';
  btnLogout.style.display = '';

  try {
    await loadBusinesses();
  } catch (e) {
    document.getElementById('adminBody').innerHTML = `<div class="tz-muted">${escapeHtml(e.message)}</div>`;
  }
}

render().catch(async (e) => {
  console.error(e);
  await SwalTZ.fire({ title: 'Error', text: e.message || 'Something went wrong', icon: 'error' });
});
