import { renderHeader } from '../components/header.js';
import { authService, state } from '../state.js';
import {
  buildIdentityLines,
  loadRelationsForPair,
  loadUserProfileCard,
} from '../services/user-connections.js';
import { renderUserAvatar } from '../components/avatar-image.js';
import { makeProfileLinksRoute } from '../services/shine-routes.js';

import { navigateBack } from '../router.js';

export const pageMeta = { id: 'user', title: 'Чужой профиль' };

function escapeHtml(text) {
  return String(text || '')
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

function openProfileInfoModal({ title, text }) {
  const root = document.getElementById('modal-root');
  if (!root) return;
  root.innerHTML = `
    <div class="modal" id="profile-info-modal">
      <div class="modal-card stack">
        <h3 class="modal-title">${escapeHtml(title)}</h3>
        <p class="meta-muted" style="white-space: pre-wrap; line-height: 1.45;">${escapeHtml(text)}</p>
        <button class="secondary-btn" type="button" id="profile-info-close">Закрыть</button>
      </div>
    </div>
  `;
  const close = () => { root.innerHTML = ''; };
  root.querySelector('#profile-info-close')?.addEventListener('click', close);
  root.querySelector('#profile-info-modal')?.addEventListener('click', (event) => {
    if (event.target?.id === 'profile-info-modal') close();
  });
}

function officialInfoText() {
  return 'Можно создавать несколько альтернативных или анонимных каналов. '
    + 'Но для корректного учёта голосов на одного реального человека используется только один официальный канал.';
}

function shineInfoText() {
  return 'Сияющие — это те, от кого идёт внутреннее сияние на тонком плане.\n\n'
    + 'Пять принципов сияющих:\n'
    + '1) сияющие не обманывают;\n'
    + '2) сияющие чувствуют, что человек — это не только физическое тело, а нечто большее;\n'
    + '3) сияющие развиваются и в духовной, и в материальной плоскости;\n'
    + '4) у сияющих есть близкие друзья, с которыми им по-настоящему хорошо;\n'
    + '5) сияющие заботятся о мире: о людях, гармонии и общем благе.';
}

function genderText(value) {
  const normalized = String(value || '').trim().toLowerCase();
  if (normalized === 'male') return 'Мужской';
  if (normalized === 'female') return 'Женский';
  return 'Не указан';
}

function relationButtonLabel(kind, flags) {
  if (kind === 'contact') return flags.outContact ? 'Убрать из контактов' : 'Добавить в контакты';
  if (kind === 'friend') return flags.outFriend ? 'Убрать из близких друзей' : 'Добавить в близкие друзья';
  return flags.outFollow ? 'Отписаться' : 'Подписаться';
}

function relationNextState(kind, flags) {
  if (kind === 'contact') return !flags.outContact;
  if (kind === 'friend') return !flags.outFriend;
  return !flags.outFollow;
}

function relationConfirmLabel(kind) {
  if (kind === 'contact') return 'контакт';
  if (kind === 'friend') return 'статус близкого друга';
  return 'подписку';
}

function relationStateText(kind, flags) {
  if (kind === 'contact') {
    if (flags.outContact && flags.inContact) return 'Вы обменялись контактами.';
    if (flags.outContact) return 'Вы добавили этот профиль в контакты.';
    if (flags.inContact) return 'Этот профиль добавил вас в контакты.';
    return '';
  }
  if (kind === 'friend') {
    if (flags.outFriend && flags.inFriend) return 'Вы взаимно близкие друзья.';
    if (flags.outFriend) return 'Вы считаете этот профиль близким другом.';
    if (flags.inFriend) return 'Этот профиль считает вас близким другом.';
    return '';
  }
  if (flags.outFollow && flags.inFollow) return 'Вы взаимно подписаны.';
  if (flags.outFollow) return 'Вы подписаны на этот профиль.';
  if (flags.inFollow) return 'Этот профиль подписан на вас.';
  return '';
}

function opinionItemsFromFlags(flags) {
  const items = [];
  if (flags.outShineSeen) {
    items.push({
      kind: 'shine_seen',
      text: 'вы утверждаете, что очень мало знаете этого человека, но вы видели его сияющим, и всё, что вы о нём знаете, подтверждает это',
      label: 'видел сияющим',
    });
  }
  if (flags.outShineConfirmed) {
    items.push({
      kind: 'shine_confirmed',
      text: 'вы утверждаете, что достаточно хорошо знаете этого человека и точно уверены, что этот человек сияющий',
      label: 'точно сияющий',
    });
  }
  if (flags.outKnownPerson) {
    items.push({
      kind: 'known_person',
      text: 'вы утверждаете, что просто знаете этого человека',
      label: 'просто знаю',
    });
  }
  return items;
}

function resolveActiveOpinionKind(flags) {
  if (flags.outShineSeen) return 'shine_seen';
  if (flags.outShineConfirmed) return 'shine_confirmed';
  if (flags.outKnownPerson) return 'known_person';
  return '';
}

function opinionLabelByKind(kind) {
  if (kind === 'shine_seen') return 'мало знаком, но видел сияющим';
  if (kind === 'shine_confirmed') return 'точно уверен, что сияющий';
  if (kind === 'known_person') return 'просто знаю человека';
  return kind;
}

function renderIdentity(card) {
  const lines = buildIdentityLines({
    login: card.login,
    firstName: card.firstName,
    lastName: card.lastName,
  });

  const row = document.createElement('div');
  row.className = 'row';
  row.style.gap = '12px';
  row.style.alignItems = 'center';

  row.append(renderUserAvatar({
    login: card.login,
    firstName: card.firstName,
    lastName: card.lastName,
    avatar: card.avatar,
    size: 'large',
    className: 'profile-avatar',
  }));

  const identityLines = document.createElement('div');
  identityLines.className = 'profile-identity-lines';
  lines.forEach((line, idx) => {
    const lineEl = document.createElement('div');
    lineEl.className = `profile-identity-line${idx === lines.length - 1 ? ' profile-identity-login' : ''}`;
    lineEl.textContent = line;
    identityLines.append(lineEl);
  });
  row.append(identityLines);

  return row;
}

function renderReadOnlyBadges(card) {
  return `
    <div class="row wrap-row">
      <button class="badge profile-badge-trigger ${card.official ? 'is-yes-official' : 'is-no'}" type="button" data-profile-info="official">Официальный: ${card.official ? 'Yes' : 'No'}</button>
      <button class="badge profile-badge-trigger ${card.shine ? 'is-yes-shine' : 'is-no'}" type="button" data-profile-info="shine">Сияющий: ${card.shine ? 'Yes' : 'No'}</button>
    </div>
  `;
}

function renderRelations(flags) {
  const rows = [
    { kind: 'contact', text: relationStateText('contact', flags), button: relationButtonLabel('contact', flags) },
    { kind: 'friend', text: relationStateText('friend', flags), button: relationButtonLabel('friend', flags) },
    { kind: 'follow', text: relationStateText('follow', flags), button: relationButtonLabel('follow', flags) },
  ];
  const opinionItems = opinionItemsFromFlags(flags);
  const hasOpinion = opinionItems.length > 0;

  return `
    <div class="card stack user-relations-list" data-profile-relations="true">
      ${rows.map((row) => `
        <div class="user-rel-row ${row.text ? '' : 'is-empty'}">
          <span class="user-rel-text">${escapeHtml(row.text)}</span>
          <button class="ghost-btn user-rel-action" type="button" data-relation-action="${row.kind}">${escapeHtml(row.button)}</button>
        </div>
      `).join('')}
      <div class="user-rel-opinions-wrap ${hasOpinion ? '' : 'is-empty'}">
        <div class="user-rel-opinions-list">
          ${opinionItems.map((item) => `
            <div class="user-rel-opinion-item">${escapeHtml(item.text)}</div>
          `).join('')}
        </div>
        <div class="user-rel-opinions-hint">Добавьте одну из этих трёх формулировок.</div>
      </div>
      <div class="user-rel-row">
        <span class="user-rel-text">${hasOpinion ? 'Мнение уже добавлено.' : 'Пока нет дополнительной связи.'}</span>
        <button class="ghost-btn user-rel-action user-rel-opinion-btn" type="button" data-relation-action="opinion-menu">${hasOpinion ? 'Изменить мнение' : 'Добавить мнение'}</button>
      </div>
    </div>
  `;
}

function openOpinionMenuModal({ flags, onApply }) {
  const root = document.getElementById('modal-root');
  if (!root) return;
  const activeKind = resolveActiveOpinionKind(flags);
  const items = [
    { kind: 'known_person', title: 'просто знаю человека' },
    { kind: 'shine_confirmed', title: 'точно уверен, что сияющий' },
    { kind: 'shine_seen', title: 'мало знаком, но видел сияющим' },
  ];
  const rowsHtml = items
    .filter((item) => item.kind !== activeKind)
    .map((item) => `<button class="secondary-btn user-opinion-modal-btn is-add" type="button" data-opinion-kind="${item.kind}" data-opinion-mode="set">Высказать: ${item.title}</button>`)
    .join('');
  const removeHtml = activeKind
    ? `<button class="secondary-btn user-opinion-modal-btn is-remove" type="button" data-opinion-kind="${activeKind}" data-opinion-mode="remove">Убрать мнение</button>`
    : '';

  root.innerHTML = `
    <div class="modal" id="user-opinion-modal">
      <div class="modal-card stack">
        <h3 class="modal-title">${activeKind ? 'Изменить мнение' : 'Добавить мнение'}</h3>
        <div class="stack">${rowsHtml}${removeHtml}</div>
        <button class="secondary-btn" type="button" id="user-opinion-modal-close">Закрыть</button>
      </div>
    </div>
  `;

  const close = () => { root.innerHTML = ''; };
  root.querySelector('#user-opinion-modal-close')?.addEventListener('click', close);
  root.querySelector('#user-opinion-modal')?.addEventListener('click', (event) => {
    if (event.target?.id === 'user-opinion-modal') close();
  });
  root.querySelectorAll('[data-opinion-mode]').forEach((btn) => {
    btn.addEventListener('click', async () => {
      const nextKind = String(btn.getAttribute('data-opinion-kind') || '').trim();
      const mode = String(btn.getAttribute('data-opinion-mode') || '').trim();
      close();
      if (!nextKind) return;
      await onApply({ mode, nextKind, activeKind });
    });
  });
}

function renderReadOnlyParams(card) {
  const rows = [
    { label: 'Имя', value: card.firstName },
    { label: 'Фамилия', value: card.lastName },
    { label: 'Пол', value: genderText(card.gender) },
    { label: 'Адрес', value: card.address },
    { label: 'Web', value: card.web },
    { label: 'Телефон', value: card.phone },
  ];

  return `
    <div class="card stack profile-param-list">
      ${rows.map((row) => `
        <div class="card profile-param-item row">
          <div class="profile-param-value"><b>${row.label}</b>: ${escapeHtml(String(row.value || '').trim() || 'не заполнено')}</div>
        </div>
      `).join('')}
    </div>
  `;
}

export function render({ navigate, route }) {
  const requestedLogin = String(route.params.login || '').trim();
  const sessionLogin = String(state.session.login || '').trim();

  const screen = document.createElement('section');
  screen.className = 'stack';

  const status = document.createElement('div');
  status.className = 'status-line';
  status.textContent = 'Загрузка профиля...';

  const body = document.createElement('div');
  body.className = 'stack';

  screen.append(
    renderHeader({
      title: 'Профиль пользователя',
      leftAction: { label: '←', onClick: () => navigateBack() },
      rightActions: [{ label: 'Показать\nсвязи', onClick: () => navigate(makeProfileLinksRoute(requestedLogin || '')) }],
    }),
    status,
    body,
  );
  const linksHeaderBtn = screen.querySelector('.header-actions .icon-btn');
  linksHeaderBtn?.classList.add('profile-links-header-btn');

  let currentCard = null;
  let currentFlags = null;
  let isBusy = false;

  function syncActionButtons() {
    const followBtn = body.querySelector('[data-relation-action="follow"]');
    const friendBtn = body.querySelector('[data-relation-action="friend"]');
    const contactBtn = body.querySelector('[data-relation-action="contact"]');
    const opinionBtn = body.querySelector('[data-relation-action="opinion-menu"]');
    if (!followBtn || !friendBtn || !contactBtn || !opinionBtn || !currentFlags) return;
    const isSelf = currentCard && currentCard.login.toLowerCase() === sessionLogin.toLowerCase();
    contactBtn.textContent = relationButtonLabel('contact', currentFlags);
    friendBtn.textContent = relationButtonLabel('friend', currentFlags);
    followBtn.textContent = relationButtonLabel('follow', currentFlags);
    contactBtn.disabled = Boolean(isSelf);
    friendBtn.disabled = Boolean(isSelf);
    followBtn.disabled = Boolean(isSelf);
    opinionBtn.textContent = opinionItemsFromFlags(currentFlags).length ? 'Изменить мнение' : 'Добавить мнение';
    opinionBtn.disabled = Boolean(isSelf);
  }

  async function refresh() {
    if (!requestedLogin) {
      status.className = 'status-line is-unavailable';
      status.textContent = 'Не передан login пользователя.';
      return;
    }

    isBusy = true;
    status.className = 'status-line';
    status.textContent = 'Загрузка профиля...';

    try {
      const card = await loadUserProfileCard(requestedLogin);
      const flags = await loadRelationsForPair({
        currentLogin: sessionLogin,
        targetLogin: card.login,
      });

      currentCard = card;
      currentFlags = flags;

      body.innerHTML = `
        ${renderReadOnlyBadges(card)}
        ${renderRelations(flags)}
        ${renderReadOnlyParams(card)}
      `;
      const identityCard = document.createElement('div');
      identityCard.className = 'card stack';
      identityCard.append(renderIdentity(card));
      body.prepend(identityCard);

      syncActionButtons();
      if (String(route?.params?.section || '').toLowerCase() === 'links') {
        const rel = body.querySelector('[data-profile-relations="true"]');
        rel?.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
      status.className = 'status-line is-available';
      status.textContent = 'Профиль обновлён.';
    } catch (error) {
      status.className = 'status-line is-unavailable';
      status.textContent = `Ошибка загрузки профиля: ${error.message || 'unknown'}`;
      window.alert(`Не удалось загрузить профиль: ${error.message || 'unknown'}`);
    } finally {
      isBusy = false;
    }
  }

  async function onRelationAction(kind) {
    if (isBusy || !currentCard || !currentFlags) return;
    if (!sessionLogin) {
      window.alert('Для изменения связей нужен активный вход.');
      return;
    }
    if (!state.session.storagePwdInMemory) {
      window.alert('Нет storagePwd в памяти сессии. Выполните вход заново.');
      return;
    }

    if (kind === 'opinion-menu') {
      openOpinionMenuModal({
        flags: currentFlags,
        onApply: onOpinionApply,
      });
      return;
    }

    const nextEnabled = relationNextState(kind, currentFlags);
    const confirmed = window.confirm(
      `Изменить ${relationConfirmLabel(kind)} с пользователем ${currentCard.login}?\n` +
      'Будет отправлен AddBlock CONNECTION.',
    );
    if (!confirmed) return;

    isBusy = true;
    status.className = 'status-line';
    status.textContent = 'Сохранение отношения в блокчейн...';

    try {
      await authService.setUserRelation({
        login: sessionLogin,
        toLogin: currentCard.login,
        kind,
        enabled: nextEnabled,
        storagePwd: state.session.storagePwdInMemory,
      });
      await refresh();
    } catch (error) {
      status.className = 'status-line is-unavailable';
      status.textContent = `Ошибка изменения связи: ${error.message || 'unknown'}`;
      window.alert(`Не удалось изменить связь: ${error.message || 'unknown'}`);
      isBusy = false;
    }
  }

  async function onOpinionApply({ mode, nextKind, activeKind }) {
    if (isBusy || !currentCard || !currentFlags) return;
    if (!sessionLogin) {
      window.alert('Для изменения связей нужен активный вход.');
      return;
    }
    if (!state.session.storagePwdInMemory) {
      window.alert('Нет storagePwd в памяти сессии. Выполните вход заново.');
      return;
    }

    const confirmed = window.confirm(`Изменить мнение о пользователе ${currentCard.login}?`);
    if (!confirmed) return;

    isBusy = true;
    status.className = 'status-line';
    status.textContent = 'Сохранение отношения в блокчейн...';

    try {
      if (activeKind) {
        await authService.setUserRelation({
          login: sessionLogin,
          toLogin: currentCard.login,
          kind: activeKind,
          enabled: false,
          storagePwd: state.session.storagePwdInMemory,
        });
      }

      if (mode === 'set') {
        await authService.setUserRelation({
          login: sessionLogin,
          toLogin: currentCard.login,
          kind: nextKind,
          enabled: true,
          storagePwd: state.session.storagePwdInMemory,
        });
      }
      await refresh();
      if (mode === 'set') {
        const opinionVisible = Boolean(
          currentFlags?.outKnownPerson
          || currentFlags?.outShineConfirmed
          || currentFlags?.outShineSeen,
        );
        if (!opinionVisible) {
          await new Promise((resolve) => window.setTimeout(resolve, 350));
          await refresh();
        }
      }
    } catch (error) {
      status.className = 'status-line is-unavailable';
      status.textContent = `Ошибка изменения связи: ${error.message || 'unknown'}`;
      window.alert(`Не удалось изменить связь: ${error.message || 'unknown'}`);
      isBusy = false;
    }
  }

  body.addEventListener('click', (event) => {
    const target = event.target;
    if (!(target instanceof HTMLElement)) return;
    const infoBtn = target.closest('[data-profile-info]');
    const infoKind = String(infoBtn?.getAttribute('data-profile-info') || '');
    if (infoKind === 'official') {
      openProfileInfoModal({
        title: 'Официальный канал',
        text: officialInfoText(),
      });
      return;
    }
    if (infoKind === 'shine') {
      openProfileInfoModal({
        title: 'Справка о сияющих',
        text: shineInfoText(),
      });
      return;
    }
    const actionBtn = target.closest('[data-relation-action]');
    const kind = String(actionBtn?.getAttribute('data-relation-action') || '');
    if (!kind) return;
    void onRelationAction(kind);
  });

  refresh();
  return screen;
}
