import fs from "node:fs";
import path from "node:path";
import matter from "gray-matter";
import { marked } from "marked";

const CONTENT_ROOT = path.join(process.cwd(), "content");

export type CompetitionSlug = "hands-on-challenge" | "ideathon" | "robo-soccer";

export type Competition = {
  slug: CompetitionSlug;
  name: string;
  short: string;
  tagline: string;
  format: string;
  durationDays?: number;
  ageGroups?: string[];
  categories?: string[];
  color?: "brand" | "accent" | "pink";
  icon?: string;
  order: number;
  bodyHtml: string;
};

export type Winner = {
  place: number;
  team: string;
  school?: string;
  members?: number;
};

export type Team = {
  name: string;
  school?: string;
  size?: number;
  note?: string;
};

export type Testimonial = {
  by: string;
  org?: string;
  quote: string;
};

export type Edition = {
  slug: string;
  competition: CompetitionSlug;
  name: string;
  status: "upcoming" | "past" | "announced";
  startDate?: string;
  endDate?: string;
  city?: string;
  venue?: string;
  hero?: string;
  stats?: {
    teams?: number;
    participants?: number;
    volunteers?: number;
  };
  partners?: string[];
  winners?: Winner[];
  teams?: Team[];
  photos?: string[];
  testimonials?: Testimonial[];
  summary?: string;
  bodyHtml: string;
};

function readDir(dir: string): string[] {
  const full = path.join(CONTENT_ROOT, dir);
  if (!fs.existsSync(full)) return [];
  return fs
    .readdirSync(full)
    .filter((f) => f.endsWith(".md"))
    .map((f) => path.join(full, f));
}

function parseFile<T extends object>(
  filePath: string,
): { data: T; bodyHtml: string } {
  const raw = fs.readFileSync(filePath, "utf8");
  const parsed = matter(raw);
  const bodyHtml = parsed.content.trim()
    ? (marked.parse(parsed.content, { async: false }) as string)
    : "";
  return { data: parsed.data as T, bodyHtml };
}

export function getCompetitions(): Competition[] {
  const files = readDir("competitions");
  const items = files.map((fp) => {
    const { data, bodyHtml } = parseFile<Omit<Competition, "bodyHtml">>(fp);
    return { ...data, bodyHtml };
  });
  return items.sort((a, b) => (a.order ?? 99) - (b.order ?? 99));
}

export function getCompetition(slug: string): Competition | null {
  return getCompetitions().find((c) => c.slug === slug) ?? null;
}

export function getEditions(): Edition[] {
  const files = readDir("editions");
  const items = files.map((fp) => {
    const { data, bodyHtml } = parseFile<Omit<Edition, "bodyHtml">>(fp);
    return { ...data, bodyHtml };
  });
  return items.sort((a, b) => {
    const ad = a.startDate ?? "0000";
    const bd = b.startDate ?? "0000";
    return bd.localeCompare(ad);
  });
}

export function getEdition(slug: string): Edition | null {
  return getEditions().find((e) => e.slug === slug) ?? null;
}

export function getEditionsFor(comp: CompetitionSlug): Edition[] {
  return getEditions().filter((e) => e.competition === comp);
}

export function getUpcomingEdition(): Edition | null {
  return (
    getEditions().find((e) => e.status === "upcoming" || e.status === "announced") ?? null
  );
}

export function getTotalStats(): {
  editions: number;
  teams: number;
  participants: number;
  volunteers: number;
} {
  const past = getEditions().filter((e) => e.status === "past");
  return past.reduce(
    (acc, e) => ({
      editions: acc.editions + 1,
      teams: acc.teams + (e.stats?.teams ?? 0),
      participants: acc.participants + (e.stats?.participants ?? 0),
      volunteers: acc.volunteers + (e.stats?.volunteers ?? 0),
    }),
    { editions: 0, teams: 0, participants: 0, volunteers: 0 },
  );
}

export function formatDateRange(start?: string, end?: string): string {
  if (!start) return "Tarih yakında açıklanacak";
  const s = new Date(start);
  const months = [
    "Ocak",
    "Şubat",
    "Mart",
    "Nisan",
    "Mayıs",
    "Haziran",
    "Temmuz",
    "Ağustos",
    "Eylül",
    "Ekim",
    "Kasım",
    "Aralık",
  ];
  if (!end || end === start) {
    return `${s.getUTCDate()} ${months[s.getUTCMonth()]} ${s.getUTCFullYear()}`;
  }
  const e = new Date(end);
  if (s.getUTCMonth() === e.getUTCMonth() && s.getUTCFullYear() === e.getUTCFullYear()) {
    return `${s.getUTCDate()}–${e.getUTCDate()} ${months[s.getUTCMonth()]} ${s.getUTCFullYear()}`;
  }
  return `${s.getUTCDate()} ${months[s.getUTCMonth()]} – ${e.getUTCDate()} ${months[e.getUTCMonth()]} ${e.getUTCFullYear()}`;
}
