const { div, h2, p, section, button, form, a, img, video: videoHyperaxe, audio: audioHyperaxe, input, table, tr, th, td, br, span, details, summary } = require("../server/node_modules/hyperaxe");
const { template, i18n, userLink, renderSpreadButton, renderContentActions } = require('./main_views');
const { config } = require('../server/SSB_server.js');
const { renderTextWithStyles } = require('../backend/renderTextWithStyles');
const { renderUrl } = require('../backend/renderUrl');
const opinionCategories = require('../backend/opinion_categories');
const { sanitizeHtml } = require('../backend/sanitizeHtml');

const seenDocumentTitles = new Set();

const detailHref = (type, key) => {
  switch (type) {
    case 'bookmark': return `/bookmarks/${encodeURIComponent(key)}`;
    case 'image': return `/images/${encodeURIComponent(key)}`;
    case 'video': return `/videos/${encodeURIComponent(key)}`;
    case 'audio': return `/audios/${encodeURIComponent(key)}`;
    case 'torrent': return `/torrents/${encodeURIComponent(key)}`;
    case 'document': return `/documents/${encodeURIComponent(key)}`;
    case 'feed': return `/feed/${encodeURIComponent(key)}`;
    case 'votes': return `/votes/${encodeURIComponent(key)}`;
    case 'transfer': return `/transfers/${encodeURIComponent(key)}`;
    case 'industry': return `/industry/${encodeURIComponent(key)}`;
    case 'project': return `/projects/${encodeURIComponent(key)}`;
    case 'report': return `/reports/${encodeURIComponent(key)}`;
    case 'task': return `/tasks/${encodeURIComponent(key)}`;
    case 'event': return `/events/${encodeURIComponent(key)}`;
    case 'shopProduct': return `/shops/product/${encodeURIComponent(key)}`;
    case 'housing': return `/housing/${encodeURIComponent(key)}`;
    case 'market': return `/market/${encodeURIComponent(key)}`;
    default: return null;
  }
};

const renderContentHtml = (content, key) => {
  switch (content.type) {
    case 'industry':
      return div({ class: 'opinion-industry' },
        div({ class: 'card-section industry' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industryName + ':'),
            span({ class: 'card-value' }, content.name || '')
          ),
          content.sector ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industrySector + ':'),
            span({ class: 'card-value' }, String(content.sector).toUpperCase())
          ) : "",
          content.membershipPolicy ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industryMembershipPolicy + ':'),
            span({ class: 'card-value' }, String(i18n['industryPolicy_' + content.membershipPolicy] || content.membershipPolicy).toUpperCase())
          ) : "",
          content.description ? p(...renderUrl(content.description)) : null,
          Array.isArray(content.tags) && content.tags.length
            ? div({ class: 'card-tags' }, content.tags.map(tag =>
                a({ href: `/search?query=%23${encodeURIComponent(tag)}`, class: 'tag-link' }, `#${tag}`)))
            : null
        )
      );
    case 'industryBlueprint':
      return div({ class: 'opinion-industry' },
        div({ class: 'card-section industry' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industryBlueprint + ':'),
            span({ class: 'card-value' }, content.name || '')
          ),
          content.outKind ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industryOutputKind + ':'),
            span({ class: 'card-value' }, String(i18n['industryKind_' + content.outKind] || content.outKind).toUpperCase())
          ) : "",
          content.laborHours ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.industryLaborHours + ':'),
            span({ class: 'card-value' }, String(content.laborHours))
          ) : "",
          content.description ? p(...renderUrl(content.description)) : null
        )
      );
    case 'housing': {
      const free = String(content.housing_type || '').toLowerCase() === 'couchsurfing';
      return div({ class: 'opinion-housing' },
        div({ class: 'card-section housing' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.title + ':'),
            span({ class: 'card-value' }, content.title || '')
          ),
          content.housing_type ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingType + ':'),
            span({ class: 'card-value' }, String(i18n['housingType' + String(content.housing_type).toUpperCase()] || content.housing_type).toUpperCase())
          ) : null,
          content.property_type ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingProperty + ':'),
            span({ class: 'card-value' }, String(i18n['housingProperty' + String(content.property_type).toUpperCase()] || content.property_type).toUpperCase())
          ) : null,
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingPrice + ':'),
            span({ class: 'card-value' }, free ? (i18n.housingFree || 'FREE') : `${Number(content.price || 0).toFixed(2)} ECO`)
          ),
          content.place ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingPlace + ':'),
            span({ class: 'card-value' }, content.place)
          ) : null,
          Number(content.rooms) > 0 ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingRooms + ':'),
            span({ class: 'card-value' }, String(content.rooms))
          ) : null,
          Number(content.size) > 0 ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingSize + ':'),
            span({ class: 'card-value' }, `${content.size} m²`)
          ) : null,
          Number(content.capacity) > 0 ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.housingCapacity + ':'),
            span({ class: 'card-value' }, String(content.capacity))
          ) : null,
          content.description ? p(...renderUrl(content.description)) : null,
          Array.isArray(content.tags) && content.tags.length
            ? div({ class: 'card-tags' }, content.tags.map(tag =>
                a({ href: `/search?query=%23${encodeURIComponent(tag)}`, class: 'tag-link' }, `#${tag}`)))
            : null
        )
      );
    }
    case 'market':
      return div({ class: 'opinion-market' },
        div({ class: 'card-section market' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.title + ':'),
            span({ class: 'card-value' }, content.title || '')
          ),
          content.item_type ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.marketItemType + ':'),
            span({ class: 'card-value' }, String(content.item_type).toUpperCase())
          ) : null,
          content.item_status ? div({ class: 'card-field' },
            span({ class: 'card-label' }, (i18n.marketItemCondition || i18n.status) + ':'),
            span({ class: 'card-value' }, String(content.item_status).toUpperCase())
          ) : null,
          div({ class: 'card-field' },
            span({ class: 'card-label' }, (i18n.marketItemPrice || i18n.price) + ':'),
            span({ class: 'card-value' }, `${content.price} ECO`)
          ),
          content.description ? p(...renderUrl(content.description)) : null,
          Array.isArray(content.tags) && content.tags.length
            ? div({ class: 'card-tags' }, content.tags.map(tag =>
                a({ href: `/search?query=%23${encodeURIComponent(tag)}`, class: 'tag-link' }, `#${tag}`)))
            : null
        )
      );
    case 'bookmark':
      return div({ class: 'opinion-bookmark' },
        div({ class: 'card-section bookmark' },
          h2(content.url ? div({ class: 'card-field' },
            span({ class: 'card-label' }, p(a({ href: content.url, target: '_blank', class: "bookmark-url" }, content.url)))
          ) : ""),
          content.lastVisit ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.bookmarkLastVisitLabel + ':'),
            span({ class: 'card-value' }, new Date(content.lastVisit).toLocaleString())
          ) : "",
          content.description
            ? [
                span({ class: 'card-label' }, i18n.bookmarkDescriptionLabel + ":"),
                p(...renderUrl(content.description))
              ]
            : null
        )
      );
    case 'image':
      return div({ class: 'opinion-image' },
        div({ class: 'card-section image' },
          content.title ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.imageTitleLabel + ':'),
            span({ class: 'card-value' }, content.title)
          ) : "",
          content.description
            ? [
                span({ class: 'card-label' }, i18n.imageDescriptionLabel + ":"),
                p(...renderUrl(content.description))
              ]
            : null,
          br(),
          div({ class: 'card-field' },
            img({ src: `/blob/${encodeURIComponent(content.url)}`, class: 'feed-image' })
          )
        )
      );
    case 'video':
      return div({ class: 'opinion-video' },
        div({ class: 'card-section video' },
          content.title ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.videoTitleLabel + ':'),
            span({ class: 'card-value' }, content.title)
          ) : "",
          content.description
            ? [
                span({ class: 'card-label' }, i18n.videoDescriptionLabel + ":"),
                p(...renderUrl(content.description))
              ]
            : null,
          div({ class: 'card-field' },
            videoHyperaxe({
              controls: true,
              src: `/blob/${encodeURIComponent(content.url)}`,
              type: content.mimeType || 'video/mp4',
              width: '640',
              height: '360'
            })
          )
        )
      );
    case 'audio':
      return div({ class: 'opinion-audio' },
        div({ class: 'card-section audio' },
          content.title ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.audioTitleLabel + ':'),
            span({ class: 'card-value' }, content.title)
          ) : "",
          content.description
            ? [
                span({ class: 'card-label' }, i18n.audioDescriptionLabel + ":"),
                p(...renderUrl(content.description))
              ]
            : null,
          div({ class: 'card-field' },
            audioHyperaxe({
              controls: true,
              src: `/blob/${encodeURIComponent(content.url)}`,
              type: content.mimeType,
              preload: 'metadata'
            })
          )
        )
      );
    case 'torrent':
      return div({ class: 'opinion-torrent' },
        div({ class: 'card-section' },
          content.title ? div({ class: 'card-field' }, span({ class: 'card-label' }, (i18n.torrentTitleLabel || 'Title') + ':'), span({ class: 'card-value' }, content.title)) : ""
        )
      );
    case 'document': {
      const t = content.title?.trim();
      if (t && seenDocumentTitles.has(t)) return null;
      if (t) seenDocumentTitles.add(t);
      return div({ class: 'opinion-document' },
        div({ class: 'card-section document' },
          t ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.documentTitleLabel + ':'),
            span({ class: 'card-value' }, t)
          ) : "",
          content.description
            ? [
                span({ class: 'card-label' }, i18n.documentDescriptionLabel + ":"),
                p(...renderUrl(content.description))
              ]
            : null,
          div({ class: 'card-field' },
            div({ class: 'pdf-viewer-container', 'data-pdf-url': `/blob/${encodeURIComponent(content.url)}` })
          )
        )
      );
    }
    case 'feed':
      return div({ class: 'opinion-feed' },
        div({ class: 'card-section feed' },
          div({ class: 'feed-text', innerHTML: sanitizeHtml(renderTextWithStyles(content.text)) }),
          content.refeeds
            ? h2({ class: 'card-field' }, span({ class: 'card-label' }, `${i18n.tribeFeedRefeeds}: `), span({ class: 'card-value' }, content.refeeds))
            : ""
        )
      );
    case 'votes': {
      const votesList = content.votes && typeof content.votes === 'object'
        ? Object.entries(content.votes).map(([option, count]) => ({ option, count }))
        : [];
      return div({ class: 'opinion-votes' },
        div({ class: 'card-section votes' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.voteQuestionLabel + ':'),
            span({ class: 'card-value' }, content.question)
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.voteDeadline + ':'),
            span({ class: 'card-value' }, content.deadline ? new Date(content.deadline).toLocaleString() : '')
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.voteTotalVotes + ':'),
            span({ class: 'card-value' }, content.totalVotes)
          ),
          table(
            tr(...votesList.map(({ option }) => th(i18n[option] || option))),
            tr(...votesList.map(({ count }) => td(count)))
          )
        )
      );
    }
    case 'transfer':
      return div({ class: 'opinion-transfer' },
        div({ class: 'card-section transfer' },
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.concept + ':'),
            span({ class: 'card-value' }, content.concept)
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.deadline + ':'),
            span({ class: 'card-value' }, content.deadline ? new Date(content.deadline).toLocaleString() : '')
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.status + ':'),
            span({ class: 'card-value' }, content.status)
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.amount + ':'),
            span({ class: 'card-value' }, content.amount)
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.from + ':'),
            span({ class: 'card-value' }, userLink(content.from))
          ),
          div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.to + ':'),
            span({ class: 'card-value' }, userLink(content.to))
          ),
          h2({ class: 'card-field' },
            span({ class: 'card-label' }, `${i18n.transfersConfirmations}: `),
            span({ class: 'card-value' }, `${content.confirmedBy.length}/2`)
          )
        )
      );
    default:
      return div({ class: 'styled-text' },
        div({ class: 'card-section styled-text-content' },
          div({ class: 'card-field' },
            span({ class: 'card-value', innerHTML: sanitizeHtml(content.title || content.name || content.text || content.description || '[no content]') })
          )
        )
      );
  }
};

exports.opinionsView = (items, filter, spreadMap = new Map(), q = '') => {
  seenDocumentTitles.clear();
  items = items
    .filter(item => {
      const c = item.value?.content || item.content;
      return c && typeof c === 'object' && c.type !== 'tombstone';
    })
    .sort((a, b) => {
      if (filter === 'TOP') {
        const aVotes = (a.value.content.opinions_inhabitants || []).length;
        const bVotes = (b.value.content.opinions_inhabitants || []).length;
        return bVotes !== aVotes ? bVotes - aVotes : b.value.timestamp - a.value.timestamp;
      }
      return b.value.timestamp - a.value.timestamp;
    });

  const title = i18n.opinionsTitle;
  const baseFilters = ['ALL', 'MINE', 'RECENT', 'TOP'];

  const cards = items
    .map(item => {
      const c = item.value.content;
      const key = item.key;
      const contentHtml = renderContentHtml(c, key);
      if (!contentHtml) return null;
      const voteEntries = Object.entries(c.opinions || {});
      const total = voteEntries.reduce((sum, [, v]) => sum + v, 0);
      const voted = c.opinions_inhabitants?.includes(config.keys.id);
      const created = new Date(item.value.timestamp).toLocaleString();
      const allCats = opinionCategories;

      const isOwn = item.value.author && String(item.value.author) === String(config.keys.id);
      return div(
        { class: 'trending-card opinions-card' + (isOwn ? ' own-content' : '') },
        div({ class: 'card-header activity-card-header' },
          span({ class: 'pm-exposition-chip pm-exposition-whole' },
            span({ class: 'pm-exposition-text' }, String(c.type || '').toUpperCase())
          ),
          renderContentActions(key, detailHref(c.type, key), { spread: spreadMap.get(key) || null })
        ),
        div(
          { class: 'card-section opinions-card-body' },
          contentHtml,
          p({ class: 'card-footer' },
            span({ class: 'date-link' }, `${created} ${i18n.performed} `),
            userLink(item.value.author)
          ),
          (() => {
            const entries = voteEntries.filter(([, v]) => v > 0);
            const dominantPart = (() => {
              if (!entries.length) return null;
              const maxVal = Math.max(...entries.map(([, v]) => v));
              const dominant = entries.filter(([, v]) => v === maxVal).map(([k]) => i18n['vote' + k.charAt(0).toUpperCase() + k.slice(1)] || k);
              return [
                span({ class: 'trending-dominant-sep' }, '|'),
                span({ class: 'trending-dominant-text' }, `${i18n.moreVoted || 'More Voted'}: ${dominant.join(' + ')}`)
              ];
            })();
            return h2(
              `${i18n.totalOpinions || i18n.opinionsTotalCount}: `,
              span({ class: 'trending-total-count' }, String(total)),
              ...(dominantPart || [])
            );
          })(),
          details({ class: 'opinions-voting-collapse' },
            summary({ class: 'opinions-summary' },
            span({ class: 'opinions-summary-icon' }, 'ꔍ'),
            span({ class: 'opinions-summary-count' }, `(${Object.values(c.opinions || {}).reduce((s, n) => s + (Number(n) || 0), 0)})`)),
            div({ class: 'voting-buttons' },
              allCats.map(cat => {
                const label = `${String(i18n['vote' + cat.charAt(0).toUpperCase() + cat.slice(1)] || cat).toUpperCase()} [${c.opinions?.[cat] || 0}]`;
                if (voted) {
                  return button({ class: 'vote-btn', type: 'button' }, label);
                }
                return form({ method: 'POST', action: `/opinions/${encodeURIComponent(key)}/${cat}` },
                  button({ class: 'vote-btn' }, label)
                );
              })
            )
          )
        )
      );
    })
    .filter(Boolean);

  const hasDocuments = items.some(item => item.value.content?.type === 'document');
  const header = div({ class: 'tags-header' },
    h2(title),
    p(i18n.shareYourOpinions)
  );

  const html = template(
    title,
    section(
      header,
      div({ class: 'mode-buttons' },
        div({ class: 'column' },
          baseFilters.map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.positive.slice(0, 5).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.positive.slice(5, 10).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.positive.slice(10, 15).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        )
      ),
      div({ class: 'mode-buttons' },
        div({ class: 'column' },
          opinionCategories.constructive.slice(0, 5).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.constructive.slice(5, 11).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.moderation.slice(0, 5).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        ),
        div({ class: 'column' },
          opinionCategories.moderation.slice(5, 10).map(mode =>
            form({ method: 'GET', action: '/opinions' },
              input({ type: 'hidden', name: 'filter', value: mode }),
              button({ type: 'submit', class: filter === mode ? 'filter-btn active' : 'filter-btn' }, String(i18n[mode + 'Button'] || mode).toUpperCase())
            )
          )
        )
      ),
      div({ class: 'filters' },
        form({ method: 'GET', action: '/opinions', class: 'filter-box' },
          input({ type: 'hidden', name: 'filter', value: filter }),
          input({ type: 'text', name: 'q', value: q, placeholder: i18n.opinionsSearchPlaceholder, class: 'filter-box__input' }),
          div({ class: 'filter-box__controls' },
            button({ type: 'submit', class: 'filter-box__button' }, i18n.searchButton)
          )
        )
      ),
      section(
        cards.length
          ? div({ class: 'opinions-container' }, ...cards)
          : div({ class: 'no-results' }, p(i18n.noOpinionsFound))
      )
    )
  );

  return `${html}${hasDocuments
    ? `<script type="module" src="/js/pdf.min.mjs"></script>
       <script src="/js/pdf-viewer.js"></script>`
    : ''}`;
};

