import { ParsedUrlQuery } from "querystring";

import { GetStaticPaths, GetStaticProps } from "next";
import { MDXRemote } from "next-mdx-remote";
import React from "react";

import { EventCard } from "@/components/EventCard";
import { Link } from "@/components/Link";
import { MiniEventCard } from "@/components/MiniEventCard";
import {
  Event,
  getEventsPageProps,
  getEventYears,
  getEventTermsByYear,
} from "@/lib/events";
import { capitalize } from "@/utils";

import styles from "./index.module.css";

export interface Props {
  year: string;
  term: string;
  pastEvents: Event[];
  futureEvents: Event[];
  isCurrentTerm: boolean;
  pastTerms: { year: string; term: string }[];
  futureTerms: { year: string; term: string }[];
}

export default function Term(props: Props) {
  let headerTerms = [{ year: props.year, term: props.term }];

  // p, Current, f
  if (props.pastTerms.length > 0 && props.futureTerms.length > 0) {
    headerTerms = [
      ...props.pastTerms.slice(-1),
      ...headerTerms,
      ...props.futureTerms.slice(0, 1),
    ];
  }
  // p, p, Current
  else if (props.pastTerms.length > 0) {
    headerTerms = [...props.pastTerms.slice(-2), ...headerTerms];
  }
  // Current, f, f
  else {
    headerTerms = [...headerTerms, ...props.futureTerms.slice(0, 2)];
  }

  headerTerms.reverse();

  const hasPastEvents = props.pastEvents.length !== 0;
  const hasFutureEvents = props.futureEvents.length !== 0;

  return (
    <div className={styles.main}>
      <div className={styles.header}>
        {headerTerms.map((link) => (
          <HeaderLink
            {...link}
            isCurrentTerm={link.year === props.year && link.term === props.term}
            key={link.year + link.term}
          />
        ))}
        <Link href="/events/archive">Archive</Link>
      </div>
      {hasFutureEvents && (
        <>
          <h1>Upcoming Events</h1>
          <div className={styles.miniEventCards}>
            {props.futureEvents.map(({ content, metadata }) => (
              <EventCard
                {...metadata}
                date={new Date(metadata.date)}
                key={metadata.name + metadata.date.toString()}
                link={`/events/${props.year}/${props.term}/${metadata.slug}`}
              >
                <MDXRemote {...content} />
              </EventCard>
            ))}
          </div>
        </>
      )}
      {hasPastEvents && props.isCurrentTerm && <h2>Past Events</h2>}
      {hasPastEvents && !props.isCurrentTerm && (
        <h1>
          Events Archive:
          <span className={styles.blue}>
            {` ${capitalize(props.term)} ${props.year}`}
          </span>
        </h1>
      )}
      {!hasFutureEvents && !hasPastEvents && (
        <>
          <h1>Events</h1>
          There are no upcoming or past events for the{" "}
          {`${capitalize(props.term)} ${props.year}`} term. Please check back
          later!
        </>
      )}
      <div className={styles.miniEventCards}>
        {props.pastEvents.map(({ content, metadata }) => (
          <MiniEventCard
            {...metadata}
            date={new Date(metadata.date)}
            description={<MDXRemote {...content} />}
            key={metadata.name + metadata.date.toString()}
          />
        ))}
      </div>
    </div>
  );
}

function HeaderLink(props: {
  year: string;
  term: string;
  isCurrentTerm?: boolean;
}) {
  return (
    <Link href={`/events/${props.year}/${props.term}`}>
      <span className={props.isCurrentTerm ? styles.curTerm : ""}>
        {`${capitalize(props.term)} ${props.year}`}
      </span>
    </Link>
  );
}

interface Params extends ParsedUrlQuery {
  year: string;
  term: string;
}

export const getStaticProps: GetStaticProps<Props, Params> = async (
  context
) => {
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  return { props: await getEventsPageProps(context.params!) };
};

export const getStaticPaths: GetStaticPaths<Params> = async () => {
  const years = await getEventYears();
  const paths = (
    await Promise.all(
      years.map(async (year) => {
        const terms = await getEventTermsByYear(year);
        return terms.map((curTerm) => ({
          params: { year: year, term: curTerm },
        }));
      })
    )
  ).flat();

  return {
    paths: paths,
    fallback: false,
  };
};
