(function () {
  const config = window.WEMOMENTS_CONFIG || {};

  window.wemomentsShell = function () {
    return {
      modals: { login: false, register: false, settings: false, links: false, write: false },
      init() {
        window.WemomentsOpenModal = (name) => {
          if (this.modals[name] !== undefined) this.modals[name] = true;
        };
        window.WemomentsCloseModal = (name) => {
          if (this.modals[name] !== undefined) this.modals[name] = false;
        };
        window.addEventListener('write-modal-open', (event) => {
          this.modals.write = true;
          window.dispatchEvent(new CustomEvent('wemoments:edit-post', { detail: event.detail || {} }));
        });
      }
    };
  };

  function csrfHeaders(extra) {
    return Object.assign({ 'X-CSRF-Token': config.csrfToken || '' }, extra || {});
  }

  function api(method, url, data) {
    return window.axios({
      method,
      url,
      data,
      headers: csrfHeaders({ 'Content-Type': 'application/json' })
    }).then((response) => {
      if (!response.data || !response.data.success) throw new Error(response.data && response.data.message ? response.data.message : '请求失败');
      return response.data.data;
    });
  }

  function escapeHtml(value) {
    return String(value || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
  }

  function notice(message, opts) {
    opts = opts || {};
    const root = document.getElementById('wm-dialog-root');
    if (!root) return Promise.resolve(false);
    return new Promise((resolve) => {
      const dialog = document.createElement('div');
      dialog.className = 'wm-dialog-layer';
      dialog.innerHTML = [
        '<div class="wm-dialog-mask"></div>',
        '<section class="wm-dialog-card" role="dialog" aria-modal="true">',
        '<div class="wm-dialog-icon ' + (opts.danger ? 'danger' : 'info') + '">' + (opts.danger ? '!' : 'i') + '</div>',
        '<div class="wm-dialog-copy"><h3>' + escapeHtml(opts.title || '提示') + '</h3><p>' + escapeHtml(message) + '</p>',
        '<div class="wm-dialog-actions">',
        opts.confirm ? '<button data-dialog-cancel>' + escapeHtml(opts.cancelText || '取消') + '</button>' : '',
        '<button class="primary-button" data-dialog-ok>' + escapeHtml(opts.okText || '确定') + '</button>',
        '</div></div></section>'
      ].join('');
      const close = (value) => {
        dialog.classList.add('leaving');
        window.setTimeout(() => dialog.remove(), 140);
        resolve(value);
      };
      dialog.addEventListener('click', (event) => {
        if (event.target.matches('.wm-dialog-mask,[data-dialog-cancel]')) close(false);
        if (event.target.matches('[data-dialog-ok]')) close(true);
      });
      const onKey = (event) => {
        if (event.key === 'Escape') {
          document.removeEventListener('keydown', onKey);
          close(false);
        }
      };
      document.addEventListener('keydown', onKey);
      root.appendChild(dialog);
      requestAnimationFrame(() => dialog.classList.add('visible'));
    });
  }

  window.WemomentsDialog = {
    notice,
    confirm(message, opts) {
      return notice(message, Object.assign({}, opts, { confirm: true }));
    }
  };

  function openModal(name) {
    if (window.WemomentsOpenModal) window.WemomentsOpenModal(name);
  }

  function closeModal(name) {
    if (window.WemomentsCloseModal) window.WemomentsCloseModal(name);
  }

  function setTheme(dark) {
    document.documentElement.classList.toggle('dark', dark);
    localStorage.setItem('wemoments_theme_mode', dark ? 'dark' : 'light');
    const toggle = document.querySelector('[data-theme-toggle]');
    if (toggle) toggle.checked = dark;
  }

  function collectForm(form) {
    const data = {};
    new FormData(form).forEach((value, key) => {
      data[key] = value;
    });
    return data;
  }

  function setupAuthForms() {
    document.querySelectorAll('[data-auth-form]').forEach((form) => {
      form.addEventListener('submit', async (event) => {
        event.preventDefault();
        const mode = form.getAttribute('data-auth-form');
        const button = form.querySelector('button[type="submit"]');
        const payload = collectForm(form);
        try {
          if (button) button.disabled = true;
          await api('post', mode === 'register' ? '/api/auth/register' : '/api/auth/login', payload);
          const next = new URLSearchParams(location.search).get('next');
          location.href = next || '/';
        } catch (error) {
          window.WemomentsDialog.notice(error.message || '操作失败', { danger: true });
        } finally {
          if (button) button.disabled = false;
        }
      });
    });
  }

  function updateLikeUI(post, liked, count) {
    post.dataset.liked = liked ? '1' : '0';
    const action = post.querySelector('[data-action="like-post"] span');
    if (action) action.textContent = liked ? '已赞' : '赞';
    const container = post.querySelector('[data-comment-container]');
    const line = post.querySelector('.post-like-line');
    const text = post.querySelector('[data-like-text]');
    if (text) text.innerHTML = '共 <b>' + count + '</b> 人赞过';
    if (line) line.hidden = count <= 0;
    if (container && count > 0) container.hidden = false;
  }

  function showCommentForm(post, parentId, authorName) {
    if (config.commentMode === 'closed') {
      window.WemomentsDialog.notice('评论已关闭');
      return;
    }
    if (config.commentMode === 'registered' && !config.currentUser) {
      openModal('login');
      return;
    }
    const form = post.querySelector('[data-comment-form]');
    if (!form) return;
    form.hidden = false;
    form.querySelector('[name="parentId"]').value = parentId || '';
    const textarea = form.querySelector('textarea');
    if (textarea) {
      textarea.placeholder = authorName ? '回复 ' + authorName + '...' : '写评论...';
      textarea.focus();
    }
    const cachedName = localStorage.getItem('wemoments_comment_author');
    const guest = form.querySelector('[name="guestName"]');
    if (guest && cachedName) guest.value = cachedName;
  }

  function renderPost(post) {
    const avatar = post.author.avatarUrl || config.defaultAvatar;
    const images = (post.images || []).slice(0, 9);
    const gridClass = images.length === 1 ? 'single' : images.length === 4 ? 'four' : 'grid';
    return [
      '<article class="post-item" id="post-' + post.id + '" data-post-id="' + post.id + '" data-liked="' + (post.viewerLiked ? '1' : '0') + '">',
      '<a class="post-avatar" href="/u/' + escapeHtml(post.author.username) + '"><img src="' + escapeHtml(avatar) + '" alt="" loading="lazy"></a>',
      '<div class="post-body"><div class="post-head"><a class="post-author" href="/u/' + escapeHtml(post.author.username) + '">' + escapeHtml(post.author.displayName) + '</a></div>',
      post.contentHtml ? '<div class="post-content">' + post.contentHtml + '</div>' : '',
      images.length ? '<div class="post-images ' + gridClass + '">' + images.map((image) => '<a class="post-image" href="' + escapeHtml(image.url) + '" data-fancybox="gallery-' + post.id + '"><img src="' + escapeHtml(image.url) + '" alt="" loading="lazy"></a>').join('') + '</div>' : '',
      post.videoUrl ? '<video class="post-video" src="' + escapeHtml(post.videoUrl) + '" controls preload="metadata" playsinline></video>' : '',
      post.position ? '<div class="post-location"><span>' + escapeHtml(post.position) + '</span></div>' : '',
      '<div class="post-meta"><a class="post-time" href="/p/' + post.id + '">刚刚</a><button class="post-more-button" type="button" data-action="toggle-actions" aria-label="展开操作">...</button><div class="post-time-comment-modal" hidden><button type="button" data-action="like-post"><span>' + (post.viewerLiked ? '已赞' : '赞') + '</span></button><button type="button" data-action="comment-post"><span>评论</span></button></div></div>',
      '<div class="post-comment-container" data-comment-container ' + (post.likeCount ? '' : 'hidden') + '><div class="post-like-line" ' + (post.likeCount ? '' : 'hidden') + '><span data-like-text>共 <b>' + post.likeCount + '</b> 人赞过</span></div><div class="post-comment-list"></div></div>',
      '<form class="inline-comment-form" data-comment-form hidden><input type="hidden" name="postId" value="' + post.id + '"><input type="hidden" name="parentId" value=""><input class="guest-field" name="guestName" placeholder="昵称" ' + (config.currentUser ? 'hidden' : '') + '><textarea name="content" rows="2" maxlength="1000" placeholder="写评论..." required></textarea><div class="inline-comment-actions"><button type="button" data-action="cancel-comment">取消</button><button type="submit">发送</button></div></form>',
      '</div></article>'
    ].join('');
  }

  function setupFeed() {
    document.addEventListener('click', async (event) => {
      const openButton = event.target.closest('[data-open-modal]');
      if (openButton) openModal(openButton.getAttribute('data-open-modal'));
      const closeButton = event.target.closest('[data-close-modal]');
      if (closeButton) closeModal(closeButton.getAttribute('data-close-modal'));
      const switchButton = event.target.closest('[data-switch-modal]');
      if (switchButton) {
        closeModal(switchButton.getAttribute('data-switch-modal') === 'login' ? 'register' : 'login');
        openModal(switchButton.getAttribute('data-switch-modal'));
      }
      const actionButton = event.target.closest('[data-action]');
      if (!actionButton) return;
      const post = actionButton.closest('.post-item');
      const action = actionButton.getAttribute('data-action');
      if (action === 'toggle-actions' && post) {
        const modal = post.querySelector('.post-time-comment-modal');
        if (modal) modal.hidden = !modal.hidden;
      }
      if (action === 'like-post' && post) {
        if (!config.currentUser) return openModal('login');
        const liked = post.dataset.liked === '1';
        const oldCount = Number(post.querySelector('[data-like-text] b')?.textContent || '0');
        updateLikeUI(post, !liked, Math.max(0, oldCount + (liked ? -1 : 1)));
        try {
          const data = await api(liked ? 'delete' : 'post', '/api/posts/' + post.dataset.postId + '/like');
          updateLikeUI(post, !liked, data.likeCount);
        } catch (error) {
          updateLikeUI(post, liked, oldCount);
          window.WemomentsDialog.notice(error.message || '点赞失败', { danger: true });
        }
      }
      if (action === 'comment-post' && post) showCommentForm(post);
      if (action === 'reply-comment' && post) showCommentForm(post, actionButton.dataset.commentId, actionButton.dataset.author);
      if (action === 'cancel-comment' && post) {
        const form = post.querySelector('[data-comment-form]');
        if (form) form.hidden = true;
      }
      if (action === 'delete-comment') {
        const id = actionButton.dataset.commentId;
        if (id && await window.WemomentsDialog.confirm('确定删除这条评论吗？', { danger: true })) {
          await api('delete', '/api/comments/' + id);
          location.reload();
        }
      }
    });

    document.addEventListener('submit', async (event) => {
      const form = event.target.closest('[data-comment-form]');
      if (!form) return;
      event.preventDefault();
      const payload = collectForm(form);
      const guest = payload.guestName;
      if (guest) localStorage.setItem('wemoments_comment_author', guest);
      try {
        await api('post', '/api/comments', payload);
        location.reload();
      } catch (error) {
        window.WemomentsDialog.notice(error.message || '评论失败', { danger: true });
      }
    });
  }

  function setupWriteModal() {
    const form = document.querySelector('[data-write-form]');
    if (!form) return;
    const state = { images: [], videoKey: null, previews: [] };
    const picker = form.querySelector('[data-media-picker]');
    const imageInput = form.querySelector('[data-image-input]');
    const videoInput = form.querySelector('[data-video-input]');
    const textarea = form.querySelector('textarea[name="content"]');
    const count = form.querySelector('[data-write-count]');

    function renderMedia() {
      picker.querySelectorAll('.media-preview').forEach((node) => node.remove());
      state.previews.forEach((preview, index) => {
        const item = document.createElement('div');
        item.className = 'media-preview';
        item.innerHTML = preview.type === 'video'
          ? '<video src="' + preview.url + '" muted playsinline></video><button type="button" aria-label="删除">×</button>'
          : '<img src="' + preview.url + '" alt=""><button type="button" aria-label="删除">×</button>';
        item.querySelector('button').addEventListener('click', () => {
          if (preview.type === 'video') state.videoKey = null;
          else state.images.splice(index, 1);
          state.previews.splice(index, 1);
          renderMedia();
        });
        picker.insertBefore(item, picker.firstChild);
      });
    }

    async function upload(file, kind) {
      const signed = await api('post', '/api/uploads/sign', { kind, filename: file.name, size: file.size, mime: file.type });
      await window.axios.put(signed.putUrl, file, {
        headers: csrfHeaders(Object.assign({}, signed.headers, { 'X-CSRF-Token': config.csrfToken || '' }))
      });
      await api('post', '/api/uploads/confirm', { key: signed.key });
      return signed.key;
    }

    form.addEventListener('input', () => {
      if (count && textarea) count.textContent = String(textarea.value.length);
    });
    form.querySelector('[data-action="pick-image"]').addEventListener('click', () => imageInput.click());
    form.querySelector('[data-action="pick-video"]').addEventListener('click', () => videoInput.click());
    imageInput.addEventListener('change', async () => {
      const files = Array.from(imageInput.files || []).slice(0, 9 - state.images.length);
      if (state.videoKey) return window.WemomentsDialog.notice('图片和视频不能同时发布');
      for (const file of files) {
        try {
          const key = await upload(file, 'image');
          state.images.push(key);
          state.previews.push({ type: 'image', url: URL.createObjectURL(file) });
          renderMedia();
        } catch (error) {
          window.WemomentsDialog.notice(error.message || '上传失败', { danger: true });
        }
      }
      imageInput.value = '';
    });
    videoInput.addEventListener('change', async () => {
      const file = videoInput.files && videoInput.files[0];
      if (!file) return;
      if (state.images.length) return window.WemomentsDialog.notice('图片和视频不能同时发布');
      try {
        const key = await upload(file, 'video');
        state.videoKey = key;
        state.previews = [{ type: 'video', url: URL.createObjectURL(file) }];
        renderMedia();
      } catch (error) {
        window.WemomentsDialog.notice(error.message || '上传失败', { danger: true });
      }
      videoInput.value = '';
    });
    form.querySelector('[data-action="use-location"]').addEventListener('click', () => {
      if (!navigator.geolocation) return window.WemomentsDialog.notice('当前浏览器不支持定位');
      navigator.geolocation.getCurrentPosition(async (pos) => {
        form.querySelector('[name="positionLat"]').value = pos.coords.latitude;
        form.querySelector('[name="positionLng"]').value = pos.coords.longitude;
        try {
          const res = await window.axios.get('/api/geo/lookup?lat=' + pos.coords.latitude + '&lng=' + pos.coords.longitude);
          const position = res.data.data.position || '当前位置';
          form.querySelector('[name="position"]').value = position;
          form.querySelector('[data-location-label]').textContent = position;
        } catch {
          form.querySelector('[name="position"]').value = '当前位置';
        }
      });
    });
    form.addEventListener('submit', async (event) => {
      event.preventDefault();
      const payload = collectForm(form);
      payload.isTop = Boolean(payload.isTop);
      payload.isAd = Boolean(payload.isAd);
      payload.images = state.images;
      payload.videoKey = state.videoKey;
      payload.positionLat = payload.positionLat ? Number(payload.positionLat) : null;
      payload.positionLng = payload.positionLng ? Number(payload.positionLng) : null;
      try {
        await api('post', '/api/posts', payload);
        location.href = '/';
      } catch (error) {
        window.WemomentsDialog.notice(error.message || '发布失败', { danger: true });
      }
    });
  }

  function setupInfiniteScroll() {
    const list = document.querySelector('[data-feed-list]');
    const loading = document.querySelector('[data-feed-loading]');
    if (!list || !list.dataset.nextCursor) return;
    let busy = false;
    async function loadMore() {
      if (busy || !list.dataset.nextCursor) return;
      if (window.innerHeight + window.scrollY < document.documentElement.scrollHeight - 420) return;
      busy = true;
      if (loading) loading.hidden = false;
      try {
        const response = await window.axios.get('/api/posts?cursor=' + encodeURIComponent(list.dataset.nextCursor));
        const data = response.data.data;
        list.insertAdjacentHTML('beforeend', data.posts.map(renderPost).join(''));
        list.dataset.nextCursor = data.nextCursor || '';
        if (window.Fancybox) window.Fancybox.bind('[data-fancybox]');
      } finally {
        busy = false;
        if (loading) loading.hidden = true;
      }
    }
    window.addEventListener('scroll', loadMore, { passive: true });
  }

  document.addEventListener('DOMContentLoaded', () => {
    const nav = document.querySelector('[data-top-nav]');
    const onScroll = () => nav && nav.classList.toggle('scrolled', window.scrollY > 24);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    document.querySelectorAll('[data-theme-toggle]').forEach((toggle) => {
      toggle.checked = document.documentElement.classList.contains('dark');
      toggle.addEventListener('change', () => setTheme(toggle.checked));
    });
    setupAuthForms();
    setupFeed();
    setupWriteModal();
    setupInfiniteScroll();
    if (window.Fancybox) window.Fancybox.bind('[data-fancybox]');
  });
})();
