{% extends "base.html" %}
{% import "_macros.html" as ui %}
{% block title %}{{ 'Business Groups' if tab == 'businesses' else ('RSS' if tab == 'rss-bots' else tab | title) }} — SimpleX Manager{% endblock %}

{% block head %}
<style>
  .empty-state { text-align: center; padding: 56px 24px; color: var(--muted); }
  .empty-state p { margin-top: 8px; font-size: 13px; }

  .profile-card { cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
                  border: 1px solid transparent; }
  .profile-card:hover { border-color: var(--accent); }
  .profile-card:active { transform: translateY(1px); }

  .addr-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
  .addr-link { flex: 1; min-width: 0; color: var(--muted); font-family: monospace; font-size: 12px;
               text-decoration: none; word-break: break-all; }
  .addr-link:hover { color: var(--accent); text-decoration: underline; }
  .copy-btn { flex-shrink: 0; padding: 4px 9px; font-size: 13px; line-height: 1; }

  .bot-types-card table td { vertical-align: top; }
  .bot-types-card .tag { white-space: nowrap; }

  .chk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 6px 12px; }
  .chk { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 500;
         color: var(--text); cursor: pointer; }
  .chk input { width: auto; }
</style>
{% endblock %}

{% block content %}
{% set new_label = 'User' if tab == 'users' else ('Business Group' if tab == 'businesses' else ('RSS Bot' if tab == 'rss-bots' else 'Bot')) %}
{% set page_title = 'Business Groups' if tab == 'businesses' else ('RSS' if tab == 'rss-bots' else tab | title) %}
<div class="flex-between" style="margin-bottom: 24px;">
  <h1 style="margin:0;">{{ page_title }}</h1>
  <button class="btn btn-primary" onclick="openCreate()">
    + New {{ new_label }}
  </button>
</div>

{% if tab == 'businesses' %}
<div class="card bot-types-card" style="margin-bottom:24px;">
  <h2 style="font-size:15px;margin-bottom:8px;">Business Groups</h2>
  <p class="muted" style="font-size:13px;">
    A business group uses a <strong>business address</strong>: each customer who connects gets
    their own group chat (so teammates can be added). You handle those conversations here, the same
    way you chat in a group. Set an optional welcome message to auto-greet new customers.
  </p>
</div>
{% endif %}

{% if tab == 'rss-bots' %}
<div class="card bot-types-card" style="margin-bottom:24px;">
  <h2 style="font-size:15px;margin-bottom:8px;">RSS</h2>
  <p class="muted" style="font-size:13px;">
    RSS bots read from an RSS/Atom feed and post new items to a channel. To receive a feed,
    share the bot's <strong>channel</strong> link with subscribers — open the bot and copy its
    <strong>channel</strong> link, <strong>not</strong> the user address.
  </p>
</div>
{% endif %}

{% if tab == 'bots' %}
<div class="card bot-types-card" style="margin-bottom:24px;">
  <h2 style="font-size:15px;margin-bottom:12px;">Available bot types</h2>
  <table>
    <tr><td><span class="tag">echo</span></td><td class="muted">Repeats every message back to the sender — handy for testing a connection end to end.</td></tr>
    <tr><td><span class="tag">llm</span></td><td class="muted">Chat with a local or remote LLM (OpenAI-compatible, e.g. Ollama). Give it context, it replies to your messages.</td></tr>
    <tr><td><span class="tag">crypto</span></td><td class="muted">Streams selected crypto prices (CoinGecko) to a channel on an interval. Pick coins &amp; currencies below.</td></tr>
    <tr><td><span class="tag">broadcast</span></td><td class="muted">Relays messages from authorized publishers out to all of the bot's contacts.</td></tr>
    <tr><td><span class="tag">support</span></td><td class="muted">Business inbox — auto-replies with a welcome message and collects incoming inquiries.</td></tr>
    <tr><td><span class="tag">directory</span></td><td class="muted">Directory service for discovering and listing groups or contacts.</td></tr>
    <tr><td><span class="tag">deadmans</span></td><td class="muted">Dead man's switch — triggers an action if expected check-ins stop arriving.</td></tr>
  </table>
</div>
{% endif %}

{% if items %}
  {% for p in items %}
  <div class="card profile-card" id="profile-{{ p.id }}"
       onclick="location.href='/profile/{{ p.id }}'">
    <div class="flex-between">
      <div class="flex gap-8">
        {% if p.config.avatar %}
        <img src="{{ p.config.avatar }}" alt=""
             style="width:32px;height:32px;border-radius:50%;object-fit:cover;border:1px solid var(--border);flex-shrink:0;">
        {% endif %}
        <strong>{{ p.name }}</strong>
        <span class="tag {% if p.bot_type == 'user' %}tag-user{% endif %}">{{ p.bot_type }}</span>
        <span class="badge {% if p.running %}badge-green{% else %}badge-red{% endif %}"
              id="status-{{ p.id }}"
              hx-get="/api/profiles/{{ p.id }}/status"
              hx-trigger="every 5s"
              hx-swap="none"
              hx-on::after-request="updateStatus({{ p.id }}, event)">
          {% if p.running %}running{% else %}stopped{% endif %}
        </span>
      </div>
      <div class="flex gap-8" onclick="event.stopPropagation()">
        <button class="btn btn-success" style="padding:6px 14px;font-size:13px;"
                hx-post="/api/profiles/{{ p.id }}/start" hx-swap="none"
                onclick="this.textContent='Starting…'">Start</button>
        <button class="btn btn-danger" style="padding:6px 14px;font-size:13px;"
                hx-post="/api/profiles/{{ p.id }}/stop" hx-swap="none"
                onclick="this.textContent='Stopping…'">Stop</button>
      </div>
    </div>
    {% if tab == 'rss-bots' %}
    <div style="margin-top:8px;font-size:12px;color:var(--muted);">
      <i class="fa-solid fa-clock"></i>
      <span id="poll-{{ p.id }}">{{ '—' if not p.running else 'Loading…' }}</span>
    </div>
    {% endif %}
    {% if p.address %}
    <div onclick="event.stopPropagation()" style="margin-top:10px;">{{ ui.linkbox(p.address, 'p' ~ p.id) }}</div>
    {% endif %}
  </div>
  {% endfor %}
{% else %}
<div class="empty-state card">
  {% if tab == 'users' %}
  <strong>No users yet</strong>
  <p>Create a SimpleX user account to manage contacts and channels.</p>
  {% elif tab == 'businesses' %}
  <strong>No business groups yet</strong>
  <p>Create a business group; each customer who connects gets their own group chat.</p>
  {% elif tab == 'rss-bots' %}
  <strong>No RSS bots yet</strong>
  <p>Create an RSS bot to post a feed to a channel.</p>
  {% else %}
  <strong>No bots yet</strong>
  <p>Bots can echo messages, broadcast to subscribers, or run automated tasks.</p>
  {% endif %}
</div>
{% endif %}

<!-- Create dialog -->
<dialog id="create-dialog">
  <h2 style="margin-bottom:20px;">New {{ new_label }}</h2>
  <form id="create-form">
    <div class="field">
      <label>Name</label>
      <input type="text" name="name" placeholder="{{ 'Alice' if tab == 'users' else ('Acme Inc' if tab == 'businesses' else 'My Bot') }}" required>
    </div>
    <div class="field">
      <label>Bio / Description <span class="muted" style="font-weight:400;">(optional)</span></label>
      <textarea name="bio" rows="2" placeholder="A short description shown on the profile"></textarea>
    </div>
    <div class="field">
      <label>Avatar <span class="muted" style="font-weight:400;">(optional image)</span></label>
      <div class="flex gap-8">
        <img id="avatar-preview" alt="" style="display:none;width:48px;height:48px;border-radius:50%;object-fit:cover;border:1px solid var(--border);">
        <input type="file" name="avatar_file" accept="image/*" onchange="onAvatarChange(this)" style="flex:1;">
      </div>
    </div>
    {% if tab == 'businesses' %}
    <div class="field">
      <label>Welcome Message <span class="muted" style="font-weight:400;">(optional auto-reply to new customers)</span></label>
      <input type="text" name="welcome_message" placeholder="Thanks for reaching out! How can we help?">
    </div>
    {% endif %}
    {% if tab == 'rss-bots' %}
    <div class="field">
      <label>Feed URL</label>
      <input type="text" name="feed_url" placeholder="https://example.com/feed.xml">
    </div>
    <div class="field">
      <label>How often to check the feed</label>
      <div class="chk-grid">
        <label class="chk"><input type="radio" name="rss_poll" value="3600" checked> Per hour</label>
        <label class="chk"><input type="radio" name="rss_poll" value="86400"> Per day</label>
        <label class="chk"><input type="radio" name="rss_poll" value="604800"> Per week</label>
      </div>
    </div>
    {% endif %}
    {% if tab == 'bots' %}
    <div class="field">
      <label>Bot Type</label>
      <select name="profile_type" id="type-select" onchange="onTypeChange()">
        {% for t in create_types %}
        <option value="{{ t }}">{{ t }}</option>
        {% endfor %}
      </select>
    </div>
    <div class="field" id="welcome-field">
      <label>Welcome Message</label>
      <input type="text" name="welcome_message" placeholder="Welcome! How can I help?">
    </div>
    <div id="support-fields" style="display:none;">
      <div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
        <p class="muted" style="margin-bottom:12px;">
          LLM backend (OpenAI-compatible — works with a local Ollama via <code>ollama serve</code>,
          OpenAI, Grok…). The LLM bot needs the URL; support bots may leave it blank for a
          welcome-only inbox.
        </p>
      </div>
      <div class="field">
        <label>API Base URL</label>
        <input type="text" name="api_base" placeholder="http://localhost:11434/v1   (Ollama)   ·   https://api.x.ai/v1">
      </div>
      <div class="field">
        <label>API Key <span class="muted" style="font-weight:400;">(any value for Ollama)</span></label>
        <input type="password" name="api_key" placeholder="ollama   ·   xai-…">
      </div>
      <div class="field">
        <label>Model</label>
        <input type="text" name="model" placeholder="llama3.2   (Ollama)   ·   grok-2">
      </div>
      <div class="field">
        <label>Context <span class="muted" style="font-weight:400;">(system prompt given on start-up)</span></label>
        <textarea name="system_prompt" rows="3" placeholder="You are a helpful assistant…"></textarea>
      </div>
    </div>
    <div id="deadmans-fields" style="display:none;">
      <div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
        <p class="muted" style="margin-bottom:12px;">
          Fires a message to recipients if no check-in arrives in time. Check in by messaging the bot.
        </p>
      </div>
      <div class="field">
        <label>Check-in window (hours)</label>
        <input type="number" name="checkin_hours" min="0.1" step="0.1" value="24">
      </div>
      <div class="field">
        <label>Trigger message</label>
        <textarea name="dms_message" rows="2" placeholder="If you receive this, I haven't checked in…"></textarea>
      </div>
      <div class="field">
        <label>Recipients <span class="muted" style="font-weight:400;">(comma-separated names; blank = all contacts)</span></label>
        <input type="text" name="recipients" placeholder="Alice, Bob">
      </div>
      <div class="field">
        <label>Owner <span class="muted" style="font-weight:400;">(only this contact's messages count as check-in; blank = anyone)</span></label>
        <input type="text" name="owner" placeholder="Alice">
      </div>
    </div>
    <div id="directory-fields" style="display:none;">
      <div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
        <p class="muted" style="margin-bottom:12px;">
          Group owners register by adding this bot to their group. Listings stay pending until a super-user approves.
        </p>
      </div>
      <div class="field">
        <label>Super-users <span class="muted" style="font-weight:400;">(comma-separated contact names who can /approve)</span></label>
        <input type="text" name="superusers" placeholder="Alice, Bob">
      </div>
    </div>
    <div id="broadcast-fields" style="display:none;">
      <div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
        <p class="muted" style="margin-bottom:12px;">
          Only listed publishers can broadcast; their text/links are relayed to every contact.
          Anyone else gets the prohibited reply and their message is deleted.
        </p>
      </div>
      <div class="field">
        <label>Publishers <span class="muted" style="font-weight:400;">(comma-separated; "Name" or "ID:Name")</span></label>
        <input type="text" name="publishers" placeholder="Alice, 2:Bob">
      </div>
      <div class="field">
        <label>Prohibited reply <span class="muted" style="font-weight:400;">(blank = default listing publishers)</span></label>
        <input type="text" name="prohibited_message" placeholder="Only publishers can broadcast. Your message is deleted.">
      </div>
    </div>
    <div id="crypto-fields" style="display:none;">
      <div style="border-top:1px solid var(--border);margin:4px 0 14px;padding-top:14px;">
        <p class="muted" style="margin-bottom:12px;">
          Posts a price snapshot of the selected coins to a channel every interval (via CoinGecko).
        </p>
      </div>
      <div class="field">
        <label>Coins</label>
        <div class="chk-grid">
          <label class="chk"><input type="checkbox" name="coin" value="bitcoin" checked> Bitcoin</label>
          <label class="chk"><input type="checkbox" name="coin" value="ethereum" checked> Ethereum</label>
          <label class="chk"><input type="checkbox" name="coin" value="solana"> Solana</label>
          <label class="chk"><input type="checkbox" name="coin" value="ripple"> XRP</label>
          <label class="chk"><input type="checkbox" name="coin" value="cardano"> Cardano</label>
          <label class="chk"><input type="checkbox" name="coin" value="dogecoin"> Dogecoin</label>
          <label class="chk"><input type="checkbox" name="coin" value="binancecoin"> BNB</label>
          <label class="chk"><input type="checkbox" name="coin" value="polkadot"> Polkadot</label>
          <label class="chk"><input type="checkbox" name="coin" value="litecoin"> Litecoin</label>
          <label class="chk"><input type="checkbox" name="coin" value="tron"> TRON</label>
          <label class="chk"><input type="checkbox" name="coin" value="chainlink"> Chainlink</label>
          <label class="chk"><input type="checkbox" name="coin" value="tether"> Tether</label>
        </div>
      </div>
      <div class="field">
        <label>Currencies</label>
        <div class="chk-grid">
          <label class="chk"><input type="checkbox" name="cur" value="usd" checked> USD</label>
          <label class="chk"><input type="checkbox" name="cur" value="gbp" checked> GBP</label>
          <label class="chk"><input type="checkbox" name="cur" value="eur"> EUR</label>
          <label class="chk"><input type="checkbox" name="cur" value="jpy"> JPY</label>
          <label class="chk"><input type="checkbox" name="cur" value="aud"> AUD</label>
          <label class="chk"><input type="checkbox" name="cur" value="cad"> CAD</label>
        </div>
      </div>
      <div class="field">
        <label>Poll interval <span class="muted" style="font-weight:400;">(seconds)</span></label>
        <input type="number" name="crypto_poll_seconds" min="60" value="300">
      </div>
    </div>
    {% endif %}
    <div class="flex gap-8 mt-16" style="justify-content:flex-end;">
      <button type="button" class="btn btn-ghost"
              onclick="document.getElementById('create-dialog').close()">Cancel</button>
      <button type="submit" class="btn btn-primary">Create</button>
    </div>
  </form>
</dialog>

<script>
const _pollNextMap = {};   // profile_id → poll_next epoch (seconds)

function fmtCountdown(secs) {
  if (secs <= 0) return 'polling now…';
  const h = Math.floor(secs / 3600);
  const m = Math.floor((secs % 3600) / 60);
  const s = Math.floor(secs % 60);
  if (h > 0) return `in ${h}h ${m}m`;
  if (m > 0) return `in ${m}m ${s}s`;
  return `in ${s}s`;
}

function tickPolls() {
  const now = Date.now() / 1000;
  for (const [id, pollNext] of Object.entries(_pollNextMap)) {
    const el = document.getElementById('poll-' + id);
    if (!el) continue;
    el.textContent = pollNext > 0 ? fmtCountdown(pollNext - now) : '—';
  }
}
setInterval(tickPolls, 1000);

function updateStatus(id, event) {
  try {
    const data = JSON.parse(event.detail.xhr.responseText);
    const badge = document.getElementById('status-' + id);
    if (badge) {
      badge.textContent = data.running ? 'running' : 'stopped';
      badge.className = 'badge ' + (data.running ? 'badge-green' : 'badge-red');
    }
    if (data.poll_next !== undefined) {
      _pollNextMap[id] = data.running ? data.poll_next : 0;
      const el = document.getElementById('poll-' + id);
      if (el) el.textContent = data.running && data.poll_next > 0
        ? fmtCountdown(data.poll_next - Date.now() / 1000) : '—';
    }
  } catch(e) {}
}

let avatarDataUri = '';

function openCreate() {
  document.getElementById('create-form').reset();
  avatarDataUri = '';
  const prev = document.getElementById('avatar-preview');
  prev.style.display = 'none'; prev.src = '';
  {% if tab == 'bots' %}onTypeChange();{% endif %}
  document.getElementById('create-dialog').showModal();
}

// Read an image file, downscale it to a small square data URI (avatars are sent
// over the wire to every contact, so keep them tiny). Stores result in avatarDataUri.
function onAvatarChange(input) {
  const file = input.files && input.files[0];
  if (!file) { avatarDataUri = ''; return; }
  const reader = new FileReader();
  reader.onload = (e) => {
    const img = new Image();
    img.onload = () => {
      const size = 256;
      const canvas = document.createElement('canvas');
      canvas.width = size; canvas.height = size;
      const ctx = canvas.getContext('2d');
      // center-crop to square
      const m = Math.min(img.width, img.height);
      const sx = (img.width - m) / 2, sy = (img.height - m) / 2;
      ctx.drawImage(img, sx, sy, m, m, 0, 0, size, size);
      avatarDataUri = canvas.toDataURL('image/jpeg', 0.85);
      const prev = document.getElementById('avatar-preview');
      prev.src = avatarDataUri; prev.style.display = 'block';
    };
    img.src = e.target.result;
  };
  reader.readAsDataURL(file);
}

// robustCopy and the SimpleX link box (sx*) live in base.html (shared).

{% if tab == 'bots' %}
function onTypeChange() {
  const val = document.getElementById('type-select').value;
  document.getElementById('welcome-field').style.display = (val === 'echo') ? 'none' : '';
  document.getElementById('support-fields').style.display = (val === 'support' || val === 'llm') ? 'block' : 'none';
  document.getElementById('deadmans-fields').style.display = (val === 'deadmans') ? 'block' : 'none';
  document.getElementById('directory-fields').style.display = (val === 'directory') ? 'block' : 'none';
  document.getElementById('broadcast-fields').style.display = (val === 'broadcast') ? 'block' : 'none';
  document.getElementById('crypto-fields').style.display = (val === 'crypto') ? 'block' : 'none';
}
{% endif %}

document.getElementById('create-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const fd = new FormData(e.target);
  {% if tab == 'users' %}
  const botType = 'user';
  const config = {};
  {% else %}
  const botType = fd.get('profile_type') || '{{ create_types[0] }}';
  const config = {};
  const welcome = fd.get('welcome_message');
  if (welcome) config.welcome_message = welcome;
  if (botType === 'support' || botType === 'llm') {
    const apiBase = (fd.get('api_base') || '').trim();
    if (apiBase) config.api_base = apiBase;
    const apiKey = (fd.get('api_key') || '').trim();
    if (apiKey) config.api_key = apiKey;
    const model = (fd.get('model') || '').trim();
    if (model) config.model = model;
    const sysPrompt = (fd.get('system_prompt') || '').trim();
    if (sysPrompt) config.system_prompt = sysPrompt;
  }
  if (botType === 'deadmans') {
    const hrs = parseFloat(fd.get('checkin_hours'));
    if (!isNaN(hrs) && hrs > 0) config.checkin_hours = hrs;
    const dmsMsg = (fd.get('dms_message') || '').trim();
    if (dmsMsg) config.message = dmsMsg;
    const recips = (fd.get('recipients') || '').split(',').map(s => s.trim()).filter(Boolean);
    if (recips.length) config.recipients = recips;
    const owner = (fd.get('owner') || '').trim();
    if (owner) config.owner = owner;
  }
  if (botType === 'directory') {
    const su = (fd.get('superusers') || '').split(',').map(s => s.trim()).filter(Boolean);
    if (su.length) config.superusers = su;
  }
  if (botType === 'broadcast') {
    const pubs = (fd.get('publishers') || '').split(',').map(s => s.trim()).filter(Boolean);
    if (pubs.length) config.publishers = pubs;
    const prohibited = (fd.get('prohibited_message') || '').trim();
    if (prohibited) config.prohibited_message = prohibited;
  }
  if (botType === 'rss') {
    const url = (fd.get('feed_url') || '').trim();
    if (!url) { alert('Feed URL is required for an RSS bot'); return; }
    config.feed_url = url;
    const ps = parseInt(fd.get('rss_poll'), 10);
    if (!isNaN(ps)) config.poll_seconds = ps;
  }
  if (botType === 'crypto') {
    const coins = Array.from(document.querySelectorAll('#crypto-fields input[name=coin]:checked')).map(c => c.value);
    const curs  = Array.from(document.querySelectorAll('#crypto-fields input[name=cur]:checked')).map(c => c.value);
    if (!coins.length) { alert('Pick at least one coin'); return; }
    if (!curs.length)  { alert('Pick at least one currency'); return; }
    config.coins = coins;
    config.currencies = curs;
    const ps = parseInt(fd.get('crypto_poll_seconds'), 10);
    if (!isNaN(ps) && ps >= 60) config.poll_seconds = ps;
  }
  {% endif %}
  // Shared profile fields (users and bots)
  const bio = (fd.get('bio') || '').trim();
  if (bio) config.bio = bio;
  if (avatarDataUri) config.avatar = avatarDataUri;
  const token = document.cookie.match(/(?:^|;\s*)token=([^;]+)/)?.[1] || '';
  const resp = await fetch('/api/profiles', {
    method: 'POST',
    headers: {'Content-Type': 'application/json', 'X-Token': token},
    body: JSON.stringify({name: fd.get('name'), bot_type: botType, config}),
  });
  if (resp.ok) {
    document.getElementById('create-dialog').close();
    location.reload();
  } else {
    const err = await resp.json();
    alert('Error: ' + (err.detail || 'unknown'));
  }
});
</script>
{% endblock %}
