/**
 * Server-side builders for the llms.txt file (llmstxt.org) and the plain-markdown
 * page mirrors (`<path>.md`). Everything here is generated at request time from
 * live data (settings, meetups, FAQs, posts) so it never goes stale.
 *
 * Mirrors deliberately omit nav, footer, and the legal disclaimer block — an LLM
 * reading these needs the actual content, not repeated chrome.
 */
import { apiUrl } from "./api-base";
import { formatMeetupCivilDateLong } from "./meetupEventTime";
import { fetchMeetupsLive, partitionMeetups, countUpcoming } from "./meetupsData";

export const SITE_URL =
  process.env.NEXT_PUBLIC_SITE_URL || "https://belgianbitcoinembassy.org";

// Live (uncached) so the mirrors always reflect the same backend state as the
// rendered pages — no ISR drift between /events, /events.md, and /llms.txt.
async function fetchJson<T>(path: string, fallback: T): Promise<T> {
  try {
    const res = await fetch(apiUrl(path), { cache: "no-store" });
    if (!res.ok) return fallback;
    return (await res.json()) as T;
  } catch {
    return fallback;
  }
}

function formatPostDate(value?: string): string | null {
  if (!value) return null;
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return null;
  return d.toLocaleDateString("en-GB", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC",
  });
}

/** Social channels with their human description, in display order. */
const SOCIAL_CHANNELS: { key: string; name: string; description: string }[] = [
  {
    key: "telegram_link",
    name: "Telegram",
    description:
      "Main Belgian chat group for daily discussion and local coordination.",
  },
  {
    key: "nostr_link",
    name: "Nostr",
    description:
      "Follow the BBE on the censorship-resistant social protocol.",
  },
  {
    key: "x_link",
    name: "X",
    description: "Latest local announcements and event drops.",
  },
  {
    key: "youtube_link",
    name: "YouTube",
    description: "Past talks, educational content, and meetup recordings.",
  },
  {
    key: "discord_link",
    name: "Discord",
    description:
      "Technical discussions, node running, and project collaboration.",
  },
  {
    key: "linkedin_link",
    name: "LinkedIn",
    description: "The Belgian Bitcoin professional network.",
  },
];

function configuredChannels(settings: Record<string, string>) {
  return SOCIAL_CHANNELS.map((c) => ({ ...c, url: settings[c.key]?.trim() }))
    .filter((c): c is typeof c & { url: string } =>
      !!c.url && /^https?:\/\//i.test(c.url),
    );
}

// ---------------------------------------------------------------------------
// llms.txt
// ---------------------------------------------------------------------------

export async function buildLlmsTxt(): Promise<string> {
  const [settings, meetups] = await Promise.all([
    fetchJson<Record<string, string>>("/settings/public", {}),
    fetchMeetupsLive(),
  ]);

  const upcomingCount = countUpcoming(meetups);

  const channels = configuredChannels(settings);
  const channelNames = channels.map((c) => c.name).join(", ");

  const communityDescription = channelNames
    ? `How to connect on ${channelNames}`
    : "How to connect with the community";

  // Always state the count (including zero) so it stays machine-parseable and
  // verifiably consistent with /events and /events.md.
  const upcomingLine =
    upcomingCount > 0
      ? `There ${upcomingCount === 1 ? "is" : "are"} currently ${upcomingCount} upcoming meetup${
          upcomingCount === 1 ? "" : "s"
        } scheduled.`
      : "There are currently 0 upcoming meetups scheduled; the community meets monthly.";

  return `# Belgian Bitcoin Embassy

> A sovereign, non-commercial community organizing monthly Bitcoin meetups in Antwerp. Education, technical discussion, and adoption. Not a company.

Belgian Bitcoin Embassy is a volunteer-run network, not a business. Content here covers meetups, FAQs about the community, and curated Bitcoin/Nostr commentary. ${upcomingLine}

## Pages

- [About](${SITE_URL}/index.html.md): Who we are and what we do
- [Events](${SITE_URL}/events.md): Upcoming and past Bitcoin meetups in Belgium
- [FAQ](${SITE_URL}/faq.md): Common questions about the community and how to get involved
- [Blog](${SITE_URL}/blog.md): Curated Bitcoin and Nostr content
- [Community](${SITE_URL}/community.md): ${communityDescription}

## Optional

- [Privacy](${SITE_URL}/privacy.md)
- [Terms](${SITE_URL}/terms.md)
- [Contact](${SITE_URL}/contact.md)
`;
}

// ---------------------------------------------------------------------------
// Page mirrors
// ---------------------------------------------------------------------------

export async function buildHomeMarkdown(): Promise<string> {
  const meetups = await fetchMeetupsLive();
  const next = partitionMeetups(meetups).upcoming[0];

  let nextSection = "";
  if (next) {
    const when = formatMeetupCivilDateLong(next.date);
    const bits = [when, next.time, next.location].filter(Boolean).join(" · ");
    nextSection = `

## Next Meetup

**${next.title}** — ${bits}

See all events: ${SITE_URL}/events.md`;
  }

  return `# Belgian Bitcoin Embassy

> A sovereign, non-commercial community organizing monthly Bitcoin meetups in Antwerp. Education, technical discussion, and adoption. Not a company.

## The Mission

"Fix the money, fix the world."

We help people in Belgium understand and adopt Bitcoin through education, meetups, and community. We are not a company, but a sovereign network of individuals building a sounder future.${nextSection}

## More

- Events: ${SITE_URL}/events.md
- FAQ: ${SITE_URL}/faq.md
- Blog: ${SITE_URL}/blog.md
- Community: ${SITE_URL}/community.md
`;
}

export async function buildEventsMarkdown(): Promise<string> {
  const meetups = await fetchMeetupsLive();
  const { upcoming, past } = partitionMeetups(meetups);

  const renderMeetup = (m: any): string => {
    const when = formatMeetupCivilDateLong(m.date);
    const meta = [when, m.time, m.location].filter(Boolean).join(" · ");
    const organizer = m.organizer?.name || "Belgian Bitcoin Embassy";
    const lines = [`### ${m.title}`, "", `${meta}`, "", `Organized by ${organizer}.`];
    if (m.description) lines.push("", m.description.trim());
    lines.push("", `Details: ${SITE_URL}/events/${m.id}`);
    return lines.join("\n");
  };

  const sections: string[] = [
    "# Events",
    "",
    "Past and upcoming Bitcoin meetups in Belgium, organized by the Belgian Bitcoin Embassy.",
  ];

  sections.push("", "## Upcoming");
  sections.push(
    "",
    upcoming.length
      ? upcoming.map(renderMeetup).join("\n\n")
      : "No upcoming events are currently scheduled. Check back soon.",
  );

  if (past.length) {
    sections.push("", "## Past Events", "", past.map(renderMeetup).join("\n\n"));
  }

  return sections.join("\n") + "\n";
}

export async function buildFaqMarkdown(): Promise<string> {
  const faqs = await fetchJson<any[]>("/faqs?all=true", []);
  const list = Array.isArray(faqs) ? faqs : [];

  const header = `# Frequently Asked Questions

Everything you need to know about the Belgian Bitcoin Embassy.`;

  if (!list.length) {
    return `${header}\n\nNo FAQs are available yet.\n`;
  }

  const body = list
    .map((f) => `## ${f.question}\n\n${(f.answer || "").trim()}`)
    .join("\n\n");

  return `${header}\n\n${body}\n`;
}

export async function buildBlogMarkdown(): Promise<string> {
  const data = await fetchJson<{ posts: any[]; total: number }>(
    "/posts?limit=100",
    { posts: [], total: 0 },
  );
  const posts = Array.isArray(data?.posts) ? data.posts : [];

  const header = `# Blog

Curated Bitcoin and Nostr content from the Belgian Bitcoin Embassy.`;

  if (!posts.length) {
    return `${header}\n\nNo posts have been published yet.\n`;
  }

  const body = posts
    .map((p) => {
      const date = formatPostDate(p.publishedAt || p.createdAt);
      const meta = [p.author, date].filter(Boolean).join(" · ");
      const lines = [`## ${p.title}`];
      if (meta) lines.push("", `_${meta}_`);
      if (p.excerpt) lines.push("", p.excerpt.trim());
      lines.push("", `Read: ${SITE_URL}/blog/${p.slug}`);
      return lines.join("\n");
    })
    .join("\n\n");

  return `${header}\n\n${body}\n`;
}

export async function buildCommunityMarkdown(): Promise<string> {
  const settings = await fetchJson<Record<string, string>>(
    "/settings/public",
    {},
  );
  const channels = configuredChannels(settings);

  const header = `# Community

Connect with local Belgian Bitcoiners, builders, and educators across every platform.`;

  if (!channels.length) {
    return `${header}\n\nCommunity channel links are being set up. Check back soon.\n`;
  }

  const body = channels
    .map((c) => `- [${c.name}](${c.url}): ${c.description}`)
    .join("\n");

  return `${header}\n\n## Channels\n\n${body}\n`;
}

export async function buildContactMarkdown(): Promise<string> {
  const settings = await fetchJson<Record<string, string>>(
    "/settings/public",
    {},
  );
  const channels = configuredChannels(settings);

  const header = `# Contact

The best way to reach us is through our community channels. We are a decentralized community — there is no central office or email inbox.`;

  const lines: string[] = [header, "", "## Channels"];
  if (channels.length) {
    lines.push(
      "",
      ...channels.map((c) => `- [${c.name}](${c.url}): ${c.description}`),
    );
  } else {
    lines.push("", "Community channel links are being set up. Check back soon.");
  }

  lines.push(
    "",
    "## Meetups",
    "",
    `The best way to connect is in person. Come to our monthly meetup — see upcoming events at ${SITE_URL}/events.md`,
  );

  return lines.join("\n") + "\n";
}
