const ACTIVITIES_CONFIG = {
    apiBase: "https://openbokeron.uma.es/gitea/api/v1",
    repo: "OpenBokeron/Actividades",
    state: "open",
};

const ACTIVITY_LABELS = {
    cooking: "cocinando",
};

const ACTIVITY_BADGES = {
    es: {
        cooking: "Cocinando",
    },
    en: {
        cooking: "Cooking",
    },
};

const ACTIVITY_BADGE_STYLE = {
    cooking: "status-cooking",
};

const ACTIVITY_CTA = {
    es: "Ver en Gitea",
    en: "View on Gitea",
};

const ACTIVITY_EMPTY = {
    es: "Ahora mismo no hay actividades abiertas. Vuelve pronto o mira el tablero completo.",
    en: "There are no open activities right now. Come back soon or check the full board.",
};


const FALLBACK_TEXT = {
    es: "Oops, la hemos liado al querer cargar el tablero. Puedes verlo directamente en Gitea:",
    en: "Oops, we messed up while trying to load the board. You can still open it in Gitea:",
};

const FALLBACK_LINK = {
    es: "Abrir tablero",
    en: "Open board",
};

const LANGUAGE_LABELS = {
    es: {
        milestone: "Hito",
        comments: "comentarios",
        updated: "Actualizado",
        noCooking: "No hay actividades en desarrollo. Mira el tablero completo.",
        noIdeas: "No hay ideas nuevas ahora mismo.",
    },
    en: {
        milestone: "Milestone",
        comments: "comments",
        updated: "Updated",
        noCooking: "No activities in development. Check the full board.",
        noIdeas: "There are no new ideas right now.",
    },
};

const escapeHtml = (value) => {
    if (value === null || value === undefined) {
        return "";
    }

    return String(value).replace(/[&<>"']/g, (char) => {
        const map = {
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': "&quot;",
            "'": "&#39;",
        };
        return map[char] || char;
    });
};

const container = document.querySelector("[data-activities-root]");
if (container) {
    const grid = container.querySelector("[data-activities-grid]");
    const lang = document.documentElement.lang.startsWith("es") ? "es" : "en";
    const labels = LANGUAGE_LABELS[lang];

    const fetchActivities = async () => {
        const url = `${ACTIVITIES_CONFIG.apiBase}/repos/${ACTIVITIES_CONFIG.repo}/issues?state=${ACTIVITIES_CONFIG.state}`;
        const response = await fetch(url, {
            headers: {
                Accept: "application/json",
            },
        });

        if (!response.ok) {
            throw new Error(`Request failed: ${response.status}`);
        }

        return response.json();
    };

    const formatDate = (value) => {
        const date = new Date(value);
        if (Number.isNaN(date.getTime())) {
            return value;
        }
        return new Intl.DateTimeFormat(lang, {
            year: "numeric",
            month: "short",
            day: "numeric",
        }).format(date);
    };

    const getLabelNames = (issue) => (issue.labels || []).map((label) => label.name.toLowerCase());

    const hasLabel = (issue, label) => getLabelNames(issue).includes(label);

    const renderTags = (tags) => {
        if (!tags || tags.length === 0) {
            return "";
        }

        return tags
            .filter((label) => label.name.toLowerCase() !== ACTIVITY_LABELS.cooking)
            .slice(0, 3)
            .map((label) => `<span class="activity-tag">${label.name}</span>`)
            .join("");
    };

    const getBadge = (issue) => {
        if (hasLabel(issue, ACTIVITY_LABELS.cooking)) {
            return {
                text: ACTIVITY_BADGES[lang].cooking,
                className: ACTIVITY_BADGE_STYLE.cooking,
            };
        }
        return null;
    };

    const renderActivity = (issue) => {
        const tags = renderTags(issue.labels);
        const milestone = issue.milestone?.title;
        const updated = formatDate(issue.updated_at);
        const badge = getBadge(issue);
        const comments = issue.comments || 0;

        return `
      <article class="activity-card">
        <div class="activity-head">
          ${badge ? `<span class="activity-status ${badge.className}">${badge.text}</span>` : ""}
        </div>
        <h3>${escapeHtml(issue.title)}</h3>
        <p>${issue.body ? escapeHtml(issue.body.replace(/\s+/g, " ").slice(0, 140) + "...") : ""}</p>
        <div class="activity-meta">
          <span>${labels.updated} ${updated}</span>
          <span>${comments} ${labels.comments}</span>
          <span>#${issue.number}</span>
        </div>
        ${milestone ? `<div class="activity-meta">${labels.milestone}: ${milestone}</div>` : ""}
        ${tags ? `<div class="activity-tags">${tags}</div>` : ""}
        <a class="activity-link" href="${issue.html_url}" target="_blank" rel="noopener">${ACTIVITY_CTA[lang]}</a>
      </article>
    `;
    };

    const renderIdeas = (ideas) => {
        const ideasList = container.querySelector("[data-activities-ideas-list]");

        if (!ideasList) {
            return;
        }

        if (!ideas || ideas.length === 0) {
            ideasList.innerHTML = `<li class="activities-idea">${labels.noIdeas}</li>`;
            return;
        }

        ideasList.innerHTML = ideas
            .map(
                (issue) => `
          <li class="activities-idea">
            <div>
              <strong>${escapeHtml(issue.title)}</strong>
              <span class="activity-meta">#${issue.number}</span>
            </div>
            <a href="${issue.html_url}" target="_blank" rel="noopener">${ACTIVITY_CTA[lang]}</a>
          </li>
        `
            )
            .join("");
    };

    const renderActivities = (issues) => {
        if (!issues || issues.length === 0) {
            grid.innerHTML = `<div class="activities-empty">${ACTIVITY_EMPTY[lang]}</div>`;
            renderIdeas([]);
            return;
        }

        const cooking = issues.filter((issue) => hasLabel(issue, ACTIVITY_LABELS.cooking));
        const ideas = issues.filter((issue) => !hasLabel(issue, ACTIVITY_LABELS.cooking));

        const cookingTitles = new Set(cooking.map((issue) => issue.title));
        const filteredIdeas = ideas.filter((issue) => !cookingTitles.has(issue.title));

        if (cooking.length === 0) {
            grid.innerHTML = `<div class="activities-empty">${labels.noCooking}</div>`;
        } else {
            grid.innerHTML = cooking.map(renderActivity).join("");
        }

        renderIdeas(filteredIdeas);
    };

    const renderFallback = () => {
        grid.innerHTML = `
      <div class="activities-empty">
        ${FALLBACK_TEXT[lang]}
        <a href="https://openbokeron.uma.es/gitea/OpenBokeron/-/projects/5" target="_blank" rel="noopener">${FALLBACK_LINK[lang]}</a>
      </div>
    `;

        const ideasList = container.querySelector("[data-activities-ideas-list]");
        if (ideasList) {
            ideasList.innerHTML = `<li class="activities-idea">${labels.noIdeas}</li>`;
        }
    };

    fetchActivities()
        .then((issues) => {
            const sorted = [...issues].sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));
            renderActivities(sorted);
        })
        .catch(() => {
            renderFallback();
        });
}
