import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
import { createPopularPostsPageURL } from "#lib/urls";
import { parseOffset } from "#lib/pagination";
import { fetchPopularPosts } from "#api/posts";
import { PageSkeleton } from "#components/pages";
import { Paginator } from "#components/pagination";
import { FooterAd, HeaderAd, SliderAd } from "#components/ads";
import { CardList, PostFavoriteCard } from "#components/cards";
import {
  IPopularPostsPeriod,
  IPostWithFavorites,
  validatePeriod,
} from "#entities/posts";

interface IProps {
  minDate: string;
  maxDate: string;
  rangeDescription: string;
  earliestDateForPopular: string;
  navigationDates: Record<IPopularPostsPeriod, [string, string, string]>;
  scale?: IPopularPostsPeriod;
  today: string;
  count: number;
  posts: IPostWithFavorites[];
  offset?: number;
  date?: string;
}

export function PopularPostsPage() {
  const {
    minDate,
    maxDate,
    rangeDescription,
    navigationDates,
    earliestDateForPopular,
    scale,
    today,
    count,
    offset,
    date,
    posts,
  } = useLoaderData() as IProps;
  const title = `Popular posts for ${rangeDescription}`;

  return (
    <PageSkeleton
      name="popular-posts"
      title={title}
      heading={
        <>
          Popular Posts for{" "}
          <span title={`${minDate} to ${maxDate}`}>{rangeDescription}</span>
        </>
      }
    >
      <SliderAd />

      <div className="paginator" id="paginator-dates">
        <div id="daily">
          <span>
            {navigationDates.day[0] < earliestDateForPopular ? (
              <span>next »</span>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.day[0], "day")
                )}
              >
                « prev
              </a>
            )}
          </span>{" "}

          <span>
            {scale === "day" ? (
              <strong>Day</strong>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.day[2], "day")
                )}
              >
                Day
              </a>
            )}
          </span>{" "}

          <span>
            {navigationDates.day[1] > today ? (
              <span>next »</span>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.day[1], "day")
                )}
              >
                next »
              </a>
            )}
          </span>
        </div>

        <div id="weekly">
          <span>
            {navigationDates.week[0] < earliestDateForPopular ? (
              <span>next »</span>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.week[0], "week")
                )}
              >
                « prev
              </a>
            )}
          </span>{" "}

          <span>
            {scale === "week" ? (
              <strong>Week</strong>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.week[2], "week")
                )}
              >
                Week
              </a>
            )}
          </span>{" "}

          <span>
            {navigationDates.week[1] > today ? (
              <span>next »</span>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.week[1], "week")
                )}
              >
                next »
              </a>
            )}
          </span>
        </div>

        <div id="monthly">
          <span>
            {navigationDates.month[0] < earliestDateForPopular ? (
              <span>next »</span>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.month[0], "month")
                )}
              >
                « prev
              </a>
            )}
          </span>{" "}

          <span>
            {scale === "month" ? (
              <strong>Month</strong>
            ) : (
              <a
                href={String(
                  createPopularPostsPageURL(navigationDates.month[2], "month")
                )}
              >
                Month
              </a>
            )}
          </span>{" "}

          <span>
            <span>
              {navigationDates.month[1] > today ? (
                <span>next »</span>
              ) : (
                <a
                  href={String(
                    createPopularPostsPageURL(navigationDates.month[1], "month")
                  )}
                >
                  next »
                </a>
              )}
            </span>
          </span>
        </div>

        <div className="paginator" id="paginator-top">
          <Paginator
            count={count}
            offset={offset}
            constructURL={(offset) =>
              String(createPopularPostsPageURL(date, scale, offset))
            }
          />

          <HeaderAd />

          <CardList>
            {count === 0 ? (
              <div className="card-list__item--no-results">
                <h2 className="subtitle">Nobody here but us chickens!</h2>
                <p className="subtitle">There are no posts for your query.</p>
              </div>
            ) : (
              posts.map((post) => (
                <PostFavoriteCard
                  key={`${post.id}-${post.service}`}
                  post={post}
                />
              ))
            )}
          </CardList>

          <FooterAd />

          <div className="paginator" id="paginator-bottom">
            <Paginator
              count={count}
              offset={offset}
              constructURL={(offset) =>
                String(createPopularPostsPageURL(date, scale, offset))
              }
            />
          </div>
        </div>
      </div>
    </PageSkeleton>
  );
}

export async function loader({ request }: LoaderFunctionArgs): Promise<IProps> {
  const searchParams = new URL(request.url).searchParams;

  const date = searchParams.get("date")?.trim();

  const scale = searchParams.get("period")?.trim() ?? "recent";
  validatePeriod(scale);

  let offset: number | undefined;
  {
    const inputOffset = searchParams.get("o")?.trim();

    if (inputOffset) {
      offset = parseOffset(inputOffset);
    }
  }

  const { info, props, results } = await fetchPopularPosts(date, scale, offset);
  const { count, earliest_date_for_popular, today } = props;
  const { range_desc, min_date, max_date, navigation_dates } = info;

  return {
    date,
    count,
    scale,
    offset,
    posts: results,
    today,
    earliestDateForPopular: earliest_date_for_popular,
    rangeDescription: range_desc,
    minDate: min_date,
    maxDate: max_date,
    navigationDates: navigation_dates,
  };
}
