/**
 * Переводчик формата запросов (UI с undergroundbrand.ru) → локальный SPAMIMPAKTER.
 * НЕ ходит на undergroundbrand.ru — только window.fetch('/api/...') на 127.0.0.1.
 * Подключается ДО broadcast_ug.js.
 */
(function () {
  const API = '/api';
  window.API_URL = API;

  function toast(msg, kind) {
    const el = document.getElementById('toast');
    if (!el) return;
    el.textContent = msg;
    el.className = 'toast ' + (kind || 'info');
    el.hidden = false;
    clearTimeout(window._ugToastT);
    window._ugToastT = setTimeout(() => { el.hidden = true; }, 4000);
  }
  window.showNotification = toast;

  if (!window.escapeHtml) {
    window.escapeHtml = function (s) {
      const d = document.createElement('div');
      d.textContent = s == null ? '' : String(s);
      return d.innerHTML;
    };
  }

  window.fetchWithTimeout = async function (url, options, timeoutMs) {
    const ctrl = new AbortController();
    const t = setTimeout(() => ctrl.abort(), timeoutMs || 15000);
    try {
      return await fetch(url, { ...options, signal: ctrl.signal });
    } finally {
      clearTimeout(t);
    }
  };

  function usersDataToTargets(usersData) {
    if (!usersData || !usersData.length) return '';
    const lines = [];
    for (const u of usersData) {
      if (!u || typeof u !== 'object') continue;
      const phone = u.phone || u.phone_number;
      if (phone) {
        lines.push(String(phone).trim());
        continue;
      }
      if (u.user_id) {
        lines.push(String(u.user_id));
        continue;
      }
      if (u.username) {
        lines.push(String(u.username).replace(/^@/, '').trim());
      }
    }
    return lines.join('\n');
  }

  function mapJob(j) {
    const qs = j.queue_stats || {};
    return {
      ...j,
      message_text: j.text || '',
      spintax_enabled: j.randomize_text !== false,
      pause_min: j.delay_min,
      pause_max: j.delay_max,
      sent_total: (qs.sent != null ? qs.sent : (j.sent_count || 0)),
      failed_total: (qs.failed != null ? qs.failed : (j.failed_count || 0)),
      skipped_total: qs.skipped || 0,
      total_recipients: qs.total || j.total_targets || j.total_count || 0,
      total_accounts: (j.account_phones || []).length || (j.accounts_used || 0),
      account_ids: j._ug_account_ids || [],
      users_source: j.parsed_base_id ? 'parsed_base' : (j.recipient_source || 'manual'),
      source_label: j.source_label || '',
      post_links: j.post_links_list || j.post_links,
      status: j.status === 'stopped' ? 'cancelled' : j.status,
    };
  }

  function mapJobDetail(raw) {
    if (raw.job) {
      return {
        ...raw,
        job: mapJob(raw.job),
        queue_stats: raw.queue_stats || raw.job.queue_stats,
      };
    }
    const qs = raw.queue_stats || {};
    const accounts = (raw.accounts || []).map(a => ({
      phone: a.phone,
      username: a.username,
      status: a.pool_status || 'pending',
      spam_status: a.spam_status,
      spam_until: a.spam_until,
      sent_total: a.job_sent || 0,
      failed_today: 0,
      last_error: a.last_error,
    }));
    return {
      job: mapJob(raw),
      queue_stats: qs.sent != null ? qs : {
        sent: raw.sent_count || 0,
        failed: raw.failed_count || 0,
        skipped: (raw.queue_stats && raw.queue_stats.skipped) || 0,
        pending: raw.pending_count || qs.pending || 0,
        total: qs.total || raw.total_count || 0,
      },
      accounts,
    };
  }

  function jobStatusMatches(job, filterStatus) {
    const jobStatus = job.status;
    if (!filterStatus) return true;
    if (filterStatus === 'pending') return jobStatus === 'draft' || jobStatus === 'waiting';
    if (filterStatus === 'cancelled') return jobStatus === 'stopped' || jobStatus === 'cancelled';
    if (filterStatus === 'failed') {
      return (job.failed_count || 0) > 0 && jobStatus !== 'running';
    }
    return jobStatus === filterStatus;
  }

  const origFetch = window.fetch.bind(window);
  window.fetch = async function (input, init) {
    let url = typeof input === 'string' ? input : input.url;
    const method = (init && init.method) || 'GET';
    const opts = { ...(init || {}) };
    delete opts.headers?.Authorization;

    if (url.includes('/broadcast/jobs') && method === 'GET' && !url.match(/\/jobs\/\d+/)) {
      const u = new URL(url, location.origin);
      const st = u.searchParams.get('status');
      const [jobsRaw, accs] = await Promise.all([
        origFetch(API + '/broadcast/jobs').then(r => r.json()),
        origFetch(API + '/accounts').then(r => r.json()),
      ]);
      let jobs = Array.isArray(jobsRaw) ? jobsRaw : jobsRaw.jobs || [];
      const phoneToId = {};
      (accs || []).forEach(a => { if (a.phone) phoneToId[a.phone] = a.id; });
      if (st) jobs = jobs.filter(j => jobStatusMatches(j, st));
      const mapped = jobs.map(j => {
        const m = mapJob(j);
        m.account_ids = (j.account_phones || []).map(p => phoneToId[p]).filter(Boolean);
        return m;
      });
      return new Response(JSON.stringify({ jobs: mapped }), { status: 200, headers: { 'Content-Type': 'application/json' } });
    }

    if (url.match(/\/broadcast\/jobs\/\d+$/) && method === 'GET') {
      const id = url.match(/(\d+)$/)[1];
      const raw = await origFetch(API + '/broadcast/jobs/' + id).then(r => r.json());
      return new Response(JSON.stringify(mapJobDetail(raw)), { status: 200, headers: { 'Content-Type': 'application/json' } });
    }

    if (url.includes('/broadcast/create') && method === 'POST') {
      url = API + '/broadcast/create';
    } else if (url.includes('/broadcast/parser-bases')) {
      url = API + '/broadcast/parser-bases';
    } else if (url.includes('/broadcast/upload-base')) {
      url = API + '/broadcast/upload-base';
    } else if (url.includes('/accounts/for-warmup')) {
      url = API + '/accounts/for-warmup' + (url.includes('?') ? url.slice(url.indexOf('?')) : '');
    } else if (url.includes('/projects') && method === 'GET') {
      const raw = await origFetch(API + '/projects').then(r => r.json());
      const list = Array.isArray(raw) ? raw : raw.projects || [];
      return new Response(JSON.stringify({ projects: list }), { status: 200, headers: { 'Content-Type': 'application/json' } });
    } else if (url.match(/\/broadcast\/jobs\/\d+$/) && method === 'PUT') {
      const id = url.match(/(\d+)$/)[1];
      const body = JSON.parse(opts.body || '{}');
      const payload = {
        name: body.name,
        text: body.message_text,
        randomize_text: body.spintax_enabled,
        delete_after_send: body.delete_after_send,
        silent_send: body.silent_send,
        hide_author: body.hide_author,
        delay_min: body.pause_min,
        delay_max: body.pause_max,
        parallel_workers: body.parallel_workers,
        messages_per_account: body.messages_per_account,
        batch_size: body.batch_size,
        daily_limit: body.daily_limit,
        auto_stop_percent: body.auto_stop_percent,
        content_type: body.content_type,
        post_links: body.post_links,
        autoreply_enabled: body.autoreply_enabled,
        autoreply_template_id: body.autoreply_template_id || null,
      };
      if (body.parsed_base_id) payload.parsed_base_id = body.parsed_base_id;
      if (body.recipient_source) payload.recipient_source = body.recipient_source;
      if (body.replace_recipients) payload.replace_recipients = true;
      if (body.users_data && body.users_data.length) {
        payload.targets = usersDataToTargets(body.users_data);
      }
      if (body.account_ids && body.account_ids.length) {
        const accs = await origFetch(API + '/accounts').then(r => r.json());
        const idSet = new Set(body.account_ids.map(Number));
        payload.account_phones = accs.filter(a => idSet.has(a.id)).map(a => a.phone);
      }
      const res = await origFetch(API + '/broadcast/jobs/' + id + '/settings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!res.ok) return res;
      const data = await res.json();
      return new Response(
        JSON.stringify({ ok: true, message: 'Задача обновлена', ...data }),
        { status: 200, headers: { 'Content-Type': 'application/json' } }
      );
    } else if (url.match(/\/broadcast\/jobs\/\d+$/) && method === 'DELETE') {
      const id = url.match(/(\d+)$/)[1];
      return origFetch(API + '/broadcast/jobs/' + id, { method: 'DELETE' });
    } else if (url.includes('/broadcast/jobs/') && url.endsWith('/reset') && method === 'POST') {
      const id = url.match(/(\d+)/)[1];
      return origFetch(API + '/broadcast/jobs/' + id + '/reset', { method: 'POST' });
    } else if (url.includes('/broadcast/jobs/')) {
      url = API + url.slice(url.indexOf('/broadcast'));
    }

    const passThrough =
      url.startsWith(API + '/broadcast') ||
      url.startsWith(API + '/parser') ||
      url.startsWith(API + '/accounts') ||
      url.startsWith(API + '/projects') ||
      url.startsWith(API + '/spintax') ||
      url.startsWith(API + '/ai') ||
      url.startsWith(API + '/settings');

    if (passThrough) {
      const headers = { ...(opts.headers || {}) };
      delete headers.Authorization;
      opts.headers = headers;
      const target = url.startsWith(API) ? url : API + url.replace(/^.*\/api/, '/api');
      return origFetch(target, opts);
    }

    return origFetch(input, init);
  };

  window.__ugBroadcast = true;
})();
