const { div, h2, p, section, button, form, a, span, textarea, br, input, h1, label } = require("../server/node_modules/hyperaxe");
const { template, i18n, userLink } = require("./main_views");
const { config } = require("../server/SSB_server.js");
const { renderTextWithStyles } = require("../backend/renderTextWithStyles");
const opinionCategories = require("../backend/opinion_categories");
const moment = require("../server/node_modules/moment");
const { sanitizeHtml } = require('../backend/sanitizeHtml');
const { renderUrl } = require("../backend/renderUrl");

const FEED_TEXT_MIN = Number(config?.feed?.minLength ?? 1);
const FEED_TEXT_MAX = Number(config?.feed?.maxLength ?? 280);

const normalizeOptions = (opts) => {
  if (typeof opts === "string") return { filter: String(opts || "ALL").toUpperCase(), q: "", tag: "", msg: "" };
  if (!opts || typeof opts !== "object") return { filter: "ALL", q: "", tag: "", msg: "" };
  return {
    filter: String(opts.filter || "ALL").toUpperCase(),
    q: typeof opts.q === "string" ? opts.q : "",
    tag: typeof opts.tag === "string" ? opts.tag : "",
    msg: typeof opts.msg === "string" ? opts.msg : ""
  };
};

const formatDate = (feed) => {
  const ts = feed?.value?.timestamp || Date.parse(feed?.value?.content?.createdAt || "") || 0;
  return ts ? new Date(ts).toLocaleString() : "";
};

const extractTags = (text) => {
  const list = (String(text || "").match(/#[A-Za-z0-9_]{1,32}/g) || []).map((t) => t.slice(1).toLowerCase());
  return Array.from(new Set(list));
};

const rewriteHashtagLinks = (html) => {
    return String(html || '').replace(
        /href=(["'])\/hashtag\/([^"'?#\s<]+)\1/gi,
        (m, q, rawTag) => {
            let t = String(rawTag || '');
            try { t = decodeURIComponent(t); } catch {}
            t = t.replace(/[^A-Za-z0-9_]/g, '');
            const tag = t.toLowerCase();
            const query = encodeURIComponent(`#${tag}`);
            return `href=${q}/search?query=${query}${q}`;
        }
    );
};

const generateFilterButtons = (filters, currentFilter, action, extra = {}) => {
  const cur = String(currentFilter || "").toUpperCase();
  const hiddenInputs = (obj) =>
    Object.entries(obj)
      .filter(([, v]) => v !== undefined && v !== null && String(v).length > 0)
      .map(([k, v]) => input({ type: "hidden", name: k, value: String(v) }));

  return filters.map((mode) =>
    form(
      { method: "GET", action },
      input({ type: "hidden", name: "filter", value: mode }),
      ...hiddenInputs(extra),
      button({ type: "submit", class: cur === mode ? "filter-btn active" : "filter-btn" }, i18n[mode + "Button"] || mode)
    )
  );
};

const renderVotesSummary = (opinions = {}) => {
  const entries = Object.entries(opinions).filter(([, v]) => Number(v) > 0);
  if (!entries.length) return null;
  entries.sort((a, b) => Number(b[1]) - Number(a[1]) || String(a[0]).localeCompare(String(b[0])));
  return div(
    { class: "votes" },
    entries.map(([category, count]) => span({ class: "vote-category" }, `${category}: ${count}`))
  );
};

const renderCardField = (labelText, value) =>
  div(
    { class: "card-field" },
    span({ class: "card-label" }, labelText),
    span({ class: "card-value" }, value)
  );

const renderFeedCommentsSection = (feedKey, comments = []) => {
  const list = Array.isArray(comments) ? comments : [];
  const commentsCount = list.length;

  return div(
    { class: "vote-comments-section" },
    div(
      { class: "comments-count" },
      span({ class: "card-label" }, i18n.voteCommentsLabel + ": "),
      span({ class: "card-value" }, String(commentsCount))
    ),
    div(
      { class: "comment-form-wrapper" },
      h2({ class: "comment-form-title" }, i18n.voteNewCommentLabel || i18n.feedPostComment || "Post a comment"),
      form(
        { method: "POST", action: `/feed/${encodeURIComponent(feedKey)}/comments`, class: "comment-form", enctype: "multipart/form-data" },
        textarea({
          id: "comment-text",
          name: "text",
          rows: 4,
          class: "comment-textarea",
          placeholder: i18n.voteNewCommentPlaceholder || ""
        }),
        div({ class: "comment-file-upload" }, label(i18n.uploadMedia || "Upload media"), input({ type: "file", name: "blob" })),
        br(),
        button({ type: "submit", class: "comment-submit-btn" }, i18n.voteNewCommentButton || i18n.feedPostComment || "Send")
      )
    ),
    list.length
      ? div(
          { class: "comments-list" },
          list.map((c) => {
            const author = c?.value?.author || "";
            const ts = c?.value?.timestamp || c?.timestamp;
            const absDate = ts ? moment(ts).format("YYYY/MM/DD HH:mm:ss") : "";
            const relDate = ts ? moment(ts).fromNow() : "";
            const userName = author && author.includes("@") ? author.split("@")[1] : author;

            const content = c?.value?.content || {};
            const text = content.text || c?.value?.text || "";
            const threadRoot = content.fork || content.root || null;

            return div(
              { class: "votations-comment-card" },
              span(
                { class: "created-at" },
                span(i18n.createdBy),
                author ? a({ href: `/author/${encodeURIComponent(author)}` }, `@${userName}`) : span("(unknown)"),
                absDate ? span(" | ") : "",
                absDate ? span({ class: "votations-comment-date" }, absDate) : "",
                relDate ? span({ class: "votations-comment-date" }, " | ", i18n.sendTime) : "",
                relDate && threadRoot
                  ? a({ href: `/thread/${encodeURIComponent(threadRoot)}#${encodeURIComponent(c.key)}` }, relDate)
                  : ""
              ),
              p({ class: "votations-comment-text" }, ...renderUrl(text))
            );
          })
        )
      : p({ class: "votations-no-comments" }, i18n.voteNoCommentsYet || i18n.noComments || "")
  );
};

const renderFeedCard = (feed) => {
    const content = feed.value.content || {};
    const rawText = typeof content.text === "string" ? content.text : "";
    const safeText = rawText.trim();
    if (!safeText) return null;

    const voteEntries = Object.entries(content.opinions || {});
    const totalCount = voteEntries.reduce((sum, [, count]) => sum + (Number(count) || 0), 0);
    const createdAt = formatDate(feed);
    const me = config?.keys?.id;

    const alreadyRefeeded = Array.isArray(content.refeeds_inhabitants) && me ? content.refeeds_inhabitants.includes(me) : false;
    const alreadyVoted = Array.isArray(content.opinions_inhabitants) && me ? content.opinions_inhabitants.includes(me) : false;

    const authorId = content.author || feed.value.author || "";
    const refeedsNum = Number(content.refeeds || 0) || 0;
    const commentCount = Number(content.commentCount || 0);
    const styledHtml = rewriteHashtagLinks(renderTextWithStyles(safeText));

    return div(
        { class: "feed-card" },
        div(
            { class: "feed-row" },
            div(
                { class: "refeed-column" },
                h1(String(refeedsNum)),
                form(
                    { method: "POST", action: `/feed/refeed/${encodeURIComponent(feed.key)}` },
                    button({ class: alreadyRefeeded ? "refeed-btn active" : "refeed-btn", type: "submit", ...(alreadyRefeeded ? { disabled: true } : {}) }, i18n.refeedButton)
                ),
                alreadyRefeeded ? p({ class: "muted" }, i18n.alreadyRefeeded) : null
            ),
            div(
                { class: "feed-main" },
                div({ class: "feed-text", innerHTML: sanitizeHtml(styledHtml) }),
                h2(
                    `${i18n.totalOpinions}: ${totalCount}`,
                    ...(() => {
                        const entries = voteEntries.filter(([, v]) => Number(v) > 0);
                        if (!entries.length) return [];
                        const maxVal = Math.max(...entries.map(([, v]) => Number(v)));
                        const dominant = entries.filter(([, v]) => Number(v) === maxVal).map(([k]) => i18n['vote' + k.charAt(0).toUpperCase() + k.slice(1)] || k);
                        return [
                            span({ style: 'margin:0 8px;opacity:0.5;' }, '|'),
                            span({ style: 'font-weight:700;' }, `${i18n.moreVoted || 'More Voted'}: ${dominant.join(' + ')}`)
                        ];
                    })()
                ),
                p(
                    { class: "card-footer" },
                    span({ class: "date-link" }, `${createdAt} ${i18n.performed} `),
                    userLink(authorId),
                    content._textEdited ? span({ class: "edited-badge" }, ` · ${i18n.edited || "edited"}`) : null
                )
            )
        ),
        div(
            { class: "voting-buttons" },
            opinionCategories.map((cat) =>
                form(
                    { method: "POST", action: `/feed/opinions/${encodeURIComponent(feed.key)}/${cat}` },
                    button(
                        { class: alreadyVoted ? "vote-btn disabled" : "vote-btn", type: "submit", ...(alreadyVoted ? { disabled: true } : {}) },
                        `${i18n["vote" + cat.charAt(0).toUpperCase() + cat.slice(1)] || cat} [${content.opinions?.[cat] || 0}]`
                    )
                )
            )
        ),
        div(
            { class: "card-comments-summary" },
            span({ class: "card-label" }, `${i18n.voteCommentsLabel || "Comments"}:`),
            span({ class: "card-value" }, String(commentCount)),
            br(),
            br(),
            form(
                { method: "GET", action: `/feed/${encodeURIComponent(feed.key)}` },
                button({ type: "submit", class: "filter-btn" }, i18n.voteCommentsForumButton || i18n.feedOpenDiscussion || "Open Discussion")
            )
        )
    );
};

exports.feedView = (feeds, opts = "ALL") => {
  const { filter, q, tag, msg } = normalizeOptions(opts);

  const title =
    filter === "MINE"
      ? i18n.MINEButton
      : filter === "TODAY"
        ? i18n.TODAYButton
        : filter === "TOP"
          ? i18n.TOPButton
          : filter === "CREATE"
            ? i18n.createFeedTitle
            : tag
              ? `${i18n.filteredByTag || i18n.filteredByTagTitle || "Filtered by tag"}: #${tag}`
              : q
                ? `${i18n.searchTitle || "Search"}: “${q}”`
                : i18n.feedTitle;

  const header = div({ class: "tags-header" }, h2(title), p(i18n.FeedshareYourOpinions));
  const successBanner = msg === 'feedPublished'
    ? div({ class: 'feed-success-msg' }, p('✓ ' + (i18n.feedPublishedSuccess || 'Feed published successfully!')))
    : null;

  const extra = { q, tag };

  return template(
    title,
    section(
      header,
      successBanner,
      div(
        { class: "mode-buttons-row" },
        ...generateFilterButtons(["ALL", "MINE", "TODAY", "TOP"], filter, "/feed", extra),
        form({ method: "GET", action: "/feed/create" }, button({ type: "submit", class: "create-button filter-btn" }, i18n.createFeedTitle || "Create Feed"))
      ),
      div(
        { class: "feed-tools-row" },
        form(
          { method: "GET", action: "/feed", class: "feed-search-form" },
          input({ type: "hidden", name: "filter", value: filter }),
          tag ? input({ type: "hidden", name: "tag", value: tag }) : null,
          input({ type: "text", name: "q", value: q, placeholder: i18n.searchPlaceholder || "Search", class: "feed-search-input" }),
          button({ type: "submit", class: "filter-btn feed-search-btn" }, i18n.searchButton || "Search")
        )
      ),
      section(
        filter === "CREATE"
          ? form(
              { method: "POST", action: "/feed/create" },
              textarea({
                name: "text",
                placeholder: i18n.feedPlaceholder,
                required: true,
                minlength: String(FEED_TEXT_MIN),
                maxlength: String(FEED_TEXT_MAX),
                rows: 4,
                cols: 50
              }),
              br(),
              button({ type: "submit", class: "create-button" }, i18n.createFeedButton)
            )
          : feeds && feeds.length > 0
            ? div({ class: "feed-container" }, feeds.map((feed) => renderFeedCard(feed)).filter(Boolean))
            : div({ class: "no-results" }, p(i18n.noFeedsFound))
      )
    )
  );
};

exports.feedCreateView = (opts = {}) => {
  const { q, tag } = normalizeOptions(opts);

  return template(
    i18n.createFeedTitle,
    section(
      div({ class: "tags-header" }, h2(i18n.createFeedTitle), p(i18n.FeedshareYourOpinions)),
      div({ class: "mode-buttons-row" }, ...generateFilterButtons(["ALL", "MINE", "TODAY", "TOP"], "CREATE", "/feed", { q, tag })),
      form(
        { method: "POST", action: "/feed/create" },
        textarea({
          name: "text",
          required: true,
          minlength: String(FEED_TEXT_MIN),
          maxlength: String(FEED_TEXT_MAX),
          rows: 5,
          cols: 50,
          placeholder: i18n.feedPlaceholder
        }),
        br(),
        button({ type: "submit", class: "create-button" }, i18n.createFeedButton || "Send Feed!")
      )
    )
  );
};

exports.singleFeedView = (feed, comments = []) => {
  const content = feed.value?.content || {};
  const rawText = typeof content.text === "string" ? content.text : "";
  const safeText = rawText.trim();
  const authorId = content.author || feed.value?.author || "";
  const createdAt = formatDate(feed);
  const styledHtml = rewriteHashtagLinks(renderTextWithStyles(safeText));
  const me = config?.keys?.id;
  const alreadyVoted = Array.isArray(content.opinions_inhabitants) && me ? content.opinions_inhabitants.includes(me) : false;
  const alreadyRefeeded = Array.isArray(content.refeeds_inhabitants) && me ? content.refeeds_inhabitants.includes(me) : false;
  const refeedsNum = Number(content.refeeds || 0) || 0;
  const tags = extractTags(safeText);

  return template(
    i18n.feedDetailTitle || "Feed",
    section(
      div(
        { class: "filters" },
        form(
          { method: "GET", action: "/feed", class: "ui-toolbar ui-toolbar--filters" },
          button({ type: "submit", name: "filter", value: "ALL", class: "filter-btn" }, i18n.ALLButton || "ALL"),
          button({ type: "submit", name: "filter", value: "MINE", class: "filter-btn" }, i18n.MINEButton || "MINE"),
          button({ type: "submit", name: "filter", value: "TODAY", class: "filter-btn" }, i18n.TODAYButton || "TODAY"),
          button({ type: "submit", name: "filter", value: "TOP", class: "filter-btn" }, i18n.TOPButton || "TOP"),
          form({ method: "GET", action: "/feed/create" }, button({ type: "submit", class: "create-button" }, i18n.createFeedTitle || "Create Feed"))
        )
      ),
      div(
        { class: "bookmark-item card feed-detail-card" },
        br,
        div(
          { class: "feed-row" },
          div(
            { class: "refeed-column" },
            h1(String(refeedsNum)),
            form(
              { method: "POST", action: `/feed/refeed/${encodeURIComponent(feed.key)}` },
              button({ class: alreadyRefeeded ? "refeed-btn active" : "refeed-btn", type: "submit", ...(alreadyRefeeded ? { disabled: true } : {}) }, i18n.refeedButton)
            ),
            alreadyRefeeded ? p({ class: "muted" }, i18n.alreadyRefeeded) : null
          ),
          div(
            { class: "feed-main" },
            div({ class: "feed-text", innerHTML: sanitizeHtml(styledHtml) }),
            tags.length
              ? div(
                  { class: "card-tags" },
                  tags.map((tag) => a({ href: `/search?query=%23${encodeURIComponent(tag)}`, class: "tag-link" }, `#${tag}`))
                )
              : null,
            br,
            p(
              { class: "card-footer" },
              span({ class: "date-link" }, `${createdAt} ${i18n.performed} `),
              userLink(authorId),
              content._textEdited ? span({ class: "edited-badge" }, ` · ${i18n.edited || "edited"}`) : null
            )
          )
        ),
        div(
          { class: "voting-buttons" },
          opinionCategories.map((cat) =>
            form(
              { method: "POST", action: `/feed/opinions/${encodeURIComponent(feed.key)}/${cat}` },
              button(
                { class: alreadyVoted ? "vote-btn disabled" : "vote-btn", type: "submit", ...(alreadyVoted ? { disabled: true } : {}) },
                `${i18n["vote" + cat.charAt(0).toUpperCase() + cat.slice(1)] || cat} [${content.opinions?.[cat] || 0}]`
              )
            )
          )
        ),
        alreadyVoted ? p({ class: "muted" }, i18n.alreadyVoted) : null
      ),
      renderFeedCommentsSection(feed.key, comments)
    )
  );
};

