const { form, button, div, h2, p, section, input, label, br, a, span, table, thead, tbody, tr, th, td, textarea, select, option, ul, li, img } = require('../server/node_modules/hyperaxe');
const moment = require("../server/node_modules/moment");
const { template, i18n, userLink} = require('./main_views');

const TERM_DAYS = 60;

const fmt = (d) => d ? moment(d).format('YYYY-MM-DD HH:mm:ss') : '—';
const timeLeft = (end) => {
  if (!end) return '—';
  const diff = moment(end).diff(moment());
  if (diff <= 0) return '0d 00:00:00';
  const dur = moment.duration(diff);
  const d = Math.floor(dur.asDays());
  const h = String(dur.hours()).padStart(2,'0');
  const m = String(dur.minutes()).padStart(2,'0');
  const s = String(dur.seconds()).padStart(2,'0');
  return `${d}d ${h}:${m}:${s}`;
};
const reqVotes = (method, total) => {
  const m = String(method || '').toUpperCase();
  if (m === 'DEMOCRACY' || m === 'ANARCHY') return Math.floor(Number(total || 0) / 2) + 1;
  if (m === 'MAJORITY') return Math.ceil(Number(total || 0) * 0.8);
  if (m === 'MINORITY') return Math.ceil(Number(total || 0) * 0.2);
  return 0;
};
const showVoteMetrics = (method) => {
  const m = String(method || '').toUpperCase();
  return !(m === 'DICTATORSHIP' || m === 'KARMATOCRACY');
};
const applyEl = (fn, attrs, kids) => fn.apply(null, [attrs || {}].concat(kids || []));
const methodImageSrc = (method) => `assets/images/${String(method || '').toUpperCase().toLowerCase()}.png`;
const MethodBadge = (method) => {
  const m = String(method || '').toUpperCase();
  const labelTxt = String(i18n[`parliamentMethod${m}`] || m).toUpperCase();
  return span(
    { class: 'method-badge' },
    labelTxt,
    br(),br(),
    img({ src: methodImageSrc(m), alt: labelTxt, class: 'method-badge__icon' })
  );
};
const MethodHero = (method) => {
  const m = String(method || '').toUpperCase();
  const labelTxt = String(i18n[`parliamentMethod${m}`] || m).toUpperCase();
  return span(
    { class: 'method-hero' },
    labelTxt,
    br(),br(),
    img({ src: methodImageSrc(m), alt: labelTxt, class: 'method-hero__icon' })
  );
};
const KPI = (labelTxt, value) =>
  div({ class: 'kpi' },
    span({ class: 'kpi__label' }, labelTxt),
    span({ class: 'kpi__value' }, value)
  );
const CycleInfo = (start, end, labels = {
  since: i18n.parliamentLegSince,
  end: i18n.parliamentLegEnd,
  remaining: i18n.parliamentTimeRemaining
}) =>
  div({ class: 'cycle-info' },
    KPI((labels.since + ': ').toUpperCase(), fmt(start)),
    KPI((labels.end + ': ').toUpperCase(), fmt(end)),
    KPI((labels.remaining + ': ').toUpperCase(), timeLeft(end))
  );
const Tabs = (active) =>
  div(
    { class: 'filters' },
    form(
      { method: 'GET', action: '/parliament' },
      ['government', 'candidatures', 'proposals', 'laws', 'revocations', 'historical', 'leaders', 'rules'].map(f =>
        button({ type: 'submit', name: 'filter', value: f, class: active === f ? 'filter-btn active' : 'filter-btn' }, i18n[`parliamentFilter${f.charAt(0).toUpperCase()+f.slice(1)}`])
      )
    )
  );

const GovHeader = (g) => {
  const termStart = g && g.since ? g.since : null;
  const termEnd = g && g.end ? g.end : null;
  const methodKeyRaw = g && g.method ? String(g.method) : 'ANARCHY';
  const methodKey = methodKeyRaw.toUpperCase();
  const i18nMeth = i18n[`parliamentMethod${methodKey}`];
  const methodLabel = (i18nMeth && String(i18nMeth).trim() ? String(i18nMeth) : methodKey).toUpperCase();
  const isAnarchy = methodKey === 'ANARCHY';
  const population = String(Number(g.inhabitantsTotal || 0));
  const votesReceivedNum = Number.isFinite(Number(g.votesReceived)) ? Number(g.votesReceived) : 0;
  const totalVotesNum = Number.isFinite(Number(g.totalVotes)) ? Number(g.totalVotes) : 0;
  const votesDisplay = `${votesReceivedNum} (${totalVotesNum})`;
  return div(
    { class: 'cycle-info' },
    div({ class: 'kpi' },
      span({ class: 'kpi__label' }, (i18n.parliamentLegSince + ': ').toUpperCase()),
      span({ class: 'kpi__value' }, fmt(termStart))
    ),
    div({ class: 'kpi' },
      span({ class: 'kpi__label' }, (i18n.parliamentLegEnd + ': ').toUpperCase()),
      span({ class: 'kpi__value' }, fmt(termEnd))
    ),
    div({ class: 'kpi' },
      span({ class: 'kpi__label' }, (i18n.parliamentTimeRemaining + ': ').toUpperCase()),
      span({ class: 'kpi__value' }, timeLeft(termEnd))
    ),
    div({ class: 'kpi' },
      span({ class: 'kpi__label' }, (i18n.parliamentPopulation + ': ').toUpperCase()),
      span({ class: 'kpi__value' }, population)
    ),
    div({ class: 'kpi' },
      span({ class: 'kpi__label' }, (i18n.parliamentGovMethod + ': ').toUpperCase()),
      span({ class: 'kpi__value' }, methodLabel)
    ),
    !isAnarchy
      ? div({ class: 'kpi' },
          span({ class: 'kpi__label' }, (i18n.parliamentVotesReceived + ': ').toUpperCase()),
          span({ class: 'kpi__value' }, votesDisplay)
        )
      : null
  );
};

const GovernmentCard = (g, meta) => {
  const termStart = g && g.since ? g.since : null;
  const termEnd = g && g.end ? g.end : null;
  const actorLabel =
    g.powerType === 'tribe'
      ? (i18n.parliamentActorInPowerTribe || i18n.parliamentActorInPower || 'TRIBE RULING')
      : (i18n.parliamentActorInPowerInhabitant || i18n.parliamentActorInPower || 'INHABITANT RULING');
  const methodKeyRaw = g && g.method ? String(g.method) : 'ANARCHY';
  const methodKey = methodKeyRaw.toUpperCase();
  const i18nMeth = i18n[`parliamentMethod${methodKey}`];
  const methodLabel = (i18nMeth && String(i18nMeth).trim() ? String(i18nMeth) : methodKey).toUpperCase();
  const actorLink =
    g.powerType === 'tribe'
      ? a({ class: 'user-link', href: `/tribe/${encodeURIComponent(g.powerId)}` }, g.powerTitle || g.powerId)
      : userLink(g.powerId, g.powerTitle);
  const actorBio = meta && meta.bio ? meta.bio : '';
  const memberIds = Array.isArray(g.membersList) ? g.membersList : (Array.isArray(g.members) ? g.members : []);
  const membersRow =
    g.powerType === 'tribe'
      ? tr(
          { class: 'parliament-members-row' },
          td(
            { colspan: 2 },
            div(
              span({ class: 'card-label' }, (i18n.parliamentMembers + ': ').toUpperCase()),
              memberIds && memberIds.length
                ? ul({ class: 'parliament-members-list' }, ...memberIds.map(id => li(userLink(id))))
                : span({ class: 'card-value' }, String(g.members || 0))
            )
          )
        )
      : null;
  return div(
    { class: 'card' },
    h2(i18n.parliamentGovernmentCard),
    GovHeader(g),
    div({ class: 'method-image-centered' }, img({ src: methodImageSrc(methodKey), alt: methodLabel })),
    div(
      { class: 'table-wrap' },
      applyEl(table, { class: 'table table--centered gov-overview' }, [
        thead(tr(
          th(i18n.parliamentGovMethod),
          th(i18n.parliamentThPresented || 'CANDIDATURES'),
          th(i18n.parliamentPoliciesProposal || 'LAWS PROPOSAL'),
          th(i18n.parliamentPoliciesApproved || 'LAWS APPROVED'),
          th(i18n.parliamentPoliciesDeclined || 'LAWS DECLINED'),
          th(i18n.parliamentPoliciesDiscarded || 'LAWS DISCARDED'),
          th(i18n.parliamentPoliciesRevocated || 'LAWS REVOCATED'),
          th(i18n.parliamentEfficiency || '% EFFICIENCY')
        )),
        tbody(tr(
          td({ 'data-label': i18n.parliamentGovMethod }, methodLabel),
          td({ 'data-label': i18n.parliamentThPresented || 'CANDIDATURES' }, String(g.presented || 0)),
          td({ 'data-label': i18n.parliamentPoliciesProposal || 'LAWS PROPOSAL' }, String(g.proposed || 0)),
          td({ 'data-label': i18n.parliamentPoliciesApproved || 'LAWS APPROVED' }, String(g.approved || 0)),
          td({ 'data-label': i18n.parliamentPoliciesDeclined || 'LAWS DECLINED' }, String(g.declined || 0)),
          td({ 'data-label': i18n.parliamentPoliciesDiscarded || 'LAWS DISCARDED' }, String(g.discarded || 0)),
          td({ 'data-label': i18n.parliamentPoliciesRevocated || 'LAWS REVOCATED' }, String(g.revocated || 0)),
          td({ 'data-label': i18n.parliamentEfficiency || '% EFFICIENCY' }, `${String(g.efficiency || 0)} %`)
        ))
      ])
    ),
    (g.powerType === 'tribe' || g.powerType === 'inhabitant')
      ? div(
          { class: 'table-wrap mt-2' },
          applyEl(table, { class: 'table parliament-actor-table' }, [
            thead(tr(
              th({ class: 'parliament-actor-col' }, String(actorLabel).toUpperCase()),
              th({ class: 'parliament-description-col' }, i18n.description.toUpperCase())
            )),
            tbody(
              tr(
                td({ class: 'parliament-actor-col' }, div({ class: 'leader-cell' }, actorLink)),
                td({ class: 'parliament-description-col' }, p(actorBio || '-'))
              ),
              membersRow
            )
          ])
        )
      : null
  );
};

const NoGovernment = () => div({ class: 'empty' }, p(i18n.parliamentNoStableGov));
const NoProposals = () => div({ class: 'empty' }, p(i18n.parliamentNoProposals));
const NoLaws = () => div({ class: 'empty' }, p(i18n.parliamentNoLaws));
const NoGovernments = () => div({ class: 'empty' }, p(i18n.parliamentNoGovernments));
const NoRevocations = () => null;

const CandidatureForm = () =>
  div(
    { class: 'div-center' },
    h2(i18n.parliamentCandidatureFormTitle),
    form(
      { method: 'POST', action: '/parliament/candidatures/propose' },
      label(i18n.parliamentCandidatureId), br(),
      input({ type: 'text', name: 'candidateId', placeholder: i18n.parliamentCandidatureIdPh, required: true }), br(), br(),
      label(i18n.parliamentCandidatureMethod), br(),
      select({ name: 'method' },
        ['DEMOCRACY','MAJORITY','MINORITY','DICTATORSHIP','KARMATOCRACY'].map(m => option({ value: m }, i18n[`parliamentMethod${m}`] || m))
      ), br(), br(),
      button({ type: 'submit', class: 'create-button' }, i18n.parliamentCandidatureProposeBtn)
    )
  );

const pickLeader = (arr) => {
  if (!arr || !arr.length) return null;
  const sorted = [...arr].sort((a, b) => {
    const va = Number(a.votes || 0), vb = Number(b.votes || 0);
    if (vb !== va) return vb - va;
    const ka = Number(a.karma || 0), kb = Number(b.karma || 0);
    if (kb !== ka) return kb - ka;
    const sa = Number(a.profileSince || 0), sb = Number(b.profileSince || 0);
    if (sa !== sb) return sa - sb;
    const ca = new Date(a.createdAt).getTime(), cb = new Date(b.createdAt).getTime();
    if (ca !== cb) return ca - cb;
    return String(a.targetId).localeCompare(String(b.targetId));
  });
  return sorted[0];
};

const CandidatureStats = (cands, govCard, leaderMeta, electionQuorum = 2) => {
  if (!cands || !cands.length) return null;
  const leader = pickLeader(cands || []);
  if (!leader) return null;
  const methodKey = String(leader.method || '').toUpperCase();
  const methodLabel = String(i18n[`parliamentMethod${methodKey}`] || methodKey).toUpperCase();
  const votes = String(leader.votes || 0);
  const hasQuorum = Number(leader.votes || 0) >= electionQuorum;
  const avatarSrc = (leaderMeta && leaderMeta.avatarUrl) ? leaderMeta.avatarUrl : '/assets/images/default-avatar.png';
  const winLbl = (i18n.parliamentWinningCandidature || i18n.parliamentCurrentLeader || 'WINNING CANDIDATURE').toUpperCase();
  const idLink = leader
    ? (leader.targetType === 'inhabitant'
        ? userLink(leader.targetId)
        : a({ class: 'tag-link', href: `/tribe/${encodeURIComponent(leader.targetId)}?` }, leader.targetTitle || leader.targetId))
    : null;
  const avatarHref = leader
    ? (leader.targetType === 'inhabitant'
        ? `/author/${encodeURIComponent(leader.targetId)}`
        : `/tribe/${encodeURIComponent(leader.targetId)}?`)
    : null;
  return div(
    { class: 'card' },
    h2(i18n.parliamentElectionsStatusTitle),
    div({ class: 'card-field card-field--spaced' },
      span({ class: 'card-label' }, winLbl + ': '),
      span({ class: 'card-value' }, hasQuorum ? idLink : span({ class: 'vote-no-quorum' }, i18n.voteNoQuorum || 'NO QUORUM'))
    ),
    hasQuorum
      ? div({ class: 'card-field card-field--spaced' },
          span({ class: 'card-label' }, (i18n.parliamentGovMethod + ': ').toUpperCase()),
          span({ class: 'card-value' }, methodLabel)
        )
      : null,
    hasQuorum
      ? div(
          { class: 'table-wrap mt-2' },
          applyEl(table, { class: 'parliament-gov-table' }, [
            thead(tr(
              th(i18n.parliamentThLeader),
              th({ class: 'parliament-method-col' }, i18n.parliamentGovMethod),
              th({ class: 'parliament-votes-col'  }, i18n.parliamentVotesReceived)
            )),
            tbody(tr(
              td(
                div({ class: 'parliament-avatar-cell' },
                  avatarHref
                    ? a({ href: avatarHref }, img({ src: avatarSrc, class: 'parliament-leader-avatar' }))
                    : img({ src: avatarSrc, class: 'parliament-leader-avatar' }),
                  idLink ? div({ class: 'parliament-avatar-name' }, idLink) : null
                )
              ),
              td({ class: 'parliament-method-col' },
                img({ src: methodImageSrc(methodKey), alt: methodLabel, class: 'parliament-method-img' })
              ),
              td({ class: 'parliament-votes-col'  }, span({ class: 'votes-value' }, votes))
            ))
          ])
        )
      : null
  );
};

const CandidaturesTable = (candidatures) => {
  const rows = (candidatures || []).map(c => {
    const idLink =
      c.targetType === 'inhabitant'
        ? p(userLink(c.targetId))
        : p(a({ class: 'tag-link', href: `/tribe/${encodeURIComponent(c.targetId)}?` }, c.targetTitle || c.targetId));
    const voters = Array.isArray(c.voters) ? c.voters : [];
    return tr(
      td(idLink),
      td(fmt(c.createdAt)),
      td({ class: 'nowrap' }, c.method),
      td(c.targetType === 'inhabitant' ? String(c.karma || 0) : '-'),
      td(
        span({ class: 'candidature-votes-count' }, String(c.votes || 0)),
        voters.length ? div({ class: 'candidature-voters' }, ...voters.map(v => div({ class: 'candidature-voter' }, userLink(v)))) : null
      ),
      td(form({ method: 'POST', action: `/parliament/candidatures/${encodeURIComponent(c.id)}/vote` }, button({ class: 'vote-btn' }, i18n.parliamentVoteBtn)))
    );
  });
  return div(
    { class: 'table-wrap' },
    h2(i18n.parliamentCandidaturesListTitle),
    applyEl(table, { class: 'table table--centered' }, [
      thead(tr(
        th(i18n.parliamentThId),
        th(i18n.parliamentThProposalDate),
        th(i18n.parliamentThMethod),
        th(i18n.parliamentThKarma),
        th(i18n.parliamentThSupports),
        th(i18n.parliamentThVote)
      )),
      applyEl(tbody, null, rows)
    ])
  );
};

const ProposalForm = () =>
  div(
    { class: 'div-center' },
    h2(i18n.parliamentProposalFormTitle),
    form(
      { method: 'POST', action: '/parliament/proposals/create' },
      label(i18n.parliamentProposalTitle), br(),
      input({ type: 'text', name: 'title', maxlength: '100', required: true }), br(), br(),
      label(i18n.parliamentProposalDescription), br(),
      textarea({ name: 'description', rows: 5, maxlength: 1000 }), br(), br(),
      button({ type: 'submit', class: 'create-button' }, i18n.parliamentProposalPublish)
    )
  );

const ProposalsList = (proposals) => {
  if (!proposals || !proposals.length) return null;
  const cards = proposals.map(pItem => {
    const titleNode = pItem && pItem.voteId
      ? a({ class: 'proposal-title-link', href: `/votes/${encodeURIComponent(pItem.voteId)}` }, pItem.title || '')
      : (pItem.title || '');
    const onTrackLabel = pItem && pItem.onTrack
      ? (i18n.parliamentProposalOnTrackYes || 'THRESHOLD REACHED')
      : (i18n.parliamentProposalOnTrackNo || 'BELOW THRESHOLD');
    return div(
      { class: 'card' },
      br(),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentThProposalDate.toUpperCase() + ': '),
        span({ class: 'card-value' }, fmt(pItem.createdAt))
      ),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentLawProposer.toUpperCase() + ': '),
        span({ class: 'card-value' }, userLink(pItem.proposer))
      ),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentGovMethod.toUpperCase() + ': '),
        span({ class: 'card-value' }, pItem.method)
      ),
      br(),
      div(
        h2(titleNode),
        p(pItem.description || '')
      ),
      pItem.deadline
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalDeadlineLabel.toUpperCase() + ': '),
            span({ class: 'card-value' }, fmt(pItem.deadline))
          )
        : null,
      pItem.deadline
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalTimeLeft.toUpperCase() + ': '),
            span({ class: 'card-value' }, timeLeft(pItem.deadline))
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentVotesNeeded.toUpperCase() + ': '),
            span({ class: 'card-value' }, String(pItem.needed || reqVotes(pItem.method, pItem.total)))
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentVotesSlashTotal.toUpperCase() + ': '),
            span({ class: 'card-value' }, `${Number(pItem.total || 0)}/${Number(pItem.needed || 0)}`)
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalVoteStatusLabel.toUpperCase() + ': '),
            span({ class: 'card-value' }, onTrackLabel)
          )
        : null,
      pItem && pItem.voteId
        ? form(
            { method: 'GET', action: `/votes/${encodeURIComponent(pItem.voteId)}` },
            button({ type: 'submit', class: 'vote-btn' }, i18n.parliamentVoteAction)
          )
        : null
    );
  });
  return div(
    { class: 'cards' },
    h2(i18n.parliamentCurrentProposalsTitle),
    applyEl(div, null, cards)
  );
};

const FutureLawsList = (rows) => {
  if (!rows || !rows.length) return null;
  const cards = rows.map(pItem =>
    div(
      { class: 'card' },
      br(),
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentGovMethod.toUpperCase() + ': '), span({ class: 'card-value' }, pItem.method)),
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentThProposalDate.toUpperCase() + ': '), span({ class: 'card-value' }, fmt(pItem.createdAt))),
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentLawProposer.toUpperCase() + ': '), span({ class: 'card-value' }, userLink(pItem.proposer))),
      h2(pItem.title || ''),
      p(pItem.description || '')
    )
  );
  return div(
    { class: 'cards' },
    h2(i18n.parliamentFutureLawsTitle),
    applyEl(div, null, cards)
  );
};

const RevocationForm = (laws = []) =>
  div(
    { class: 'div-center' },
    h2(i18n.parliamentRevocationFormTitle),
    form(
      {
        method: 'POST',
        action: '/parliament/revocations/create'
      },
      label(i18n.parliamentRevocationLaw), br(),
      select(
        { name: 'lawId', required: true },
        ...(laws || []).map(l =>
          option(
            { value: l.id },
            `${l.question || l.title || l.id}`
          )
        )
      ),
      br(), br(),
      label(i18n.parliamentRevocationReasons), br(),
      textarea({ name: 'reasons', rows: 4, maxlength: 1000 }),
      br(), br(),
      button({ type: 'submit', class: 'create-button' }, i18n.parliamentRevocationPublish || 'Publish Revocation')
    )
  );

const RevocationsList = (revocations) => {
  if (!revocations || !revocations.length) return null;
  const cards = revocations.map(pItem => {
    const titleNode = pItem && pItem.voteId
      ? a({ class: 'revocation-title-link', href: `/votes/${encodeURIComponent(pItem.voteId)}` }, pItem.title || pItem.lawTitle || '')
      : (pItem.title || pItem.lawTitle || '');
    const onTrackLabel = pItem && pItem.onTrack
      ? (i18n.parliamentProposalOnTrackYes || 'THRESHOLD REACHED')
      : (i18n.parliamentProposalOnTrackNo || 'BELOW THRESHOLD');
    return div(
      { class: 'card' },
      br(),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentThProposalDate.toUpperCase() + ': '),
        span({ class: 'card-value' }, fmt(pItem.createdAt))
      ),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentLawProposer.toUpperCase() + ': '),
        span(
          { class: 'card-value' },
          userLink(pItem.proposer)
        )
      ),
      div(
        { class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentGovMethod + ': '),
        span({ class: 'card-value' }, pItem.method)
      ),
      br(),
      div(
        h2(titleNode),
        p(pItem.reasons || '')
      ),
      pItem.deadline
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalDeadlineLabel.toUpperCase() + ': '),
            span({ class: 'card-value' }, fmt(pItem.deadline))
          )
        : null,
      pItem.deadline
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalTimeLeft.toUpperCase() + ': '),
            span({ class: 'card-value' }, timeLeft(pItem.deadline))
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentVotesNeeded.toUpperCase() + ': '),
            span({ class: 'card-value' }, String(pItem.needed || reqVotes(pItem.method, pItem.total)))
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentVotesSlashTotal.toUpperCase() + ': '),
            span({ class: 'card-value' }, `${Number(pItem.total || 0)}/${Number(pItem.needed || 0)}`)
          )
        : null,
      showVoteMetrics(pItem.method)
        ? div(
            { class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentProposalVoteStatusLabel.toUpperCase() + ': '),
            span({ class: 'card-value' }, onTrackLabel)
          )
        : null,
      pItem && pItem.voteId
        ? form(
            { method: 'GET', action: `/votes/${encodeURIComponent(pItem.voteId)}` },
            button({ type: 'submit', class: 'vote-btn' }, i18n.parliamentVoteAction)
          )
        : null
    );
  });
  return div(
    { class: 'cards' },
    h2(i18n.parliamentCurrentRevocationsTitle),
    applyEl(div, null, cards)
  );
};

const FutureRevocationsList = (rows) => {
  if (!rows || !rows.length) return null;
  const cards = rows.map(pItem =>
    div(
      { class: 'card' },
      br(),
      pItem.method ? div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentGovMethod.toUpperCase() + ': '), span({ class: 'card-value' }, pItem.method)) : null,
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentThProposalDate.toUpperCase() + ': '), span({ class: 'card-value' }, fmt(pItem.createdAt))),
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentLawProposer.toUpperCase() + ': '), span({ class: 'card-value' }, userLink(pItem.proposer))),
      h2(pItem.title || pItem.lawTitle || ''),
      p(pItem.reasons || '')
    )
  );
  return div(
    { class: 'cards' },
    h2(i18n.parliamentFutureRevocationsTitle),
    applyEl(div, null, cards)
  );
};

const LawsStats = (laws = [], revocatedCount = 0) => {
  const proposed = laws.length;
  const approved = laws.length;
  const declined = 0;
  const discarded = 0;
  const revocated = Number(revocatedCount || 0);
  return div(
    { class: 'table-wrap' },
    h2(i18n.parliamentPoliciesTitle || 'POLICIES'),
    applyEl(table, { class: 'table table--centered' }, [
      thead(tr(
        th(i18n.parliamentThProposed),
        th(i18n.parliamentThApproved),
        th(i18n.parliamentThDeclined),
        th(i18n.parliamentThDiscarded),
        th(i18n.parliamentPoliciesRevocated)
      )),
      tbody(
        tr(
          td(String(proposed)),
          td(String(approved)),
          td(String(declined)),
          td(String(discarded)),
          td(String(revocated))
        )
      )
    ])
  );
};

const LawsList = (laws) => {
  if (!laws || !laws.length) return NoLaws();
  const cards = laws.map(l => {
    const total = Number((l.votes && (l.votes.total || l.votes.TOTAL)) || 0);
    const yes = Number((l.votes && (l.votes.YES || l.votes.Yes || l.votes.yes)) || 0);
    const needed = reqVotes(l.method, total);
    const showMetricsFlag = showVoteMetrics(l.method);
    return div(
      { class: 'card' },
      br(),
      div({ class: 'card-field' }, span({ class: 'card-label' }, (i18n.parliamentGovMethod + ': ').toUpperCase()), span({ class: 'card-value' }, l.method)),
      div({ class: 'card-field' }, span({ class: 'card-label' }, (i18n.parliamentLawEnacted + ': ').toUpperCase()), span({ class: 'card-value' }, fmt(l.enactedAt))),
      div({ class: 'card-field' }, span({ class: 'card-label' }, i18n.parliamentLawProposer.toUpperCase() + ': '), span({ class: 'card-value' }, userLink(l.proposer))),
      h2(l.question || ''),
      p(l.description || ''),
      showMetricsFlag ? div({ class: 'card-field' }, span({ class: 'card-label' }, (i18n.parliamentVotesNeeded + ': ').toUpperCase()), span({ class: 'card-value' }, String(needed))) : null,
      showMetricsFlag ? div({ class: 'card-field' }, span({ class: 'card-label' }, (i18n.parliamentVotesSlashTotal + ': ').toUpperCase()), span({ class: 'card-value' }, `${yes}/${total}`)) : null
    );
  });
  return div(
    { class: 'cards' },
    h2(i18n.parliamentLawsTitle || 'LAWS'),
    applyEl(div, null, cards)
  );
};

const HistoricalGovsSummary = (rows = []) => {
  const byMethod = new Map();
  for (const g of rows) {
    const k = String(g.method || 'ANARCHY').toUpperCase();
    if (!byMethod.has(k)) byMethod.set(k, { cycles: 0, proposed: 0, approved: 0, declined: 0, discarded: 0, revocated: 0 });
    const rec = byMethod.get(k);
    rec.cycles += 1;
    rec.proposed += Number(g.proposed || 0);
    rec.approved += Number(g.approved || 0);
    rec.declined += Number(g.declined || 0);
    rec.discarded += Number(g.discarded || 0);
    rec.revocated += Number(g.revocated || 0);
  }
  const entries = Array.from(byMethod.entries()).sort((a,b) => String(a[0]).localeCompare(String(b[0])));
  const lines = entries.map(([method, rec]) =>
    tr(
      td(method),
      td(String(rec.proposed)),
      td(String(rec.approved)),
      td(String(rec.declined)),
      td(String(rec.discarded)),
      td(String(rec.revocated)),
      td(String(rec.cycles))
    )
  );
  return div(
    { class: 'table-wrap' },
    h2(i18n.parliamentHistoricalGovernmentsTitle || 'Governments'),
    applyEl(table, { class: 'table table--centered' }, [
      thead(tr(
        th(String(i18n.parliamentGovMethod).toUpperCase()),
        th(i18n.parliamentPoliciesProposal),
        th(i18n.parliamentPoliciesApproved),
        th(i18n.parliamentPoliciesDeclined),
        th(i18n.parliamentPoliciesDiscarded),
        th(i18n.parliamentPoliciesRevocated),
        th(i18n.parliamentThCycles)
      )),
      applyEl(tbody, null, lines)
    ])
  );
};

const HistoricalList = (rows, metasByKey = {}) => {
  if (!rows || !rows.length) return NoGovernments();
  const cards = rows.map(g => {
    const key = `${g.powerType}:${g.powerId}`;
    const meta = metasByKey[key];
    const showActor = g.powerType === 'tribe' || g.powerType === 'inhabitant';
    const showMembers = g.powerType === 'tribe';
    const actorLabel =
      g.powerType === 'tribe'
        ? (i18n.parliamentActorInPowerTribe || 'TRIBE RULING')
        : (i18n.parliamentActorInPowerInhabitant || 'INHABITANT RULING');
    return div(
      { class: 'card' },
      h2(g.method),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, (i18n.parliamentLegSince + ': ').toUpperCase()),
        span({ class: 'card-value' }, fmt(g.since))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, (i18n.parliamentLegEnd + ': ').toUpperCase()),
        span({ class: 'card-value' }, fmt(g.end))
      ),
      showActor ? div({ class: 'card-field' },
        span({ class: 'card-label' }, String(actorLabel).toUpperCase() + ': '),
        span({ class: 'card-value' },
          g.powerType === 'tribe'
            ? a({ class: 'user-link', href: `/tribe/${encodeURIComponent(g.powerId)}` }, g.powerTitle || g.powerId)
            : userLink(g.powerId, g.powerTitle)
        )
      ) : null,
      (g.method !== 'ANARCHY')
        ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentVotesReceived + ': '),
            span({ class: 'card-value' }, `${g.votesReceived} (${g.totalVotes})`)
          )
        : null,
      br(),
      showActor && meta && (meta.avatarUrl || meta.bio)
        ? div(
            { class: 'actor-meta' },
            meta.avatarUrl ? img({ src: meta.avatarUrl, alt: '', class: 'avatar--lg' }) : null,
            meta.bio ? p({ class: 'bio' }, meta.bio) : null
          )
        : null,
      showMembers
        ? div({ class: 'card-field' },
            span({ class: 'card-label' }, i18n.parliamentMembers + ': '),
            span({ class: 'card-value' }, String(g.members || 0))
          )
        : null,
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentPoliciesProposal + ': '),
        span({ class: 'card-value' }, String(g.proposed || 0))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentPoliciesApproved + ': '),
        span({ class: 'card-value' }, String(g.approved || 0))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentPoliciesDeclined + ': '),
        span({ class: 'card-value' }, String(g.declined || 0))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentPoliciesDiscarded + ': '),
        span({ class: 'card-value' }, String(g.discarded || 0))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentPoliciesRevocated + ': '),
        span({ class: 'card-value' }, String(g.revocated || 0))
      ),
      div({ class: 'card-field' },
        span({ class: 'card-label' }, i18n.parliamentEfficiency + ': '),
        span({ class: 'card-value' }, `${g.efficiency || 0} %`)
      )
    );
  });
  return div(
    { class: 'cards' },
    h2(i18n.parliamentHistoricalElectionsTitle || 'ELECTION CYCLES'),
    applyEl(div, null, cards)
  );
};

const LeadersSummary = (leaders = [], candidatures = [], allGovCards = [], totalCandidatures = null) => {
  const timesInPower = leaders.reduce((s, l) => s + Number(l.inPower || 0), 0);
  const totals = (allGovCards || []).reduce((acc, g) => {
    acc.proposed += Number(g.proposed || 0);
    acc.approved += Number(g.approved || 0);
    acc.declined += Number(g.declined || 0);
    acc.discarded += Number(g.discarded || 0);
    acc.revocated += Number(g.revocated || 0);
    return acc;
  }, { proposed:0, approved:0, declined:0, discarded:0, revocated:0 });
  const presented = totalCandidatures != null ? Number(totalCandidatures) : (candidatures || []).length;
  const efficiencyPct = totals.proposed > 0 ? Math.round((totals.approved / totals.proposed) * 100) : 0;
  return div(
    { class: 'table-wrap' },
    h2(i18n.parliamentHistoricalLawsTitle || 'Actions'),
    applyEl(table, { class: 'table table--centered' }, [
      thead(tr(
        th(i18n.parliamentThTotalCandidatures),
        th(i18n.parliamentThTimesInPower),
        th(i18n.parliamentThProposed),
        th(i18n.parliamentThApproved),
        th(i18n.parliamentThDeclined),
        th(i18n.parliamentThDiscarded),
        th(i18n.parliamentPoliciesRevocated),
        th(i18n.parliamentEfficiency)
      )),
      tbody(
        tr(
          td(String(presented)),
          td(String(timesInPower)),
          td(String(totals.proposed)),
          td(String(totals.approved)),
          td(String(totals.declined)),
          td(String(totals.discarded)),
          td(String(totals.revocated)),
          td(`${efficiencyPct} %`)
        )
      )
    ])
  );
};

const LeadersList = (leaders, metas = {}, candidatures = []) => {
  if (!leaders || !leaders.length) return div({ class: 'empty' }, p(i18n.parliamentNoLeaders));
  const rows = leaders.map(l => {
    const key = `${l.powerType}:${l.powerId}`;
    const meta = metas[key] || {};
    const avatarHref = l.powerType === 'tribe'
      ? `/tribe/${encodeURIComponent(l.powerId)}`
      : `/author/${encodeURIComponent(l.powerId)}`;
    const avatar = meta.avatarUrl
      ? a({ href: avatarHref }, img({ src: meta.avatarUrl, alt: '', class: 'leader-table__avatar' }))
      : null;
    const link = l.powerType === 'tribe'
      ? a({ class: 'user-link', href: `/tribe/${encodeURIComponent(l.powerId)}` }, l.powerTitle || l.powerId)
      : userLink(l.powerId, l.powerTitle);
    const leaderCell = div({ class: 'leader-cell parliament-avatar-cell' }, avatar, div({ class: 'parliament-avatar-name' }, link));
    return tr(
      td(leaderCell),
      td(String(l.proposed || 0)),
      td(String(l.approved || 0)),
      td(String(l.declined || 0)),
      td(String(l.discarded || 0)),
      td(String(l.revocated || 0)),
      td(`${(l.efficiency != null ? Math.round(l.efficiency * 100) : (l.proposed > 0 ? Math.round((l.approved / l.proposed) * 100) : 0))} %`)
    );
  });
  return div(
    { class: 'table-wrap' },
    h2(i18n.parliamentHistoricalLeadersTitle),
    applyEl(table, { class: 'table table--centered gov-overview' }, [
      thead(tr(
        th(i18n.parliamentThLeader),
        th(i18n.parliamentPoliciesProposal),
        th(i18n.parliamentPoliciesApproved),
        th(i18n.parliamentPoliciesDeclined),
        th(i18n.parliamentPoliciesDiscarded),
        th(i18n.parliamentPoliciesRevocated),
        th(i18n.parliamentEfficiency)
      )),
      applyEl(tbody, null, rows)
    ])
  );
};

const RulesContent = () => {
  const points = [
    i18n.parliamentRulesIntro,
    i18n.parliamentRulesTerm,
    i18n.parliamentRulesMethods,
    i18n.parliamentRulesAnarchy,
    i18n.parliamentRulesCandidates,
    i18n.parliamentRulesElection,
    i18n.parliamentRulesTies,
    i18n.parliamentRulesProposals,
    i18n.parliamentRulesLimit,
    i18n.parliamentRulesLaws,
    i18n.parliamentRulesRevocations,
    i18n.parliamentRulesHistorical,
    i18n.parliamentRulesLeaders
  ];
  return div(
    { class: 'card' },
    h2(i18n.parliamentRulesTitle),
    div({ class: 'rules-points' },
      points.filter(Boolean).map((t, i) =>
        div({ class: 'rules-point' },
          span({ class: 'rules-point-num' }, String(i + 1)),
          span({ class: 'rules-point-text' }, t)
        )
      )
    )
  );
};

const CandidaturesSection = (governmentCard, candidatures, leaderMeta, electionQuorum = 2) => {
  return div(
    h2(i18n.parliamentGovernmentCard),
    GovHeader(governmentCard || {}),
    CandidatureStats(candidatures || [], governmentCard || null, leaderMeta || null, electionQuorum),
    CandidatureForm(),
    candidatures && candidatures.length ? CandidaturesTable(candidatures) : null
  );
};

const ProposalsSection = (governmentCard, proposals, futureLaws, canPropose) => {
  const has = proposals && proposals.length > 0;
  const fl = FutureLawsList(futureLaws || []);
  if (!has && canPropose) return div(h2(i18n.parliamentGovernmentCard), GovHeader(governmentCard || {}), ProposalForm(), fl);
  if (!has && !canPropose) return div(h2(i18n.parliamentGovernmentCard), GovHeader(governmentCard || {}), NoProposals(), fl);
  return div(h2(i18n.parliamentGovernmentCard), GovHeader(governmentCard || {}), ProposalForm(), ProposalsList(proposals), fl);
};

const RevocationsSection = (governmentCard, laws, revocations, futureRevocations) =>
  div(
    h2(i18n.parliamentGovernmentCard),
    GovHeader(governmentCard || {}),
    RevocationForm(laws || []),
    RevocationsList(revocations || []) || '',
    FutureRevocationsList(futureRevocations || []) || ''
  );

const normalizeGovCard = (governmentCard, inhabitantsTotal) => {
  const pop = Number(inhabitantsTotal ?? governmentCard?.inhabitantsTotal ?? 0) || 0;
  if (governmentCard && (governmentCard.method || governmentCard.since || governmentCard.end || governmentCard.powerType)) {
    return { ...governmentCard, inhabitantsTotal: pop };
  }
  return null;
};

const parliamentView = async (state) => {
  const {
    filter,
    governmentCard,
    candidatures,
    proposals,
    futureLaws,
    canPropose,
    laws,
    historical,
    leaders,
    leaderMeta,
    powerMeta,
    revocations,
    futureRevocations,
    revocationsEnactedCount,
    historicalMetas = {},
    leadersMetas = {},
    inhabitantsTotal
  } = state;

  const fallbackGov = {
    method: 'ANARCHY',
    votesReceived: 0,
    totalVotes: 0,
    proposed: 0,
    approved: 0,
    declined: 0,
    discarded: 0,
    revocated: 0,
    efficiency: 0,
    powerType: 'none',
    powerId: null,
    powerTitle: 'ANARCHY',
    since: null,
    end: null,
    inhabitantsTotal: Number(inhabitantsTotal ?? 0) || 0
  };

  const gov = normalizeGovCard(governmentCard, inhabitantsTotal) || fallbackGov;
  const electionQuorum = Math.max(2, Math.ceil((Number(inhabitantsTotal) || 0) * 0.25));
  const leadersGovCards = [...(historical || []), ...(governmentCard ? [governmentCard] : [])];
  const leadersTotalCandidatures = governmentCard && governmentCard.presented != null ? governmentCard.presented : null;

  const LawsSectionWrap = () =>
    div(
      LawsStats(laws || [], revocationsEnactedCount || 0),
      LawsList(laws || [])
    );

  return template(
    i18n.parliamentTitle,
    section(div({ class: 'tags-header' }, h2(i18n.parliamentTitle), p(i18n.parliamentDescription)), Tabs(filter)),
    section(
      filter === 'government' ? GovernmentCard(gov, powerMeta) : null,
      filter === 'candidatures' ? CandidaturesSection(gov, candidatures, leaderMeta, electionQuorum) : null,
      filter === 'proposals' ? ProposalsSection(gov, proposals, futureLaws, canPropose) : null,
      filter === 'laws' ? LawsSectionWrap() : null,
      filter === 'revocations' ? RevocationsSection(gov, laws, revocations, futureRevocations) : null,
      filter === 'historical' ? div(HistoricalGovsSummary(historical || []), HistoricalList(historical || [], historicalMetas)) : null,
      filter === 'leaders' ? div(LeadersSummary(leaders || [], candidatures || [], leadersGovCards, leadersTotalCandidatures), LeadersList(leaders || [], leadersMetas, candidatures || [])) : null,
      filter === 'rules' ? RulesContent() : null
    )
  );
};

module.exports = { parliamentView, pickLeader };

