let inactivityState = {
  rules: [],
  editingId: 0
};

const esc = value => Pyrk.esc(value ?? '');

function toDays(value, unit) {
  const n = Math.max(1, Number(value || 1));
  if (unit === 'weeks') return n * 7;
  if (unit === 'months') return n * 30;
  return n;
}

function bestUnit(days) {
  days = Number(days || 0);
  if (days > 0 && days % 30 === 0) return {value: days / 30, unit: 'months'};
  if (days > 0 && days % 7 === 0) return {value: days / 7, unit: 'weeks'};
  return {value: days || 60, unit: 'days'};
}

function moneyInt(value) {
  return Number(value || 0).toLocaleString();
}

function dateText(value) {
  if (!value) return '—';
  return String(value).replace('T', ' ').slice(0, 16);
}

function statusPill(status) {
  const s = String(status || 'inactive');
  return `<span class="pill ${s === 'active' ? 'pill-green' : 'pill-muted'}">${esc(s)}</span>`;
}

function syncRulePreview() {
  const days = toDays(document.getElementById('inactiveValue').value, document.getElementById('inactiveUnit').value);
  document.getElementById('inactivityDays').value = days;
  const points = Number(document.getElementById('penaltyPoints').value || 0);
  const basis = document.getElementById('activityBasis').value === 'completed_walk' ? 'without a completed walk' : 'without walk activity';
  document.getElementById('rulePreviewBox').innerHTML = `Deduct <strong>${moneyInt(points)}</strong> points after <strong>${moneyInt(days)} days</strong> ${basis}.`;
  if (!document.getElementById('frequencyDays').dataset.touched) {
    document.getElementById('frequencyDays').value = days;
  }
}

function resetRuleForm() {
  inactivityState.editingId = 0;
  document.getElementById('ruleForm').reset();
  document.getElementById('ruleId').value = '';
  document.getElementById('inactiveValue').value = 2;
  document.getElementById('inactiveUnit').value = 'months';
  document.getElementById('penaltyPoints').value = 50;
  document.getElementById('frequencyDays').value = 60;
  document.getElementById('frequencyDays').dataset.touched = '';
  document.getElementById('minPoints').value = 1;
  document.getElementById('maxMembers').value = 0;
  document.getElementById('ruleStatus').value = 'active';
  document.getElementById('ruleFormMode').textContent = 'Create';
  document.getElementById('ruleFormTitle').textContent = 'Inactivity rule';
  syncRulePreview();
}

function fillRuleForm(rule) {
  inactivityState.editingId = Number(rule.id || 0);
  document.getElementById('ruleId').value = rule.id || '';
  document.getElementById('ruleName').value = rule.rule_name || '';
  document.getElementById('ruleDescription').value = rule.description || '';
  const unit = bestUnit(Number(rule.inactivity_days || 60));
  document.getElementById('inactiveValue').value = unit.value;
  document.getElementById('inactiveUnit').value = unit.unit;
  document.getElementById('penaltyPoints').value = Number(rule.penalty_points || 0);
  document.getElementById('frequencyDays').value = Number(rule.frequency_days || rule.inactivity_days || 60);
  document.getElementById('frequencyDays').dataset.touched = '1';
  document.getElementById('minPoints').value = Number(rule.min_points_before_penalty || 0);
  document.getElementById('maxMembers').value = Number(rule.max_members_per_run || 0);
  document.getElementById('activityBasis').value = rule.activity_basis || 'any_activity';
  document.getElementById('targetStatus').value = rule.target_user_status || 'active';
  document.getElementById('ruleStatus').value = rule.status || 'active';
  document.getElementById('allowNegative').checked = Number(rule.allow_negative || 0) === 1;
  document.getElementById('ruleFormMode').textContent = 'Edit';
  document.getElementById('ruleFormTitle').textContent = rule.rule_name || 'Edit rule';
  syncRulePreview();
  document.getElementById('ruleForm').scrollIntoView({behavior: 'smooth', block: 'start'});
}

function renderStats(stats = {}) {
  document.getElementById('statRules').textContent = Number(stats.rules || 0);
  document.getElementById('statActiveRules').textContent = Number(stats.active_rules || 0);
  document.getElementById('statMembers30').textContent = Number(stats.members_penalized_30d || 0);
  document.getElementById('statPoints30').textContent = moneyInt(stats.points_deducted_30d || 0);
}

function renderRules() {
  const box = document.getElementById('rulesList');
  const rules = inactivityState.rules || [];

  box.innerHTML = rules.map(rule => `
    <article class="inactivity-rule-card ${rule.status === 'active' ? 'is-active' : ''}">
      <div class="rule-card-head">
        <div>
          <h3>${esc(rule.rule_name)}</h3>
          <p class="muted small">${esc(rule.description || 'No description')}</p>
        </div>
        ${statusPill(rule.status)}
      </div>
      <div class="rule-metrics">
        <div><strong>${moneyInt(rule.inactivity_days)}</strong><span>inactive days</span></div>
        <div><strong>-${moneyInt(rule.penalty_points)}</strong><span>points</span></div>
        <div><strong>${moneyInt(rule.frequency_days)}</strong><span>repeat guard</span></div>
        <div><strong>${moneyInt(rule.total_applications || 0)}</strong><span>applications</span></div>
      </div>
      <div class="rule-tags">
        <span>${rule.activity_basis === 'completed_walk' ? 'Completed walks only' : 'Any activity'}</span>
        <span>${esc(rule.target_user_status || 'active')} accounts</span>
        <span>${Number(rule.allow_negative || 0) === 1 ? 'Can go negative' : 'Stops at zero'}</span>
      </div>
      <div class="rule-actions">
        <button class="btn btn-light btn-small" type="button" data-edit-rule="${Number(rule.id)}">Edit</button>
        <button class="btn btn-light btn-small" type="button" data-preview-rule="${Number(rule.id)}">Preview</button>
        <button class="btn btn-small" type="button" data-run-rule="${Number(rule.id)}" ${rule.status !== 'active' ? 'disabled' : ''}>Apply now</button>
        <button class="btn btn-danger btn-small" type="button" data-deactivate-rule="${Number(rule.id)}">Deactivate</button>
      </div>
    </article>
  `).join('') || '<p class="muted">No inactivity rules yet. Create the first rule from the form.</p>';
}

function renderRuns(runs = []) {
  const box = document.getElementById('runHistory');
  box.innerHTML = runs.map(run => `
    <article class="rule-run-card">
      <div><strong>${esc(run.rule_name || 'Rule')}</strong><small>${esc(dateText(run.started_at))}</small></div>
      <span>${Number(run.applied_count || 0)} members</span>
      <b>-${moneyInt(run.points_deducted || 0)} pts</b>
    </article>
  `).join('') || '<p class="muted">No runs yet.</p>';
}

async function loadInactivityRules() {
  const res = await Pyrk.get('loyalty_inactivity_rules.php', {action: 'overview'});
  if (!res.ok) {
    document.getElementById('rulesList').innerHTML = `<p class="notice bad">${esc(res.message)}</p>`;
    return;
  }

  if (!res.data.tables_ready) {
    document.getElementById('rulesList').innerHTML = `<p class="notice bad">Rules table is not installed. Run database/migrations/035_loyalty_inactivity_rules.sql</p>`;
    return;
  }

  inactivityState.rules = res.data.rules || [];
  renderStats(res.data.stats || {});
  renderRules();
  renderRuns(res.data.recent_runs || []);
}

async function previewRule(ruleId) {
  const res = await Pyrk.get('loyalty_inactivity_rules.php', {action: 'preview', id: ruleId, limit: 100});
  const body = document.getElementById('previewRows');

  if (!res.ok) {
    body.innerHTML = `<tr><td colspan="5" class="notice bad">${esc(res.message)}</td></tr>`;
    return;
  }

  const rows = res.data.members || [];
  body.innerHTML = rows.map(member => `
    <tr>
      <td><strong>${esc(member.full_name)}</strong><small>${esc(member.email || '')}</small></td>
      <td>${moneyInt(member.loyalty_points)}</td>
      <td>${moneyInt(member.inactive_days)}</td>
      <td><strong>-${moneyInt(member.points_to_deduct)}</strong></td>
      <td>${esc(dateText(member.last_activity_at))}</td>
    </tr>
  `).join('') || '<tr><td colspan="5" class="muted">No eligible members for this rule right now.</td></tr>';
}

async function saveRule(event) {
  event.preventDefault();
  syncRulePreview();

  const fd = new FormData(event.target);
  const payload = Object.fromEntries(fd);
  payload.action = 'save';
  payload.id = document.getElementById('ruleId').value || '';
  payload.inactivity_days = document.getElementById('inactivityDays').value;
  payload.allow_negative = document.getElementById('allowNegative').checked ? 1 : 0;

  const res = await Pyrk.post('loyalty_inactivity_rules.php', payload);
  Pyrk.toast('ruleMsg', res);
  if (res.ok) {
    resetRuleForm();
    await loadInactivityRules();
  }
}

async function runRule(ruleId) {
  const rule = (inactivityState.rules || []).find(r => Number(r.id) === Number(ruleId));
  if (!rule) return;
  if (!confirm(`Apply rule "${rule.rule_name}" now?\n\nThis will deduct points from eligible inactive members.`)) return;

  const res = await Pyrk.post('loyalty_inactivity_rules.php', {action: 'run', id: ruleId});
  alert(res.message || (res.ok ? 'Rule applied.' : 'Error'));
  if (res.ok) {
    await previewRule(ruleId);
    await loadInactivityRules();
  }
}

async function runAllRules() {
  if (!confirm('Apply all active inactivity rules now?')) return;
  const res = await Pyrk.post('loyalty_inactivity_rules.php', {action: 'run_all'});
  alert(res.message || (res.ok ? 'Rules applied.' : 'Error'));
  if (res.ok) await loadInactivityRules();
}

async function deactivateRule(ruleId) {
  if (!confirm('Deactivate this rule?')) return;
  const res = await Pyrk.post('loyalty_inactivity_rules.php', {action: 'deactivate', id: ruleId});
  alert(res.message || (res.ok ? 'Rule deactivated.' : 'Error'));
  if (res.ok) await loadInactivityRules();
}

document.getElementById('ruleForm')?.addEventListener('submit', saveRule);
document.getElementById('resetRuleBtn')?.addEventListener('click', resetRuleForm);
document.getElementById('runAllRulesBtn')?.addEventListener('click', runAllRules);
document.getElementById('frequencyDays')?.addEventListener('input', e => { e.target.dataset.touched = '1'; });

['inactiveValue', 'inactiveUnit', 'penaltyPoints', 'activityBasis'].forEach(id => {
  document.getElementById(id)?.addEventListener('input', syncRulePreview);
  document.getElementById(id)?.addEventListener('change', syncRulePreview);
});

document.addEventListener('click', e => {
  const edit = e.target.closest('[data-edit-rule]');
  if (edit) {
    const rule = (inactivityState.rules || []).find(r => Number(r.id) === Number(edit.dataset.editRule));
    if (rule) fillRuleForm(rule);
    return;
  }

  const preview = e.target.closest('[data-preview-rule]');
  if (preview) {
    previewRule(Number(preview.dataset.previewRule));
    return;
  }

  const run = e.target.closest('[data-run-rule]');
  if (run) {
    runRule(Number(run.dataset.runRule));
    return;
  }

  const deactivate = e.target.closest('[data-deactivate-rule]');
  if (deactivate) {
    deactivateRule(Number(deactivate.dataset.deactivateRule));
  }
});

resetRuleForm();
loadInactivityRules();
