/**
 * persona-editor.mjs — AI-Do v4.0 persona editor modal
 * Allows editing avatar style, name, greeting, and personality trait sliders.
 */

import store from '../store.mjs';
import api from '../api.mjs';
import { show as showModal, close as closeModal } from './modal.mjs';
import { createElement } from '../utils/dom.mjs';

// ── Avatar body presets ──
const AVATAR_STYLES = [
  { id: 'avatar1', label: 'Style 1', src: '/assets/avatar1.png' },
  { id: 'avatar2', label: 'Style 2', src: '/assets/avatar2.png' },
  { id: 'avatar3', label: 'Style 3', src: '/assets/avatar3.png' },
  { id: 'avatar4', label: 'Style 4', src: '/assets/avatar4.png' }
];

// ── Trait definitions ──
const TRAITS = [
  {
    key: 'creativity',
    name: 'Creativity',
    labels: [
      { value: 0.1, text: 'Precise' },
      { value: 0.5, text: 'Balanced' },
      { value: 0.9, text: 'Wildly Creative' }
    ]
  },
  {
    key: 'verbosity',
    name: 'Verbosity',
    labels: [
      { value: 0.1, text: 'Concise' },
      { value: 0.5, text: 'Balanced' },
      { value: 0.9, text: 'Very Detailed' }
    ]
  },
  {
    key: 'formality',
    name: 'Formality',
    labels: [
      { value: 0.1, text: 'Casual' },
      { value: 0.5, text: 'Balanced' },
      { value: 0.9, text: 'Very Formal' }
    ]
  },
  {
    key: 'humor',
    name: 'Humor',
    labels: [
      { value: 0.1, text: 'Serious' },
      { value: 0.5, text: 'Balanced' },
      { value: 0.9, text: 'Comedian' }
    ]
  }
];

// ──────────────────────────────────────
// Public API
// ──────────────────────────────────────

export function openPersonaEditor() {
  const state = store.getState();
  const persona = { ...state.persona, traits: { ...state.persona.traits } };

  // Build the editor content element
  const content = buildEditorContent(persona);

  showModal({
    title: 'Edit Persona',
    content,
    closable: true,
    actions: [
      {
        label: 'Cancel',
        className: 'glass-button',
        onClick: () => closeModal()
      },
      {
        label: 'Save',
        className: 'glass-button glass-button-accent',
        onClick: () => savePersona(content)
      }
    ]
  });
}

// ──────────────────────────────────────
// Editor DOM construction
// ──────────────────────────────────────

function buildEditorContent(persona) {
  const editor = createElement('div', { className: 'persona-editor' });

  // Avatar selector
  const avatarGroup = createElement('div', { className: 'field-group' });
  avatarGroup.appendChild(createElement('label', { className: 'field-label' }, ['Avatar Style']));

  const avatarSelector = createElement('div', { className: 'avatar-selector' });

  for (const style of AVATAR_STYLES) {
    const option = createElement('button', {
      className: `avatar-option${persona.avatarStyle === style.id ? ' selected' : ''}`,
      dataset: { style: style.id },
      'aria-label': `Avatar: ${style.label}`,
      type: 'button'
    });
    option.style.cssText = 'padding:4px;border-radius:12px;border:2px solid transparent;background:var(--glass-bg,rgba(255,255,255,0.06));cursor:pointer;transition:border-color 0.2s,transform 0.2s;';
    if (persona.avatarStyle === style.id) {
      option.style.borderColor = 'var(--accent,#4a9eff)';
    }

    const img = createElement('img');
    img.src = style.src;
    img.alt = style.label;
    img.draggable = false;
    img.style.cssText = 'width:56px;height:56px;border-radius:8px;object-fit:cover;display:block;';
    option.appendChild(img);

    option.addEventListener('click', () => {
      const allOptions = avatarSelector.querySelectorAll('.avatar-option');
      for (const opt of allOptions) {
        opt.classList.remove('selected');
        opt.style.borderColor = 'transparent';
      }
      option.classList.add('selected');
      option.style.borderColor = 'var(--accent,#4a9eff)';
    });

    avatarSelector.appendChild(option);
  }

  avatarGroup.appendChild(avatarSelector);

  // Custom URL input
  const customUrlInput = createElement('input', {
    className: 'glass-input',
    type: 'text',
    placeholder: 'Custom avatar URL (optional)',
    dataset: { field: 'customAvatarUrl' }
  });
  avatarGroup.appendChild(customUrlInput);
  editor.appendChild(avatarGroup);

  // Name input
  const nameGroup = createElement('div', { className: 'field-group' });
  nameGroup.appendChild(createElement('label', { className: 'field-label' }, ['Name']));
  const nameInput = createElement('input', {
    className: 'glass-input',
    type: 'text',
    value: persona.name || '',
    placeholder: 'Agent name',
    dataset: { field: 'name' }
  });
  nameGroup.appendChild(nameInput);
  editor.appendChild(nameGroup);

  // Greeting textarea
  const greetingGroup = createElement('div', { className: 'field-group' });
  greetingGroup.appendChild(createElement('label', { className: 'field-label' }, ['Greeting']));
  const greetingTextarea = createElement('textarea', {
    className: 'glass-textarea',
    rows: '3',
    placeholder: 'Agent greeting message',
    dataset: { field: 'greeting' }
  });
  greetingTextarea.value = persona.greeting || '';
  greetingGroup.appendChild(greetingTextarea);
  editor.appendChild(greetingGroup);

  // Personality trait sliders
  const traitsLabel = createElement('div', { className: 'field-group' });
  traitsLabel.appendChild(createElement('label', { className: 'field-label' }, ['Personality Traits']));
  editor.appendChild(traitsLabel);

  for (const trait of TRAITS) {
    const traitEl = buildTraitSlider(trait, persona.traits[trait.key] || 0.5);
    editor.appendChild(traitEl);
  }

  return editor;
}

function buildTraitSlider(trait, currentValue) {
  const container = createElement('div', { className: 'trait-slider' });

  // Header with name and value
  const header = createElement('div', { className: 'trait-header' });
  header.appendChild(createElement('span', { className: 'trait-name' }, [trait.name]));

  const valueDisplay = createElement('span', { className: 'trait-value' }, [
    getDynamicLabel(trait, currentValue)
  ]);
  header.appendChild(valueDisplay);
  container.appendChild(header);

  // Range slider
  const slider = createElement('input', {
    className: 'glass-range',
    type: 'range',
    min: '0',
    max: '1',
    step: '0.1',
    value: String(currentValue),
    dataset: { trait: trait.key }
  });

  slider.addEventListener('input', () => {
    const val = parseFloat(slider.value);
    valueDisplay.textContent = getDynamicLabel(trait, val);
    updateTraitLabels(labelsRow, trait, val);
  });

  container.appendChild(slider);

  // Label row (low / mid / high)
  const labelsRow = createElement('div', { className: 'trait-labels' });
  for (const labelDef of trait.labels) {
    const isActive = Math.abs(currentValue - labelDef.value) < 0.15;
    const labelEl = createElement('span', {
      className: `trait-label-text${isActive ? ' active' : ''}`,
      dataset: { labelValue: String(labelDef.value) }
    }, [labelDef.text]);
    labelsRow.appendChild(labelEl);
  }
  container.appendChild(labelsRow);

  return container;
}

function getDynamicLabel(trait, value) {
  // Find the closest label
  let closest = trait.labels[0];
  let minDist = Math.abs(value - closest.value);

  for (const label of trait.labels) {
    const dist = Math.abs(value - label.value);
    if (dist < minDist) {
      minDist = dist;
      closest = label;
    }
  }

  return `${closest.text} (${value.toFixed(1)})`;
}

function updateTraitLabels(labelsRow, trait, value) {
  const labelEls = labelsRow.querySelectorAll('.trait-label-text');
  labelEls.forEach((el, i) => {
    const labelDef = trait.labels[i];
    const isActive = Math.abs(value - labelDef.value) < 0.15;
    if (isActive) {
      el.classList.add('active');
    } else {
      el.classList.remove('active');
    }
  });
}

// ──────────────────────────────────────
// Save
// ──────────────────────────────────────

async function savePersona(editorEl) {
  // Gather values from the editor
  const nameInput = editorEl.querySelector('[data-field="name"]');
  const greetingInput = editorEl.querySelector('[data-field="greeting"]');
  const selectedAvatar = editorEl.querySelector('.avatar-option.selected');
  const customUrlInput = editorEl.querySelector('[data-field="customAvatarUrl"]');

  const name = nameInput?.value?.trim() || 'AI-Do';
  const greeting = greetingInput?.value?.trim() || 'Hello! I\'m AI-Do, your personal AI.';
  const avatarStyle = selectedAvatar?.dataset?.style || 'default';

  // Collect trait values
  const traits = {};
  const sliders = editorEl.querySelectorAll('.glass-range[data-trait]');
  for (const slider of sliders) {
    traits[slider.dataset.trait] = parseFloat(slider.value);
  }

  const data = { name, greeting, avatarStyle, traits };

  // Include custom avatar URL if provided
  const customUrl = customUrlInput?.value?.trim();
  if (customUrl) {
    data.customAvatarUrl = customUrl;
  }

  // Dispatch to store immediately for responsive UI
  store.dispatch('SET_PERSONA', data);

  // Persist to server
  try {
    await api.updatePersona(data);
  } catch (err) {
    console.error('[persona-editor] Save failed:', err);
  }

  closeModal();
}
