// ═══════════════════════════════════════════════════════
//  CVC Dashboard — Settings Module
// ═══════════════════════════════════════════════════════
import * as api from './api';

let dirty = false;
let settingsCache: any = null;

function esc(s: string): string {
  const d = document.createElement('div');
  d.textContent = s;
  return d.innerHTML;
}

function toast(message: string, type: 'success' | 'error' | 'info' = 'info'): void {
  (window as any).toast?.(message, type);
}

// ── Collapsible sections ────────────────────────────
function setupCollapsible(): void {
  document.querySelectorAll('.card-header.collapsible').forEach(header => {
    header.addEventListener('click', () => {
      const targetId = (header as HTMLElement).dataset.target;
      if (!targetId) return;
      const body = document.getElementById(targetId);
      if (!body) return;
      const arrow = header.querySelector('.collapse-arrow');
      if (body.classList.contains('collapsed')) {
        body.classList.remove('collapsed');
        body.style.display = '';
        if (arrow) arrow.textContent = '▼';
      } else {
        body.classList.add('collapsed');
        body.style.display = 'none';
        if (arrow) arrow.textContent = '▶';
      }
    });
  });
}

// ── Level tabs ──────────────────────────────────────
function setupLevelTabs(): void {
  document.querySelectorAll('.settings-level-tab').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.settings-level-tab').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      // Filtering could be added here for level-specific views
    });
  });
}

// ── Search ──────────────────────────────────────────
function setupSearch(): void {
  const input = document.getElementById('settings-search') as HTMLInputElement;
  if (!input) return;
  input.addEventListener('input', () => {
    const q = input.value.toLowerCase();
    document.querySelectorAll('.settings-section').forEach(section => {
      const text = (section as HTMLElement).textContent?.toLowerCase() || '';
      (section as HTMLElement).style.display = !q || text.includes(q) ? '' : 'none';
    });
  });
}

// ── Mark dirty ──────────────────────────────────────
function markDirty(): void {
  dirty = true;
  const bar = document.getElementById('settings-save-bar');
  if (bar) bar.style.display = '';
}

// ── Populate form from settings data ────────────────
function populateForm(data: any): void {
  const g = data.global || {};
  const p = data.project || {};

  // Provider & Model
  setVal('setting-provider', g.provider || 'anthropic');
  setVal('setting-model', g.model || '');

  // API keys
  renderApiKeys(g.api_keys || {});

  // Agent behavior
  setVal('setting-output-style', p.outputStyle || p.output_style || 'concise');
  setChecked('setting-always-thinking', p.alwaysThinkingEnabled ?? p.always_thinking_enabled ?? false);
  setChecked('setting-auto-memory', p.autoMemoryEnabled ?? p.auto_memory_enabled ?? true);
  setVal('setting-compact-threshold', String(p.autoCompactThreshold ?? p.auto_compact_threshold ?? 50));
  setVal('setting-plan-display', p.plan_display || 'full');

  // Permissions
  setChecked('autopilot-toggle', (window as any)._autopilot ?? false);
  setVal('setting-trust-mode', p.trust_mode || 'balanced');
  setVal('setting-tools-allow', (p.permissions?.allow || []).join(', '));
  setVal('setting-tools-deny', (p.permissions?.deny || []).join(', '));

  // Advanced
  setVal('setting-trusted-cmds', (p.trusted_commands || []).join(', '));
  setVal('setting-blocked-cmds', (p.blocked_commands || []).join(', '));

  // Hooks
  renderHooks(p.hooks || {});

  // Env
  renderEnvVars(p.env || {});

  // Plugins
  renderPlugins(p.enabledPlugins ?? p.enabled_plugins ?? {});
}

function setVal(id: string, value: string): void {
  const el = document.getElementById(id) as HTMLInputElement | HTMLSelectElement;
  if (el) el.value = value;
}

function setChecked(id: string, checked: boolean): void {
  const el = document.getElementById(id) as HTMLInputElement;
  if (el) el.checked = checked;
}

// ── API Keys ────────────────────────────────────────
function renderApiKeys(keys: Record<string, string>): void {
  const container = document.getElementById('api-keys-container');
  if (!container) return;
  const providers = ['anthropic', 'openai', 'google', 'openrouter'];
  container.innerHTML = providers.map(p => {
    const has = !!keys[p];
    return `<div class="api-key-row">
      <span class="api-key-provider">${esc(p)}</span>
      <input type="password" class="input input-sm api-key-input" data-provider="${esc(p)}"
        value="${has ? '••••••••' : ''}" placeholder="sk-…" style="width:200px" />
      <button class="btn btn-sm ${has ? 'btn-green' : ''}" onclick="testApiKey('${esc(p)}')">${has ? '✓ Set' : 'Set'}</button>
      ${has ? `<button class="btn btn-sm btn-red" onclick="removeApiKeyUI('${esc(p)}')">✕</button>` : ''}
    </div>`;
  }).join('');
}

(window as any).testApiKey = async (provider: string) => {
  try {
    const result = await api.testApiKey(provider);
    toast(result.message || `${provider}: OK`, 'success');
  } catch (e) { toast((e as Error).message, 'error'); }
};

(window as any).removeApiKeyUI = async (provider: string) => {
  try {
    await api.removeApiKey(provider);
    toast(`${provider} key removed`, 'success');
    loadSettingsData();
  } catch (e) { toast((e as Error).message, 'error'); }
};

// ── Hooks ───────────────────────────────────────────
function renderHooks(hooks: Record<string, unknown[]>): void {
  const container = document.getElementById('hooks-list');
  if (!container) return;
  const entries = Object.entries(hooks);
  if (!entries.length) {
    container.innerHTML = '<p class="text-muted">No hooks configured.</p>';
    return;
  }
  container.innerHTML = entries.map(([event, cmds]) =>
    (cmds as string[]).map((cmd, i) =>
      `<div class="hook-row">
        <span class="tag tag-blue">${esc(event)}</span>
        <code>${esc(String(cmd))}</code>
        <button class="btn btn-sm btn-red" onclick="removeHookUI('${esc(event)}', ${i})">✕</button>
      </div>`
    ).join('')
  ).join('');
}

(window as any).removeHookUI = async (event: string, index: number) => {
  try {
    await api.removeHook(event, index);
    toast('Hook removed', 'success');
    loadSettingsData();
  } catch (e) { toast((e as Error).message, 'error'); }
};

// ── Env Vars ────────────────────────────────────────
function renderEnvVars(env: Record<string, string>): void {
  const container = document.getElementById('env-vars-list');
  if (!container) return;
  const entries = Object.entries(env);
  if (!entries.length) {
    container.innerHTML = '<p class="text-muted">No environment variables configured.</p>';
    return;
  }
  container.innerHTML = `<table class="data-table"><thead><tr><th>Key</th><th>Value</th></tr></thead><tbody>` +
    entries.map(([k, v]) =>
      `<tr><td><code>${esc(k)}</code></td><td>${esc(v)}</td></tr>`
    ).join('') + '</tbody></table>';
}

// ── Plugins ─────────────────────────────────────────
function renderPlugins(plugins: Record<string, boolean>): void {
  const container = document.getElementById('plugins-list');
  if (!container) return;
  const entries = Object.entries(plugins);
  if (!entries.length) {
    container.innerHTML = '<p class="text-muted">No plugins configured.</p>';
    return;
  }
  container.innerHTML = entries.map(([name, enabled]) =>
    `<div class="plugin-row">
      <label class="toggle-label">
        <input type="checkbox" ${enabled ? 'checked' : ''} data-plugin="${esc(name)}" class="plugin-toggle" />
        ${esc(name)}
      </label>
    </div>`
  ).join('');
}

// ── Save ────────────────────────────────────────────
async function saveSettings(): Promise<void> {
  try {
    // Gather global settings
    const provider = (document.getElementById('setting-provider') as HTMLSelectElement)?.value;
    const model = (document.getElementById('setting-model') as HTMLInputElement)?.value;

    // Save API keys that were changed
    const keyInputs = document.querySelectorAll('.api-key-input') as NodeListOf<HTMLInputElement>;
    for (const input of keyInputs) {
      const prov = input.dataset.provider;
      const val = input.value;
      if (prov && val && !val.startsWith('••')) {
        await api.setApiKey(prov, val);
      }
    }

    // Save global
    await api.updateGlobalSettings({ provider, model });

    // Gather project settings
    const projectData: Record<string, unknown> = {
      output_style: (document.getElementById('setting-output-style') as HTMLSelectElement)?.value,
      always_thinking_enabled: (document.getElementById('setting-always-thinking') as HTMLInputElement)?.checked,
      auto_memory_enabled: (document.getElementById('setting-auto-memory') as HTMLInputElement)?.checked,
      auto_compact_threshold: parseInt(
        (document.getElementById('setting-compact-threshold') as HTMLInputElement)?.value || '50',
      ),
      plan_display: (document.getElementById('setting-plan-display') as HTMLSelectElement)?.value,
      trust_mode: (document.getElementById('setting-trust-mode') as HTMLSelectElement)?.value,
      trusted_commands: parseCSV('setting-trusted-cmds'),
      blocked_commands: parseCSV('setting-blocked-cmds'),
      permission_allow: parseCSV('setting-tools-allow'),
      permission_deny: parseCSV('setting-tools-deny'),
    };
    await api.updateProjectSettings(projectData);

    dirty = false;
    const bar = document.getElementById('settings-save-bar');
    if (bar) bar.style.display = 'none';
    toast('Settings saved', 'success');
  } catch (e) {
    toast((e as Error).message, 'error');
  }
}

function parseCSV(id: string): string[] {
  const el = document.getElementById(id) as HTMLInputElement;
  if (!el || !el.value) return [];
  return el.value.split(',').map(s => s.trim()).filter(Boolean);
}

// ── Main loader ─────────────────────────────────────
export async function loadSettingsData(): Promise<void> {
  try {
    const [settings, vcs, auditResp] = await Promise.all([
      api.getSettings().catch(() => ({ global: {}, project: {}, schema: { sections: [] } })),
      api.getVCSStatus().catch(() => ({ provider: '—', has_repo: false })),
      api.getAudit().catch(() => ({ entries: [] })),
    ]);

    settingsCache = settings;
    populateForm(settings);

    // VCS
    const vcsEl = document.getElementById('settings-vcs');
    if (vcsEl) {
      vcsEl.innerHTML = `<div class="detail-grid">
        <div><span class="label">Provider</span><span class="value">${esc((vcs as any).provider || '—')}</span></div>
        <div><span class="label">Has Repo</span><span class="value">${(vcs as any).has_repo ? '<span class="tag tag-green">Yes</span>' : '<span class="tag tag-red">No</span>'}</span></div>
        <div><span class="label">Repo Root</span><span class="value code">${esc((vcs as any).repo_root || '—')}</span></div>
        <div><span class="label">Branch</span><span class="value">${esc((vcs as any).current_branch || '—')}</span></div>
      </div>`;
    }

    // Audit
    const auditEl = document.getElementById('settings-audit');
    if (auditEl) {
      const auditList = (auditResp as any).entries || (Array.isArray(auditResp) ? auditResp : []);
      if (!auditList.length) {
        auditEl.innerHTML = '<p class="text-muted">No audit entries.</p>';
      } else {
        auditEl.innerHTML = `<table class="data-table"><thead><tr><th>Time</th><th>Action</th><th>Details</th></tr></thead><tbody>` +
          auditList.slice(0, 50).map((e: any) =>
            `<tr><td>${(window as any).formatDate?.(e.created_at || e.timestamp) || e.created_at || ''}</td><td><code>${esc(e.event_type || e.action || '')}</code></td><td>${esc(e.action_detail ? JSON.stringify(e.action_detail) : (e.details || ''))}</td></tr>`
          ).join('') + '</tbody></table>';
      }
    }
  } catch { /* ignore */ }
}

// ── Init ────────────────────────────────────────────
export function initSettings(): void {
  setupCollapsible();
  setupLevelTabs();
  setupSearch();

  // Save / discard buttons
  document.getElementById('settings-save-btn')?.addEventListener('click', saveSettings);
  document.getElementById('settings-discard-btn')?.addEventListener('click', () => {
    dirty = false;
    const bar = document.getElementById('settings-save-bar');
    if (bar) bar.style.display = 'none';
    if (settingsCache) populateForm(settingsCache);
  });

  // Add hook
  document.getElementById('hook-add-btn')?.addEventListener('click', async () => {
    const event = (document.getElementById('hook-event-select') as HTMLSelectElement)?.value;
    const command = (document.getElementById('hook-command-input') as HTMLInputElement)?.value.trim();
    if (!event || !command) return;
    try {
      await api.addHook(event, command);
      toast('Hook added', 'success');
      (document.getElementById('hook-command-input') as HTMLInputElement).value = '';
      loadSettingsData();
    } catch (e) { toast((e as Error).message, 'error'); }
  });

  // Detect changes
  document.getElementById('tab-settings')?.addEventListener('change', markDirty);
  document.getElementById('tab-settings')?.addEventListener('input', markDirty);
}
