(function(){
  'use strict';

  const apiUrl = window.PYRK_PUSH_PRESETS_API || '../../api/push_notification_presets.php';
  const csrf = window.__PYRK_CSRF__ || window.PYRK_CSRF || '';
  const state = {presets:[], useCases:{}, variables:{}, installed:true, selectedId:0};
  const $ = id => document.getElementById(id);
  const els = {
    list:$('pushPresetList'), count:$('pushPresetCount'), search:$('pushPresetSearch'), status:$('pushPresetStatusFilter'),
    form:$('pushPresetForm'), id:$('pushPresetId'), name:$('pushPresetName'), useCase:$('pushPresetUseCase'), sort:$('pushPresetSort'),
    active:$('pushPresetActive'), isDefault:$('pushPresetDefault'), subject:$('pushPresetSubject'), message:$('pushPresetMessage'),
    variables:$('pushPresetVariables'), previewSubject:$('pushPresetPreviewSubject'), previewMessage:$('pushPresetPreviewMessage'), counter:$('pushPresetCharacterCount'),
    notice:$('pushPresetNotice'), editorState:$('pushPresetEditorState'), eyebrow:$('pushPresetEditorEyebrow'), title:$('pushPresetEditorTitle'),
    newBtn:$('newPushPresetBtn'), reloadBtn:$('reloadPushPresetsBtn'), saveBtn:$('savePushPresetBtn'), duplicateBtn:$('duplicatePushPresetBtn'),
    toggleBtn:$('togglePushPresetBtn'), clearBtn:$('clearPushPresetBtn'), deleteBtn:$('deletePushPresetBtn'), install:$('pushPresetInstallWarning')
  };

  const sample = {
    '{first_name}':'Alex','{last_name}':'Walker','{full_name}':'Alex Walker','{walk_title}':'Beirut Sunrise Walk',
    '{walk_date}':'21/07/2026','{walk_time}':'07:00','{route_name}':'Pyrk Waterfront Route','{distance_km}':'6.4',
    '{walk_link}':'https://thepyrk.com/steps/public/walk.php?id=123'
  };

  function esc(value){
    return String(value == null ? '' : value).replace(/[&<>"']/g, ch => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'})[ch]);
  }

  function setNotice(message, type=''){
    if (!els.notice) return;
    els.notice.textContent = message || '';
    els.notice.className = `notice ${type}`.trim();
  }

  async function api(action, payload={}){
    const response = await fetch(apiUrl, {
      method:'POST', credentials:'same-origin',
      headers:{'Content-Type':'application/json','X-CSRF-Token':csrf},
      body:JSON.stringify(Object.assign({action}, payload))
    });
    const text = await response.text();
    let json;
    try { json = text ? JSON.parse(text) : {}; }
    catch (_) { throw new Error(String(text || 'API did not return JSON.').replace(/<[^>]+>/g,' ').replace(/\s+/g,' ').trim().slice(0,500)); }
    if (!response.ok || !json.ok) throw new Error(json.message || 'Request failed.');
    return json.data || {};
  }

  function useCaseLabel(key){ return state.useCases[key] || String(key || 'custom').replace(/_/g,' '); }

  function renderUseCases(){
    els.useCase.innerHTML = Object.entries(state.useCases).map(([key,label]) => `<option value="${esc(key)}">${esc(label)}</option>`).join('');
    if (!els.useCase.value) els.useCase.value = 'custom';
  }

  function renderVariables(){
    els.variables.innerHTML = Object.entries(state.variables).map(([token,label]) => `<button type="button" data-token="${esc(token)}" title="${esc(label)}">${esc(token)}</button>`).join('');
    els.variables.querySelectorAll('[data-token]').forEach(btn => btn.addEventListener('click', () => insertToken(btn.dataset.token || '')));
  }

  function filteredPresets(){
    const q = String(els.search.value || '').trim().toLowerCase();
    const status = els.status.value || 'all';
    return state.presets.filter(p => {
      if (status === 'active' && Number(p.is_active) !== 1) return false;
      if (status === 'inactive' && Number(p.is_active) === 1) return false;
      const hay = `${p.preset_name || ''} ${p.use_case || ''} ${p.subject_template || ''} ${p.message_template || ''}`.toLowerCase();
      return !q || hay.includes(q);
    });
  }

  function renderList(){
    const rows = filteredPresets();
    els.count.textContent = String(state.presets.length);
    els.list.innerHTML = rows.map(p => {
      const selected = Number(p.id) === Number(state.selectedId);
      return `<button type="button" class="push-preset-list-card ${selected ? 'is-selected' : ''} ${Number(p.is_active) === 1 ? '' : 'is-inactive'}" data-preset-id="${Number(p.id)}">
        <span class="push-preset-list-copy">
          <strong>${esc(p.preset_name || 'Unnamed preset')}</strong>
          <small>${esc(p.subject_template || '')}</small>
          <span class="push-preset-list-badges">
            <span class="push-preset-badge">${esc(useCaseLabel(p.use_case || 'custom'))}</span>
            ${Number(p.is_default) === 1 ? '<span class="push-preset-badge default">Default</span>' : ''}
            ${Number(p.is_active) !== 1 ? '<span class="push-preset-badge inactive">Inactive</span>' : ''}
          </span>
        </span><span class="push-preset-list-arrow">›</span>
      </button>`;
    }).join('') || '<div class="push-preset-empty">No presets match this filter.</div>';
    els.list.querySelectorAll('[data-preset-id]').forEach(btn => btn.addEventListener('click', () => editPreset(Number(btn.dataset.presetId))));
  }

  function replaceSample(value){
    let result = String(value || '');
    Object.entries(sample).forEach(([token,replacement]) => { result = result.split(token).join(replacement); });
    return result;
  }

  function renderPreview(){
    els.previewSubject.textContent = replaceSample(els.subject.value).trim() || 'Notification preview';
    els.previewMessage.textContent = replaceSample(els.message.value).trim() || 'Start typing to preview the message.';
    els.counter.textContent = `${els.message.value.length} / 4000 characters`;
  }

  function insertToken(token){
    const target = document.activeElement === els.subject ? els.subject : els.message;
    const start = Number.isInteger(target.selectionStart) ? target.selectionStart : target.value.length;
    const end = Number.isInteger(target.selectionEnd) ? target.selectionEnd : start;
    target.value = target.value.slice(0,start) + token + target.value.slice(end);
    const caret = start + token.length;
    target.focus(); target.setSelectionRange(caret,caret); renderPreview();
  }

  function selectedPreset(){ return state.presets.find(p => Number(p.id) === Number(state.selectedId)) || null; }

  function clearEditor(){
    state.selectedId = 0;
    els.id.value = ''; els.name.value = ''; els.useCase.value = 'custom'; els.sort.value = '100';
    els.active.checked = true; els.isDefault.checked = false; els.subject.value = ''; els.message.value = '';
    els.eyebrow.textContent = 'Create'; els.title.textContent = 'New push notification preset'; els.editorState.textContent = 'New';
    els.duplicateBtn.hidden = true; els.toggleBtn.hidden = true; els.deleteBtn.hidden = true;
    renderPreview(); renderList(); setNotice('');
  }

  function fillEditor(p){
    state.selectedId = Number(p.id);
    els.id.value = String(p.id || ''); els.name.value = p.preset_name || ''; els.useCase.value = p.use_case || 'custom';
    els.sort.value = String(p.sort_order ?? 100); els.active.checked = Number(p.is_active) === 1; els.isDefault.checked = Number(p.is_default) === 1;
    els.subject.value = p.subject_template || ''; els.message.value = p.message_template || '';
    els.eyebrow.textContent = 'Edit'; els.title.textContent = p.preset_name || 'Push notification preset';
    els.editorState.textContent = Number(p.is_active) === 1 ? 'Active' : 'Inactive';
    els.duplicateBtn.hidden = false; els.toggleBtn.hidden = false; els.deleteBtn.hidden = false;
    els.toggleBtn.textContent = Number(p.is_active) === 1 ? 'Deactivate' : 'Activate';
    renderPreview(); renderList(); setNotice('');
  }

  function editPreset(id){
    const p = state.presets.find(row => Number(row.id) === Number(id));
    if (p) fillEditor(p);
  }

  async function load(){
    setNotice('Loading presets…');
    try {
      const data = await api('list');
      state.installed = Number(data.installed || 0) === 1;
      state.presets = Array.isArray(data.presets) ? data.presets : [];
      state.useCases = data.use_cases || {};
      state.variables = data.variables || {};
      els.install.hidden = state.installed;
      renderUseCases(); renderVariables(); renderList();
      if (state.selectedId) {
        const selected = selectedPreset();
        if (selected) fillEditor(selected); else clearEditor();
      }
      setNotice(state.installed ? '' : 'Import migration 044 before managing presets.', state.installed ? '' : 'bad');
    } catch (error) {
      setNotice(error.message, 'bad');
    }
  }

  els.form.addEventListener('submit', async event => {
    event.preventDefault();
    const payload = {
      id:Number(els.id.value || 0), preset_name:els.name.value, use_case:els.useCase.value,
      sort_order:Number(els.sort.value || 100), is_active:els.active.checked ? 1 : 0, is_default:els.isDefault.checked ? 1 : 0,
      subject_template:els.subject.value, message_template:els.message.value
    };
    els.saveBtn.disabled = true; setNotice('Saving preset…');
    try {
      const data = await api('save', payload);
      state.presets = data.presets || state.presets;
      const saved = data.preset || null;
      setNotice('Push notification preset saved.', 'ok');
      if (saved) fillEditor(saved); else renderList();
    } catch (error) { setNotice(error.message, 'bad'); }
    finally { els.saveBtn.disabled = false; }
  });

  els.duplicateBtn.addEventListener('click', async () => {
    const id = Number(els.id.value || 0); if (!id) return;
    els.duplicateBtn.disabled = true; setNotice('Duplicating preset…');
    try {
      const data = await api('duplicate', {id});
      state.presets = data.presets || state.presets;
      if (data.preset) fillEditor(data.preset);
      setNotice('Push notification preset duplicated.', 'ok');
    } catch (error) { setNotice(error.message, 'bad'); }
    finally { els.duplicateBtn.disabled = false; }
  });

  els.toggleBtn.addEventListener('click', async () => {
    const p = selectedPreset(); if (!p) return;
    const next = Number(p.is_active) === 1 ? 0 : 1;
    els.toggleBtn.disabled = true; setNotice(next ? 'Activating preset…' : 'Deactivating preset…');
    try {
      const data = await api('toggle', {id:Number(p.id), is_active:next});
      state.presets = data.presets || state.presets;
      const refreshed = state.presets.find(row => Number(row.id) === Number(p.id));
      if (refreshed) fillEditor(refreshed);
      setNotice(next ? 'Push notification preset activated.' : 'Push notification preset deactivated.', 'ok');
    } catch (error) { setNotice(error.message, 'bad'); }
    finally { els.toggleBtn.disabled = false; }
  });

  els.deleteBtn.addEventListener('click', async () => {
    const p = selectedPreset(); if (!p) return;
    if (!window.confirm(`Delete the push notification preset “${p.preset_name}”? Existing sent notifications, queues and histories will not be changed.`)) return;
    els.deleteBtn.disabled = true; setNotice('Deleting preset…');
    try {
      const data = await api('delete', {id:Number(p.id)});
      state.presets = data.presets || [];
      clearEditor(); setNotice('Push notification preset deleted.', 'ok');
    } catch (error) { setNotice(error.message, 'bad'); }
    finally { els.deleteBtn.disabled = false; }
  });

  [els.subject,els.message].forEach(el => el.addEventListener('input', renderPreview));
  els.search.addEventListener('input', renderList); els.status.addEventListener('change', renderList);
  els.newBtn.addEventListener('click', clearEditor); els.clearBtn.addEventListener('click', clearEditor); els.reloadBtn.addEventListener('click', load);
  els.active.addEventListener('change', () => { if (!els.active.checked) els.isDefault.checked = false; });
  els.isDefault.addEventListener('change', () => { if (els.isDefault.checked) els.active.checked = true; });

  clearEditor(); load();
})();
