/**
 * Ragreen - Admin panel logic
 * Requires config.js + jQuery loaded first.
 */

const Admin = {
  init() {
    $('.tab-btn').on('click', function () {
      const tab = $(this).data('tab');
      $('.tab-btn').removeClass('active');
      $(this).addClass('active');
      $('.tab-panel').removeClass('active');
      $(`#tab-${tab}`).addClass('active');
      Admin.loadTab(tab);
    });

    this.loadTab('overview');

    $('#userStatusFilter, #userTypeFilter, #userSearch, #userFeaturedFilter').on('change keyup', debounce(() => this.loadUsers(1), 300));
    $('#productStatusFilter, #productSearch, #productFeaturedFilter').on('change keyup', debounce(() => this.loadProducts(1), 300));
    $('#reportStatusFilter').on('change', () => this.loadReports());
    $('#seedDemoBtn').on('click', () => this.seedDemoData());
    $('#categoryForm').on('submit', (e) => this.createCategory(e));
    $('#createAdminForm').on('submit', (e) => this.createAdmin(e));
    $('#reportDateFrom, #reportDateTo, #reportProductName, #reportVendorFilter').on('change keyup', debounce(() => this.loadAnalytics(), 300));
    $('#reportExportBtn').on('click', () => this.exportAnalytics());
    $('#saveSettingsBtn').on('click', () => this.saveSettings());
    $('#sendTestEmailBtn').on('click', () => this.sendTestEmail());
    $('#createAdForm').on('submit', (e) => this.createAd(e));
    $('#ad_type').on('change', () => this.toggleAdTypeFields());
    $('#ad_size').on('change', () => this.toggleAdSizeFields());
    $('#ad_placement').on('change', () => this.handlePlacementChange());
    this.toggleAdTypeFields();
    this.toggleAdSizeFields();
  },

  seedDemoData() {
    const proceed = confirm(
      'This resets and reseeds a demo dataset (4 businesses, 6 personal accounts, ~18 products, ' +
      '3 completed orders, pantry items, and reports) under @ragreen-demo.test emails.\n\n' +
      'It never touches real accounts. Continue?'
    );
    if (!proceed) return;

    const $alert = $('#seedAlert');
    hideAlert($alert);
    const $btn = $('#seedDemoBtn');
    setLoading($btn, true, 'Seed demo data', 'Seeding…');

    $.ajax({
      url: `${API_BASE}/admin/seed_demo_data.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ confirm: true }),
    })
      .done((res) => {
        const s = res.data.summary;
        showAlert(
          $alert,
          `Seeded ${s.businesses} businesses, ${s.personal_users} personal accounts, ${s.products} products, ` +
          `${s.orders} orders, ${s.reports} reports. Log in as any demo account with password "${s.demo_password}".`,
          'success'
        );
        this.loadOverview();
      })
      .fail((xhr) => showAlert($alert, xhr.responseJSON?.message || 'Seeding failed.'))
      .always(() => setLoading($btn, false, 'Seed demo data', 'Seeding…'));
  },

  loadTab(tab) {
    if (tab === 'overview') this.loadOverview();
    if (tab === 'users') this.loadUsers();
    if (tab === 'products') this.loadProducts();
    if (tab === 'reports') this.loadReports();
    if (tab === 'categories') this.loadCategories();
    if (tab === 'analytics') this.loadAnalytics();
    if (tab === 'ads') this.loadAds();
    if (tab === 'subscriptions') this.loadSubscriptions();
    if (tab === 'settings') this.loadSettings();
  },

  loadOverview() {
    $.get(`${API_BASE}/admin/kpi.php`).done((res) => {
      this.renderKpiStats(res.data.summary);
      this.renderKpiCharts(res.data);
    });
  },

  renderKpiStats(s) {
    $('#overviewStats').html(`
      <div class="stat-card"><div class="num">$${s.total_revenue.toFixed(2)}</div><div class="label">Total revenue (completed)</div></div>
      <div class="stat-card"><div class="num">$${s.revenue_this_month.toFixed(2)}</div><div class="label">Revenue this month</div></div>
      <div class="stat-card"><div class="num">${s.completed_orders}</div><div class="label">Orders completed</div></div>
      <div class="stat-card"><div class="num">${s.items_rescued}</div><div class="label">Food items rescued</div></div>
      <div class="stat-card"><div class="num">$${s.avg_order_value.toFixed(2)}</div><div class="label">Avg. order value</div></div>
      <div class="stat-card ${s.pending_confirmations > 0 ? 'warn' : ''}"><div class="num">${s.pending_confirmations}</div><div class="label">Awaiting confirmation</div></div>
      <div class="stat-card"><div class="num">${s.personal_users}</div><div class="label">Personal accounts</div></div>
      <div class="stat-card"><div class="num">${s.business_users}</div><div class="label">Business accounts</div></div>
      <div class="stat-card"><div class="num">${s.new_users_this_month}</div><div class="label">New accounts this month</div></div>
      <div class="stat-card ${s.suspended_users > 0 ? 'warn' : ''}"><div class="num">${s.suspended_users}</div><div class="label">Suspended</div></div>
      <div class="stat-card"><div class="num">${s.active_listings}</div><div class="label">Active listings</div></div>
      <div class="stat-card"><div class="num">${s.total_listings}</div><div class="label">Total listings</div></div>
      <div class="stat-card ${s.open_reports > 0 ? 'warn' : ''}"><div class="num">${s.open_reports}</div><div class="label">Open reports</div></div>
    `);
  },

  charts: {},

  renderKpiCharts(data) {
    if (typeof Chart === 'undefined') {
      // Chart.js failed to load (e.g. blocked CDN) - stat cards above still work fine without it.
      return;
    }

    const colors = {
      leaf: '#226343', leafDark: '#1C5137', amber: '#E3A857',
      forest: '#133625', inkMuted: '#64756A', error: '#C1503E',
      paper: '#FBF8F2',
    };

    // Destroy any existing chart instances before redrawing - Chart.js
    // throws if you re-initialize a canvas that already has one attached,
    // and this tab can be revisited (or Seed Demo Data can re-trigger it).
    Object.values(this.charts).forEach((c) => c && c.destroy());

    const labels = data.daily_trend.map(d => new Date(d.date + 'T00:00:00').toLocaleDateString(undefined, { month: 'short', day: 'numeric' }));

    this.charts.revenue = new Chart(document.getElementById('revenueTrendChart'), {
      type: 'line',
      data: {
        labels,
        datasets: [
          {
            label: 'Revenue ($)', data: data.daily_trend.map(d => d.revenue),
            borderColor: colors.leaf, backgroundColor: colors.leaf + '22', fill: true, tension: 0.3, yAxisID: 'y',
          },
          {
            label: 'Orders', data: data.daily_trend.map(d => d.orders),
            borderColor: colors.amber, backgroundColor: colors.amber + '22', fill: false, tension: 0.3, yAxisID: 'y1',
          },
        ],
      },
      options: {
        responsive: true,
        interaction: { mode: 'index', intersect: false },
        scales: {
          y: { position: 'left', beginAtZero: true, title: { display: true, text: 'Revenue ($)' } },
          y1: { position: 'right', beginAtZero: true, grid: { drawOnChartArea: false }, title: { display: true, text: 'Orders' }, ticks: { precision: 0 } },
        },
      },
    });

    this.charts.signups = new Chart(document.getElementById('signupsTrendChart'), {
      type: 'bar',
      data: {
        labels,
        datasets: [{ label: 'New accounts', data: data.daily_trend.map(d => d.signups), backgroundColor: colors.forest }],
      },
      options: { responsive: true, scales: { y: { beginAtZero: true, ticks: { precision: 0 } } } },
    });

    const statusLabels = { pending: 'Pending', fulfilled: 'Completed', cancelled: 'Cancelled' };
    this.charts.status = new Chart(document.getElementById('statusChart'), {
      type: 'doughnut',
      data: {
        labels: data.status_breakdown.map(s => statusLabels[s.status] || s.status),
        datasets: [{
          data: data.status_breakdown.map(s => s.count),
          backgroundColor: data.status_breakdown.map(s => ({ pending: colors.amber, fulfilled: colors.leaf, cancelled: colors.error }[s.status] || colors.inkMuted)),
        }],
      },
      options: { responsive: true, plugins: { legend: { position: 'bottom' } } },
    });

    this.charts.categories = new Chart(document.getElementById('categoriesChart'), {
      type: 'bar',
      data: {
        labels: data.top_categories.map(c => c.category_name),
        datasets: [{ label: 'Revenue ($)', data: data.top_categories.map(c => c.revenue), backgroundColor: colors.leafDark }],
      },
      options: { responsive: true, indexAxis: 'y', scales: { x: { beginAtZero: true } } },
    });

    this.charts.vendors = new Chart(document.getElementById('vendorsChart'), {
      type: 'bar',
      data: {
        labels: data.top_vendors.map(v => v.vendor_name || 'Unknown'),
        datasets: [{ label: 'Revenue ($)', data: data.top_vendors.map(v => v.revenue), backgroundColor: colors.amber }],
      },
      options: { responsive: true, scales: { y: { beginAtZero: true } } },
    });
  },

  loadUsers(page = 1) {
    const params = {
      status: $('#userStatusFilter').val(),
      account_type: $('#userTypeFilter').val(),
      search: valTrim('#userSearch'),
      is_featured_vendor: $('#userFeaturedFilter').val(),
      page,
    };
    $.get(`${API_BASE}/admin/users_list.php`, params).done((res) => {
      const $tbody = $('#usersTableBody');
      if (!res.data.users.length) {
        $tbody.html('<tr><td colspan="6" style="color:var(--ink-muted);">No users match.</td></tr>');
        renderPaginationControls('#usersPagination', null);
        return;
      }
      $tbody.html(res.data.users.map(u => `
        <tr>
          <td>${escapeHtml(u.display_name || '—')} ${u.is_featured_vendor ? '<span class="status-pill status-active">★ Featured</span>' : ''}</td>
          <td>${escapeHtml(u.email)}</td>
          <td>${u.account_type}</td>
          <td>${statusPillHtml(u.status === 'active' ? 'active' : 'inactive')} ${u.status}</td>
          <td>${formatDate(u.created_at.split(' ')[0])}</td>
          <td style="display:flex; gap:6px; flex-wrap:wrap;">
            ${u.status === 'active'
              ? `<button class="mini-btn danger suspend-btn" data-id="${u.id}">Suspend</button>`
              : `<button class="mini-btn primary activate-btn" data-id="${u.id}">Activate</button>`}
            ${u.account_type === 'admin'
              ? `<button class="mini-btn danger demote-btn" data-id="${u.id}">Remove admin</button>`
              : `<button class="mini-btn promote-btn" data-id="${u.id}">Make admin</button>`}
            ${u.account_type !== 'admin' ? (u.is_featured_vendor
              ? `<button class="mini-btn unfeature-vendor-btn" data-id="${u.id}">Unfeature</button>`
              : `<button class="mini-btn primary feature-vendor-btn" data-id="${u.id}">Feature vendor</button>`) : ''}
          </td>
        </tr>
      `).join(''));

      $tbody.find('.feature-vendor-btn').on('click', function () { Admin.setVendorFeatured($(this).data('id'), true); });
      $tbody.find('.unfeature-vendor-btn').on('click', function () { Admin.setVendorFeatured($(this).data('id'), false); });

      $tbody.find('.suspend-btn').on('click', function () { Admin.setUserStatus($(this).data('id'), 'suspended'); });
      $tbody.find('.activate-btn').on('click', function () { Admin.setUserStatus($(this).data('id'), 'active'); });
      $tbody.find('.promote-btn').on('click', function () { Admin.setUserRole($(this).data('id'), 'promote'); });
      $tbody.find('.demote-btn').on('click', function () { Admin.setUserRole($(this).data('id'), 'demote'); });

      renderPaginationControls('#usersPagination', res.data.pagination, (p) => this.loadUsers(p));
    });
  },

  setUserRole(id, action) {
    const confirmMsg = action === 'promote'
      ? 'Make this user an admin? They will get full access to the admin panel.'
      : 'Remove admin access from this user? Their account will revert to its original type.';
    if (!confirm(confirmMsg)) return;

    $.ajax({
      url: `${API_BASE}/admin/users_update_role.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, action }),
    }).done(() => this.loadUsers()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update this user\'s role.'));
  },

  createAdmin(e) {
    e.preventDefault();
    const $alert = $('#createAdminAlert');
    hideAlert($alert);
    const $btn = $('#createAdminBtn');
    setLoading($btn, true, 'Create admin', 'Creating…');

    $.ajax({
      url: `${API_BASE}/admin/create_admin.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({
        full_name: valTrim('#ca_full_name'),
        email: valTrim('#ca_email'),
        password: $('#ca_password').val(),
      }),
    })
      .done(() => {
        showAlert($alert, 'Admin account created.', 'success');
        $('#createAdminForm')[0].reset();
        this.loadUsers();
      })
      .fail((xhr) => showAlert($alert, xhr.responseJSON?.message || 'Could not create admin account.'))
      .always(() => setLoading($btn, false, 'Create admin', 'Creating…'));
  },

  setUserStatus(id, status) {
    $.ajax({
      url: `${API_BASE}/admin/users_update_status.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, status }),
    }).done(() => this.loadUsers()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update user.'));
  },

  loadProducts(page = 1) {
    const params = {
      scope: 'admin',
      status: $('#productStatusFilter').val(),
      search: valTrim('#productSearch'),
      featured: $('#productFeaturedFilter').val(),
      page,
    };
    $.get(`${API_BASE}/products/list.php`, params).done((res) => {
      const $tbody = $('#productsTableBody');
      if (!res.data.products.length) {
        $tbody.html('<tr><td colspan="6" style="color:var(--ink-muted);">No listings match.</td></tr>');
        renderPaginationControls('#productsPagination', null);
        return;
      }
      $tbody.html(res.data.products.map(p => `
        <tr>
          <td>${escapeHtml(p.name)} ${p.is_currently_featured ? '<span class="status-pill status-active">★ Featured</span>' : ''}</td>
          <td>${escapeHtml(p.owner_email)}</td>
          <td>$${Number(p.selling_price).toFixed(2)}</td>
          <td>${statusPillHtml(p.status)}</td>
          <td>${formatDate(p.expiry_date)}</td>
          <td style="display:flex; gap:6px; flex-wrap:wrap;">
            ${p.status === 'active'
              ? `<button class="mini-btn danger hide-btn" data-id="${p.id}">Hide</button>`
              : `<button class="mini-btn primary show-btn" data-id="${p.id}">Reactivate</button>`}
            ${p.is_currently_featured
              ? `<button class="mini-btn unfeature-btn" data-id="${p.id}">Unfeature</button>`
              : `<button class="mini-btn primary feature-btn" data-id="${p.id}">Feature</button>`}
          </td>
        </tr>
      `).join(''));

      $tbody.find('.hide-btn').on('click', function () { Admin.setProductStatus($(this).data('id'), 'inactive'); });
      $tbody.find('.show-btn').on('click', function () { Admin.setProductStatus($(this).data('id'), 'active'); });
      $tbody.find('.feature-btn').on('click', function () { Admin.setProductFeatured($(this).data('id'), true); });
      $tbody.find('.unfeature-btn').on('click', function () { Admin.setProductFeatured($(this).data('id'), false); });

      renderPaginationControls('#productsPagination', res.data.pagination, (p) => this.loadProducts(p));
    });
  },

  setProductStatus(id, status) {
    $.ajax({
      url: `${API_BASE}/admin/products_update_status.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, status }),
    }).done(() => this.loadProducts()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update listing.'));
  },

  setProductFeatured(id, isFeatured) {
    let featuredUntil = null;
    if (isFeatured) {
      featuredUntil = prompt('Feature until which date? (YYYY-MM-DD, leave blank for indefinite)', '');
      if (featuredUntil === null) return; // cancelled
    }
    $.ajax({
      url: `${API_BASE}/admin/products_toggle_featured.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, is_featured: isFeatured, featured_until: featuredUntil || undefined }),
    }).done(() => this.loadProducts()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update featured status.'));
  },

  setVendorFeatured(id, isFeatured) {
    $.ajax({
      url: `${API_BASE}/admin/vendors_toggle_featured.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, is_featured_vendor: isFeatured }),
    }).done(() => this.loadUsers()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update vendor.'));
  },

  /* ---------------- Ads ---------------- */

  toggleAdTypeFields() {
    const isGoogle = $('#ad_type').val() === 'google';
    $('#ad_google_field, #ad_test_mode_field').toggle(isGoogle);
    $('#ad_custom_fields, #ad_link_field, #ad_alt_field').toggle(!isGoogle);
  },

  handlePlacementChange() {
    const isCardPlacement = $('#ad_placement').val() === 'marketplace_card';
    // Listing-card ads only support custom (image + link) - a Google-shaped
    // native ad unit is a different integration this app doesn't build.
    $('#ad_type option[value="google"]').prop('disabled', isCardPlacement);
    if (isCardPlacement) {
      $('#ad_type').val('custom');
      $('#ad_size').val('300x400');
    }
    this.toggleAdTypeFields();
    this.toggleAdSizeFields();
  },

  toggleAdSizeFields() {
    $('#ad_custom_size_field').toggle($('#ad_size').val() === 'custom');
  },

  loadAds(page = 1) {
    $.get(`${API_BASE}/admin/ads_list.php`, { page }).done((res) => {
      const $list = $('#adsList');
      if (!res.data.ads.length) {
        $list.html('<p style="color:var(--ink-muted);">No ads configured yet.</p>');
        renderPaginationControls('#adsPagination', null);
        return;
      }
      const placementLabels = {
        marketplace_top: 'Marketplace - top', marketplace_infeed: 'Marketplace - in-feed',
        marketplace_bottom: 'Marketplace - bottom', product_details_top: 'Product page - top',
        product_details_bottom: 'Product page - bottom',
      };
      $list.html(`
        <table class="data-table">
          <thead><tr><th>Placement</th><th>Type</th><th>Size</th><th>Preview / Slot</th><th>Status</th><th></th></tr></thead>
          <tbody>
            ${res.data.ads.map(ad => `
              <tr>
                <td>${placementLabels[ad.placement_key] || ad.placement_key}</td>
                <td>${ad.ad_type === 'google' ? 'Google' : 'Custom'}${ad.ad_type === 'google' && ad.is_test_mode == 1 ? ' <span class="status-pill status-inactive">Test mode</span>' : ''}</td>
                <td>${ad.width}×${ad.height}</td>
                <td>${ad.ad_type === 'google'
                  ? escapeHtml(ad.google_ad_slot || '')
                  : (ad.custom_image_url ? `<img src="${ad.custom_image_url}" style="max-height:36px; max-width:100px;">` : '')}</td>
                <td>${statusPillHtml(ad.is_active == 1 ? 'active' : 'inactive')}</td>
                <td style="display:flex; gap:6px;">
                  ${ad.is_active == 1
                    ? `<button class="mini-btn danger ad-toggle-btn" data-id="${ad.id}" data-active="0">Pause</button>`
                    : `<button class="mini-btn primary ad-toggle-btn" data-id="${ad.id}" data-active="1">Activate</button>`}
                  <button class="mini-btn danger ad-delete-btn" data-id="${ad.id}">Delete</button>
                </td>
              </tr>
            `).join('')}
          </tbody>
        </table>
      `);
      $list.find('.ad-toggle-btn').on('click', function () {
        Admin.toggleAd($(this).data('id'), $(this).data('active') === 1);
      });
      $list.find('.ad-delete-btn').on('click', function () {
        if (confirm('Delete this ad permanently?')) Admin.deleteAd($(this).data('id'));
      });

      renderPaginationControls('#adsPagination', res.data.pagination, (p) => this.loadAds(p));
    });
  },

  createAd(e) {
    e.preventDefault();
    const $alert = $('#createAdAlert');
    hideAlert($alert);

    const sizeVal = $('#ad_size').val();
    let width, height;
    if (sizeVal === 'custom') {
      width = $('#ad_width').val();
      height = $('#ad_height').val();
    } else {
      [width, height] = sizeVal.split('x');
    }

    const adType = $('#ad_type').val();
    const formData = new FormData();
    formData.append('placement_key', $('#ad_placement').val());
    formData.append('ad_type', adType);
    formData.append('width', width);
    formData.append('height', height);
    if (adType === 'google') {
      formData.append('google_ad_slot', valTrim('#ad_google_slot'));
      formData.append('is_test_mode', $('#ad_test_mode').is(':checked') ? '1' : '0');
    } else {
      formData.append('custom_link_url', valTrim('#ad_link_url'));
      formData.append('custom_alt_text', valTrim('#ad_alt_text'));
      const file = $('#ad_image')[0].files[0];
      if (file) formData.append('image', file);
    }

    const $btn = $('#createAdBtn');
    setLoading($btn, true, 'Create ad', 'Creating…');

    $.ajax({
      url: `${API_BASE}/admin/ads_create.php`, method: 'POST', data: formData,
      processData: false, contentType: false,
    })
      .done(() => {
        showAlert($alert, 'Ad created.', 'success');
        $('#createAdForm')[0].reset();
        this.toggleAdTypeFields();
        this.toggleAdSizeFields();
        this.loadAds();
      })
      .fail((xhr) => showAlert($alert, xhr.responseJSON?.message || 'Could not create ad.'))
      .always(() => setLoading($btn, false, 'Create ad', 'Creating…'));
  },

  toggleAd(id, activate) {
    $.ajax({
      url: `${API_BASE}/admin/ads_update.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, is_active: activate }),
    }).done(() => this.loadAds()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update ad.'));
  },

  deleteAd(id) {
    $.ajax({
      url: `${API_BASE}/admin/ads_delete.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id }),
    }).done(() => this.loadAds()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not delete ad.'));
  },

  /* ---------------- Subscriptions ---------------- */

  loadSubscriptions(page = 1) {
    $.get(`${API_BASE}/admin/subscriptions_list.php`, { page }).done((res) => {
      const $list = $('#subscriptionsList');
      if (!res.data.subscriptions.length) {
        $list.html('<p style="color:var(--ink-muted);">No business accounts yet.</p>');
        renderPaginationControls('#subscriptionsPagination', null);
        return;
      }
      const statusLabels = { trial: 'Free trial', active: 'Active', expired: 'Expired', cancelled: 'Cancelled' };
      const planInterestLabels = { free_only: 'Wants to stay free', interested_paid: 'Interested in paid', not_sure: 'Not sure yet' };
      $list.html(`
        <table class="data-table">
          <thead><tr><th>Business</th><th>Email</th><th>Status</th><th>Trial ends</th><th>Plan interest</th><th></th></tr></thead>
          <tbody>
            ${res.data.subscriptions.map(s => `
              <tr>
                <td>${escapeHtml(s.business_name)}</td>
                <td>${escapeHtml(s.email)}</td>
                <td>${statusLabels[s.subscription_status] || s.subscription_status}</td>
                <td>${s.trial_ends_at ? formatDate(s.trial_ends_at) + (s.days_left !== null ? ` (${s.days_left}d)` : '') : '—'}</td>
                <td>${planInterestLabels[s.subscription_plan] || '—'}</td>
                <td>
                  <button class="mini-btn sub-edit-btn" data-id="${s.user_id}" data-status="${s.subscription_status}" data-trial="${s.trial_ends_at || ''}">Edit</button>
                </td>
              </tr>
            `).join('')}
          </tbody>
        </table>
      `);
      $list.find('.sub-edit-btn').on('click', function () {
        Admin.editSubscription($(this).data('id'), $(this).data('status'), $(this).data('trial'));
      });

      renderPaginationControls('#subscriptionsPagination', res.data.pagination, (p) => this.loadSubscriptions(p));
    });
  },

  editSubscription(userId, currentStatus, currentTrial) {
    const status = prompt('Status (trial | active | expired | cancelled):', currentStatus);
    if (status === null) return;
    if (!['trial', 'active', 'expired', 'cancelled'].includes(status)) {
      alert('Status must be one of: trial, active, expired, cancelled');
      return;
    }
    const trialEndsAt = prompt('Trial ends at (YYYY-MM-DD, blank to clear):', currentTrial || '');
    if (trialEndsAt === null) return;

    $.ajax({
      url: `${API_BASE}/admin/subscriptions_update.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ user_id: userId, subscription_status: status, trial_ends_at: trialEndsAt }),
    }).done(() => this.loadSubscriptions()).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update subscription.'));
  },

  loadReports(page = 1) {
    const status = $('#reportStatusFilter').val();
    $.get(`${API_BASE}/admin/reports_list.php`, { status, page }).done((res) => {
      const $tbody = $('#reportsTableBody');
      if (!res.data.reports.length) {
        $tbody.html('<tr><td colspan="5" style="color:var(--ink-muted);">No reports match.</td></tr>');
        renderPaginationControls('#reportsPagination', null);
        return;
      }
      $tbody.html(res.data.reports.map(r => `
        <tr>
          <td>${escapeHtml(r.reason)}</td>
          <td>${r.product_name ? escapeHtml(r.product_name) : (r.reported_user_email ? escapeHtml(r.reported_user_email) : '—')}</td>
          <td>${escapeHtml(r.reporter_email)}</td>
          <td>${r.status}</td>
          <td>
            <select class="pill-select report-status-select" data-id="${r.id}">
              <option value="open" ${r.status === 'open' ? 'selected' : ''}>Open</option>
              <option value="reviewing" ${r.status === 'reviewing' ? 'selected' : ''}>Reviewing</option>
              <option value="resolved" ${r.status === 'resolved' ? 'selected' : ''}>Resolved</option>
              <option value="dismissed" ${r.status === 'dismissed' ? 'selected' : ''}>Dismissed</option>
            </select>
          </td>
        </tr>
      `).join(''));

      $tbody.find('.report-status-select').on('change', function () {
        Admin.setReportStatus($(this).data('id'), $(this).val());
      });

      renderPaginationControls('#reportsPagination', res.data.pagination, (p) => this.loadReports(p));
    });
  },

  setReportStatus(id, status) {
    $.ajax({
      url: `${API_BASE}/admin/reports_update.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, status }),
    }).fail((xhr) => alert(xhr.responseJSON?.message || 'Could not update report.'));
  },

  /* ---------- Categories ---------- */

  loadCategories() {
    $.get(`${API_BASE}/categories/list.php`, { include_inactive: 1 }).done((res) => {
      const $tbody = $('#categoriesTableBody');
      $tbody.html(res.data.categories.map(c => `
        <tr>
          <td>${escapeHtml(c.name)}</td>
          <td>${c.is_active ? statusPillHtml('active') : statusPillHtml('inactive')}</td>
          <td>
            ${c.is_active
              ? `<button class="mini-btn danger cat-deactivate" data-id="${c.id}">Deactivate</button>`
              : `<button class="mini-btn primary cat-activate" data-id="${c.id}">Activate</button>`}
          </td>
        </tr>
      `).join(''));

      $tbody.find('.cat-deactivate').on('click', function () { Admin.setCategoryActive($(this).data('id'), false); });
      $tbody.find('.cat-activate').on('click', function () { Admin.setCategoryActive($(this).data('id'), true); });
    });
  },

  createCategory(e) {
    e.preventDefault();
    const name = valTrim('#newCategoryName');
    if (!name) return;
    $.ajax({
      url: `${API_BASE}/admin/categories_create.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ name }),
    })
      .done(() => { $('#newCategoryName').val(''); this.loadCategories(); })
      .fail((xhr) => alert(xhr.responseJSON?.message || 'Could not add category.'));
  },

  setCategoryActive(id, isActive) {
    $.ajax({
      url: `${API_BASE}/admin/categories_update.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ id, is_active: isActive }),
    }).done(() => this.loadCategories());
  },

  /* ---------- Sales analytics ---------- */

  loadAnalytics() {
    const params = {
      date_from: $('#reportDateFrom').val(),
      date_to: $('#reportDateTo').val(),
      product_name: valTrim('#reportProductName'),
      vendor_id: $('#reportVendorFilter').val(),
    };
    $.get(`${API_BASE}/admin/sales_report.php`, params).done((res) => {
      const s = res.data.summary;
      $('#reportStats').html(`
        <div class="stat-card"><div class="num">$${s.total_revenue.toFixed(2)}</div><div class="label">Total revenue</div></div>
        <div class="stat-card"><div class="num">${s.total_items_sold}</div><div class="label">Items sold</div></div>
        <div class="stat-card"><div class="num">${s.transaction_count}</div><div class="label">Transactions</div></div>
      `);

      const $tbody = $('#reportTableBody');
      if (!res.data.rows.length) {
        $tbody.html('<tr><td colspan="7" style="color:var(--ink-muted);">No transactions match these filters.</td></tr>');
        return;
      }
      $tbody.html(res.data.rows.map(r => `
        <tr>
          <td>#${r.order_id}</td>
          <td>${formatDate(r.created_at.split(' ')[0])}</td>
          <td>${escapeHtml(r.product_name)}</td>
          <td>${escapeHtml(r.category_name || '—')}</td>
          <td>${r.quantity}</td>
          <td>$${Number(r.line_total).toFixed(2)}</td>
          <td>${escapeHtml(r.vendor_name || r.vendor_email)}</td>
        </tr>
      `).join(''));

      // Populate the vendor filter once with whoever appears in the unfiltered data.
      if (!$('#reportVendorFilter').data('loaded')) {
        const vendors = [...new Map(res.data.rows.map(r => [r.vendor_email, r.vendor_name || r.vendor_email])).entries()];
        $('#reportVendorFilter').append(vendors.map(([email, name]) => `<option value="${escapeHtml(email)}">${escapeHtml(name)}</option>`).join(''));
      }
    });
  },

  exportAnalytics() {
    const params = new URLSearchParams({
      date_from: $('#reportDateFrom').val(),
      date_to: $('#reportDateTo').val(),
      product_name: valTrim('#reportProductName'),
      vendor_id: $('#reportVendorFilter').val(),
      export: 'csv',
    });
    window.location.href = `${API_BASE}/admin/sales_report.php?${params.toString()}`;
  },

  /* ---------- Settings ---------- */

  loadSettings() {
    $.get(`${API_BASE}/admin/settings_list.php`).done((res) => {
      const s = res.data.settings;
      $('#s_points_per_dollar').val(s.points_per_dollar_spent);
      $('#s_points_per_listing').val(s.points_per_new_listing);
      $('#s_market_country').val(s.market_country);
      $('#s_market_city').val(s.market_city);
      $('#s_google_id').val(s.oauth_google_client_id);
      $('#s_google_secret').val(s.oauth_google_client_secret);
      $('#s_fb_id').val(s.oauth_facebook_app_id);
      $('#s_fb_secret').val(s.oauth_facebook_app_secret);
      $('#s_smtp_host').val(s.smtp_host);
      $('#s_smtp_port').val(s.smtp_port);
      $('#s_smtp_username').val(s.smtp_username);
      $('#s_smtp_password').val(s.smtp_password);
      $('#s_smtp_encryption').val(s.smtp_encryption || 'tls');
      $('#s_smtp_from_email').val(s.smtp_from_email);
      $('#s_smtp_from_name').val(s.smtp_from_name);
      $('#s_trial_days').val(s.business_trial_days);
      $('#s_subscriptions_enabled').val(s.subscriptions_enabled);
      $('#s_adsense_client').val(s.adsense_client_id);
    });
  },

  saveSettings() {
    const $alert = $('#settingsAlert');
    hideAlert($alert);
    const updates = {
      points_per_dollar_spent: $('#s_points_per_dollar').val(),
      points_per_new_listing: $('#s_points_per_listing').val(),
      market_country: valTrim('#s_market_country'),
      market_city: valTrim('#s_market_city'),
      oauth_google_client_id: valTrim('#s_google_id'),
      oauth_google_client_secret: valTrim('#s_google_secret'),
      oauth_facebook_app_id: valTrim('#s_fb_id'),
      oauth_facebook_app_secret: valTrim('#s_fb_secret'),
      smtp_host: valTrim('#s_smtp_host'),
      smtp_port: valTrim('#s_smtp_port'),
      smtp_username: valTrim('#s_smtp_username'),
      smtp_password: $('#s_smtp_password').val(),
      smtp_encryption: $('#s_smtp_encryption').val(),
      smtp_from_email: valTrim('#s_smtp_from_email'),
      smtp_from_name: valTrim('#s_smtp_from_name'),
      business_trial_days: $('#s_trial_days').val(),
      subscriptions_enabled: $('#s_subscriptions_enabled').val(),
      adsense_client_id: valTrim('#s_adsense_client'),
    };
    const $btn = $('#saveSettingsBtn');
    setLoading($btn, true, 'Save all settings', 'Saving…');

    $.ajax({
      url: `${API_BASE}/admin/settings_update.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ updates }),
    })
      .done(() => showAlert($alert, 'Settings saved.', 'success'))
      .fail((xhr) => showAlert($alert, xhr.responseJSON?.message || 'Could not save settings.'))
      .always(() => setLoading($btn, false, 'Save all settings', 'Saving…'));
  },

  sendTestEmail() {
    const to = valTrim('#testEmailTo');
    if (!to) { alert('Enter an email address to send the test to.'); return; }

    const $result = $('#testEmailResult');
    const $btn = $('#sendTestEmailBtn');
    setLoading($btn, true, 'Send test email', 'Sending…');
    $result.html('');

    $.ajax({
      url: `${API_BASE}/admin/test_email.php`, method: 'POST', contentType: 'application/json',
      data: JSON.stringify({ to }),
    })
      .done((res) => {
        $result.html(`<span style="color:var(--leaf-dark); font-weight:600;">✓ ${escapeHtml(res.message)}</span>`);
      })
      .fail((xhr) => {
        const msg = xhr.responseJSON?.message || 'Send failed.';
        $result.html(`<span style="color:var(--error); font-weight:600;">✗ ${escapeHtml(msg)}</span>`);
      })
      .always(() => setLoading($btn, false, 'Send test email', 'Sending…'));
  },
};

function debounce(fn, wait) {
  let t;
  return function (...args) {
    clearTimeout(t);
    t = setTimeout(() => fn.apply(this, args), wait);
  };
}
