(function () {
  'use strict';

  function el(id) {
    return document.getElementById(id);
  }

  function encode(data) {
    var params = new URLSearchParams();
    Object.keys(data || {}).forEach(function (k) {
      if (data[k] === undefined || data[k] === null) return;
      params.append(k, String(data[k]));
    });
    return params.toString();
  }

  function getUrlParam(name) {
    try {
      return new URLSearchParams(window.location.search).get(name) || '';
    } catch (e) {
      return '';
    }
  }

  function ajax(action, data) {
    data = data || {};
    data.action = action;
    data.nonce = (window.WPSN_BULK && window.WPSN_BULK.nonce) ? window.WPSN_BULK.nonce : '';

    return fetch((window.WPSN_BULK && window.WPSN_BULK.ajaxUrl) ? window.WPSN_BULK.ajaxUrl : '', {
      method: 'POST',
      credentials: 'same-origin',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
      body: encode(data)
    }).then(function (r) { return r.json(); });
  }

  function setSpinner(active) {
    var sp = el('wpsn-bulk-ajax-spinner');
    if (!sp) return;
    if (active) {
      sp.classList.add('is-active');
    } else {
      sp.classList.remove('is-active');
    }
  }

  function setStatus(msg) {
    var s = el('wpsn-bulk-ajax-status');
    if (!s) return;
    s.textContent = msg || '';
  }

  function setProgress(pct) {
    var b = el('wpsn-bulk-ajax-bar');
    if (!b) return;
    b.style.width = String(Math.max(0, Math.min(100, pct))) + '%';
  }

  function showProgress(show) {
    var wrap = el('wpsn-bulk-ajax-progress');
    if (!wrap) return;
    wrap.style.display = show ? 'block' : 'none';
  }

  function getFilters() {
    var search = el('wpsn-suggestions-search');
    var pt = el('wpsn-filter-post-type');
    var source = el('wpsn-filter-source');
    var postId = getUrlParam('post_id');
    return {
      s: search ? search.value : '',
      pt: pt ? pt.value : 'any',
      source: source ? source.value : '',
      post_id: postId
    };
  }

  document.addEventListener('DOMContentLoaded', function () {
    var btn = el('wpsn-bulk-ajax-apply-all');
    if (!btn || !window.WPSN_BULK) return;

    var cancelBtn = el('wpsn-bulk-ajax-cancel');

    var running = false;
    var session = '';
    var total = 0;
    var processed = 0;
    var applied = 0;
    var cancelled = false;

    function resetUi() {
      running = false;
      cancelled = false;
      session = '';
      total = 0;
      processed = 0;
      applied = 0;

      btn.disabled = false;
      setSpinner(false);
    }

    function finish(doneOk, message) {
      running = false;
      btn.disabled = false;
      setSpinner(false);

      if (message) setStatus(message);

      if (doneOk) {
        // Refresh the page shortly to update counts and tables.
        setTimeout(function () {
          window.location.reload();
        }, 800);
      }
    }

    function step() {
      if (cancelled || !session) {
        resetUi();
        return;
      }

      ajax('wpsn_bulk_apply_all_step', { session: session, chunk: 10 })
        .then(function (res) {
          if (!res || !res.success) {
            throw new Error((res && res.data && res.data.message) ? res.data.message : (window.WPSN_BULK.strings.error || 'Error'));
          }

          processed = res.data.processed || 0;
          applied = res.data.applied || 0;
          total = res.data.total || total;

          var pct = total > 0 ? Math.round((processed / total) * 100) : 0;
          setProgress(pct);

          var msg = 'Processed ' + processed + ' / ' + total + ' • Applied ' + applied;
          if (res.data.remaining !== undefined) {
            msg += ' • Remaining ' + res.data.remaining;
          }
          setStatus(msg);

          if (res.data.done) {
            finish(true, (window.WPSN_BULK.strings.done || 'Done.') + ' ' + msg);
            return;
          }

          // Keep UI responsive.
          setTimeout(step, 200);
        })
        .catch(function (err) {
          finish(false, (window.WPSN_BULK.strings.error || 'Error') + ' ' + (err && err.message ? err.message : ''));
        });
    }

    function start() {
      if (running) return;
      running = true;
      cancelled = false;

      var limitInput = el('wpsn-bulk-apply-limit');
      var limit = limitInput ? parseInt(limitInput.value, 10) : 500;
      if (!limit || limit < 1) limit = 500;

      var onlyChangedEl = el('wpsn-bulk-apply-only-changed');
      var applyOnlyChanged = onlyChangedEl ? !!onlyChangedEl.checked : true;

      btn.disabled = true;
      setSpinner(true);
      showProgress(true);
      setProgress(0);
      setStatus(window.WPSN_BULK.strings.starting || 'Starting…');

      var filters = getFilters();

      ajax('wpsn_bulk_apply_all_start', {
        limit: limit,
        s: filters.s,
        pt: filters.pt,
        source: filters.source,
        post_id: filters.post_id,
        apply_only_changed: applyOnlyChanged ? '1' : '0'
      })
        .then(function (res) {
          if (!res || !res.success) {
            throw new Error((res && res.data && res.data.message) ? res.data.message : (window.WPSN_BULK.strings.error || 'Error'));
          }

          session = res.data.session || '';
          total = res.data.total || 0;

          if (!session) {
            throw new Error('Missing session id');
          }

          if (total <= 0) {
            finish(true, 'No draft suggestions found for the current filters.');
            return;
          }

          setStatus((window.WPSN_BULK.strings.processing || 'Processing…') + ' 0 / ' + total);
          step();
        })
        .catch(function (err) {
          finish(false, (window.WPSN_BULK.strings.error || 'Error') + ' ' + (err && err.message ? err.message : ''));
        });
    }

    function cancel() {
      if (!running || !session) {
        resetUi();
        showProgress(false);
        return;
      }

      cancelled = true;
      setStatus(window.WPSN_BULK.strings.cancelled || 'Cancelled.');

      ajax('wpsn_bulk_apply_all_cancel', { session: session })
        .then(function () {
          resetUi();
          showProgress(false);
        })
        .catch(function () {
          resetUi();
          showProgress(false);
        });
    }

    btn.addEventListener('click', function (e) {
      e.preventDefault();
      start();
    });

    if (cancelBtn) {
      cancelBtn.addEventListener('click', function (e) {
        e.preventDefault();
        cancel();
      });
    }

  });

  // Generate drafts now (AJAX) with progress (Local/OpenAI)
  document.addEventListener('DOMContentLoaded', function () {
    var btn = el('wpsn-bulk-ajax-generate-now');
    if (!btn || !window.WPSN_BULK) return;

    var cancelBtn = el('wpsn-bulk-ajax-generate-cancel');

    var running = false;
    var cancelled = false;
    var session = '';
    var total = 0;
    var processed = 0;
    var generated = 0;
    var skipped = 0;
    var failed = 0;
    var source = 'local';
    var chunkSize = 10;

    function setGenSpinner(active) {
      var sp = el('wpsn-bulk-ajax-generate-spinner');
      if (!sp) return;
      if (active) sp.classList.add('is-active');
      else sp.classList.remove('is-active');
    }

    function setGenStatus(msg) {
      var s = el('wpsn-bulk-ajax-generate-status');
      if (!s) return;
      s.textContent = msg || '';
    }

    function setGenProgress(pct) {
      var b = el('wpsn-bulk-ajax-generate-bar');
      if (!b) return;
      b.style.width = String(Math.max(0, Math.min(100, pct))) + '%';
    }

    function showGenProgress(show) {
      var wrap = el('wpsn-bulk-ajax-generate-progress');
      if (!wrap) return;
      wrap.style.display = show ? 'block' : 'none';
    }

    function getGenerateParams() {
      var form = el('wpsn-bulk-generate-form');
      var params = {};

      var sourceEl = el('wpsn-bulk-generate-source');
      source = sourceEl ? sourceEl.value : 'local';

      var limitEl = el('wpsn-bulk-generate-limit');
      var limit = limitEl ? parseInt(limitEl.value, 10) : 500;
      if (!limit || limit < 1) limit = 500;
      params.limit = limit;

      var backoffEl = el('wpsn-bulk-backoff-seconds');
      var backoff = backoffEl ? parseInt(backoffEl.value, 10) : 10;
      if (!backoff || backoff < 1) backoff = 10;
      if (backoff > 120) backoff = 120;
      params.backoff_seconds = backoff;

      params.source = source;

      var fields = [];
      if (form) {
        var fChecks = form.querySelectorAll('input[type="checkbox"][name^="fields["]');
        fChecks.forEach(function (cb) {
          if (cb && cb.checked) {
            if (cb.name.indexOf('title') !== -1) fields.push('title');
            if (cb.name.indexOf('description') !== -1) fields.push('description');
          }
        });

        var ptChecks = form.querySelectorAll('input[type="checkbox"][name^="post_types["]');
        var pts = [];
        ptChecks.forEach(function (cb) {
          if (cb && cb.checked) {
            // name="post_types[post]" => extract between brackets
            var m = cb.name.match(/\[([^\]]+)\]/);
            if (m && m[1]) pts.push(m[1]);
          }
        });
        params.post_types = pts.join(',');

        var onlyIfEmptyEl = form.querySelector('input[type="checkbox"][name="only_if_empty"]');
        params.only_if_empty = (onlyIfEmptyEl && onlyIfEmptyEl.checked) ? 1 : 0;

        var overwriteEl = form.querySelector('input[type="checkbox"][name="overwrite_suggestions"]');
        params.overwrite_suggestions = (overwriteEl && overwriteEl.checked) ? 1 : 0;
      }

      params.fields = fields.join(',');

      // Optional single-post mode (deep link): tools.php?page=wpsn-seo-bulk&post_id=123
      var postId = getUrlParam('post_id');
      if (postId) {
        params.post_id = postId;
      }

      // Chunk size: OpenAI is slower; keep requests short.
      chunkSize = (source === 'openai') ? 1 : 10;

      return params;
    }

    function resetUi() {
      running = false;
      cancelled = false;
      session = '';
      total = 0;
      processed = 0;
      generated = 0;
      skipped = 0;
      failed = 0;

      btn.disabled = false;
      setGenSpinner(false);
    }

    function finish(doneOk, message) {
      running = false;
      btn.disabled = false;
      setGenSpinner(false);

      if (message) setGenStatus(message);

      if (doneOk) {
        setTimeout(function () {
          window.location.reload();
        }, 900);
      }
    }

    function step() {
      if (cancelled || !session) {
        resetUi();
        return;
      }

      ajax('wpsn_bulk_generate_step', { session: session, chunk: chunkSize })
        .then(function (res) {
          if (!res || !res.success) {
            throw new Error((res && res.data && res.data.message) ? res.data.message : (window.WPSN_BULK.strings.error || 'Error'));
          }

          processed = res.data.processed || 0;
          generated = res.data.generated || 0;
          skipped = res.data.skipped || 0;
          failed = res.data.failed || 0;
          total = res.data.total || total;

          var pct = total > 0 ? Math.round((processed / total) * 100) : 0;
          setGenProgress(pct);

          var msg = 'Processed ' + processed + ' / ' + total +
            ' • Generated ' + generated +
            ' • Skipped ' + skipped +
            ' • Failed ' + failed;

          if (res.data.remaining !== undefined) {
            msg += ' • Remaining ' + res.data.remaining;
          }

          // Optional: show top error summary if any.
          if (res.data.errors) {
            try {
              var keys = Object.keys(res.data.errors);
              if (keys.length) {
                msg += ' • Errors: ' + keys.slice(0, 1).join(', ');
              }
            } catch (e) {}
          }

          setGenStatus(msg);

          // Soft rate-limit handling (HTTP 429): pause and retry.
          if (res.data.rate_limited) {
            var waitSec = parseInt(res.data.retry_after, 10);
            if (!waitSec || waitSec < 1) waitSec = 10;
            if (waitSec > 120) waitSec = 120;

            var rlm = res.data.rate_limit_message ? String(res.data.rate_limit_message) : '';

            var remaining = waitSec;
            (function tick() {
              if (cancelled || !session) {
                resetUi();
                return;
              }
              var tmsg = 'Rate limited. Waiting ' + remaining + 's…';
              if (rlm) tmsg += ' ' + rlm;
              tmsg += ' • ' + msg;
              setGenStatus(tmsg);
              if (remaining <= 0) {
                setTimeout(step, 60);
                return;
              }
              remaining -= 1;
              setTimeout(tick, 1000);
            })();
            return;
          }

          if (res.data.done) {
            finish(true, (window.WPSN_BULK.strings.done || 'Done.') + ' ' + msg);
            return;
          }

          setTimeout(step, (source === 'openai') ? 350 : 150);
        })
        .catch(function (err) {
          finish(false, (window.WPSN_BULK.strings.error || 'Error') + ' ' + (err && err.message ? err.message : ''));
        });
    }

    function start() {
      if (running) return;

      running = true;
      cancelled = false;

      btn.disabled = true;
      setGenSpinner(true);
      showGenProgress(true);
      setGenProgress(0);
      setGenStatus(window.WPSN_BULK.strings.starting || 'Starting…');

      var params = getGenerateParams();

      ajax('wpsn_bulk_generate_start', params)
        .then(function (res) {
          if (!res || !res.success) {
            throw new Error((res && res.data && res.data.message) ? res.data.message : (window.WPSN_BULK.strings.error || 'Error'));
          }

          session = res.data.session || '';
          total = res.data.total || 0;

          if (!session) {
            throw new Error('Missing session id');
          }

          if (total <= 0) {
            finish(true, 'No published posts found for the selected post types (or limit is 0).');
            return;
          }

          setGenStatus((window.WPSN_BULK.strings.processing || 'Processing…') + ' 0 / ' + total);
          step();
        })
        .catch(function (err) {
          finish(false, (window.WPSN_BULK.strings.error || 'Error') + ' ' + (err && err.message ? err.message : ''));
        });
    }

    function cancel() {
      if (!running || !session) {
        resetUi();
        showGenProgress(false);
        return;
      }

      cancelled = true;
      setGenStatus(window.WPSN_BULK.strings.cancelled || 'Cancelled.');

      ajax('wpsn_bulk_generate_cancel', { session: session })
        .then(function () {
          resetUi();
          showGenProgress(false);
        })
        .catch(function () {
          resetUi();
          showGenProgress(false);
        });
    }

    btn.addEventListener('click', function (e) {
      e.preventDefault();
      start();
    });

    if (cancelBtn) {
      cancelBtn.addEventListener('click', function (e) {
        e.preventDefault();
        cancel();
      });
    }
  });
})();
