/**
 * Copyright (C) 2019-2021 Carl Kittelberger <icedream@icedream.pw>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import * as React from 'react';

import { Breadcrumb } from 'react-bootstrap';

import Head from 'next/head';
import Link from 'next/link';

import { useIntl } from 'react-intl';
import { GetServerSideProps, NextPage } from 'next';
import { RunnerList } from 'util/datatypes/RunnerList';
import { FormattedMessage } from '../components/localization';

import RelativeTime from '../components/RelativeTime';
import VideoList from '../components/VideoList';

import { notFound } from '../util/status';
import { getIndex, getRunners, getVideos } from '../util/api';
import { VideoEntry } from '../util/datatypes/VideoList';

interface VideoListPageProps {
  id?: string,
  lastUpdatedAt?: string,
  thumbnailServerURL?: string,
  title?: string,
  videos?: Array<VideoEntry>,
  runners?: RunnerList,
}

export const getServerSideProps: GetServerSideProps<VideoListPageProps> = async ({
  params: { id },
}) => {
  // Fetch URL to thumbnails server
  const {
    ids,
    servers: { thumbnails: thumbnailServerURL },
  } = await getIndex();

  const runners = await getRunners();

  const vodMeta = ids.find(({
    id: thisID,
  }: {
    id: string
  }) => id === thisID);

  if (!vodMeta) {
    return {
      props: {},
    };
  }

  const { title } = vodMeta;

  const requestedID = typeof id === 'string' ? id : id[0];

  // Fetch list of videos for this VOD ID
  const vodInfo = await getVideos(requestedID);
  const { videos } = vodInfo;
  let lastUpdatedAt = null;
  lastUpdatedAt = vodInfo.lastUpdatedAt;
  const finalVideos: VideoEntry[] = videos
    .map((video: VideoEntry) => ({
      ...video,
      duration: typeof video.duration === 'string' ? parseFloat(video.duration) : video.duration || null,
      sourceVideoStart: typeof video.sourceVideoStart === 'string' ? parseFloat(video.sourceVideoStart) : video.sourceVideoStart || null,
      sourceVideoEnd: typeof video.sourceVideoEnd === 'string' ? parseFloat(video.sourceVideoEnd) : video.sourceVideoEnd || null,
    }));

  // Pass data to the page via props
  return {
    props: {
      id: requestedID,
      thumbnailServerURL,
      title,
      videos: finalVideos,
      lastUpdatedAt,
      runners,
    },
  };
};

const VideoListPage: NextPage<VideoListPageProps> = function VideoListPage({
  id,
  lastUpdatedAt,
  thumbnailServerURL,
  title,
  videos,
  runners,
}) {
  if (!id) {
    return notFound();
  }

  let lastUpdatedDate = null;
  if (typeof (lastUpdatedAt) === 'string') {
    lastUpdatedDate = new Date(lastUpdatedAt);
  }

  const intl = useIntl();

  return (
    <div>
      <Head>
        <title>
          {`${title} – ${intl.formatMessage({
            id: 'App.title',
            description: 'The full title of the website',
            defaultMessage: 'Games Done Quick Instant Archive',
          })}`}
        </title>
      </Head>

      <Breadcrumb>
        <Link passHref href="/">
          <Breadcrumb.Item>
            <FormattedMessage
              id="Breadcrumb.homeTitle"
              defaultMessage="GDQ Instant Archive"
              description="Root node text in breadcrumb"
            />
          </Breadcrumb.Item>
        </Link>
        <Link passHref href="/[id]" as={`/${id}`}>
          <Breadcrumb.Item active>
            {title}
          </Breadcrumb.Item>
        </Link>
      </Breadcrumb>

      <VideoList
        id={id}
        runners={runners}
        thumbnailServerURL={thumbnailServerURL}
        videos={videos}
      />

      {
        lastUpdatedDate
          ? (
            <footer className="pt-4 my-md-5 pt-md-5 border-top">
              <FormattedMessage
                id="VideoListPage.updatedLastAgo"
                description="Text below the video list on the video list page that says in relative time when the list was last updated"
                defaultMessage="Updated last {time}"
                values={{
                  time: (
                    <RelativeTime>
                      {lastUpdatedDate}
                    </RelativeTime>
                  ),
                }}
              />
            </footer>
          )
          : ''
      }
    </div>
  );
};

export default VideoListPage;
