import * as React from "react";

import * as countries from "i18n-iso-countries";
// @ts-ignore
countries.registerLocale(require("i18n-iso-countries/langs/fr.json"));

import { AuthorsAPA } from "./Author";
import { Notice, NoticeTypeContext } from "../../Notice";
import { Separator, Dot } from "../../common/Separator";
import Italic from "../../common/Italic";

export const renderedGroups = ["OUV", "COUV", "ART", "COMM", "DOUV", "POSTER", "THESE", "HDR"];

const Title: React.FC<{
  title: string;
  bookTitle?: string;
  journalTitle?: string;
  conferenceTitle?: string;
}> = ({ title, bookTitle, journalTitle, conferenceTitle }) => {
  if (title.length === 0) {
    return <></>;
  }
  if (!bookTitle && !journalTitle && !conferenceTitle) {
    return (
      <>
        <Italic>{title}</Italic>
        <Dot />
      </>
    );
  }
  return (
    <span>
      {title}
      <Dot />
    </span>
  );
};

const BookTitleAndScientificEditorAndPage: React.FC<{
  bookTitle: string | undefined;
  journalTitle: string | undefined;
  conferenceTitle: string | undefined;
  scientificEditor: string | undefined;
  page: string | undefined;
}> = ({ bookTitle, journalTitle, conferenceTitle, scientificEditor, page }) => {
  const { noticeType } = React.useContext(NoticeTypeContext);
  if (
    !(
      noticeType === "COUV" ||
      (bookTitle !== undefined &&
        journalTitle === undefined &&
        conferenceTitle === undefined &&
        (noticeType === "DEFAULT" || noticeType === "DOUV"))
    )
  ) {
    return <></>;
  }
  const ret: JSX.Element[] = [];
  ret.push(
    <>
      <Italic> in </Italic>
    </>
  );
  if (scientificEditor !== undefined) {
    ret.push(
      <>
        {scientificEditor} (dir.)
        <Separator />
      </>
    );
  }
  if (bookTitle !== undefined) {
    ret.push(
      <>
        <Italic>{bookTitle}</Italic>
      </>
    );
  }
  if (page !== undefined) {
    ret.push(<> (p. {page})</>);
  }
  ret.push(
    <>
      <Dot />
    </>
  );
  return (
    <>
      {ret.map((val, i) => (
        <span key={i}>{val}</span>
      ))}
    </>
  );
};

const JournalTitleAndVolumeAndIssueAndPage: React.FC<{
  journalTitle: string | undefined;
  volume: string | undefined;
  issue: string | undefined;
  page: string | undefined;
  otherType: string | undefined;
}> = ({ journalTitle, volume, issue, page, otherType }) => {
  const { noticeType } = React.useContext(NoticeTypeContext);
  if (!(noticeType === "ART" || (journalTitle !== undefined && (noticeType === "DEFAULT" || noticeType === "DOUV")))) {
    return <></>;
  }
  const ret: JSX.Element[] = [];
  const separator = !volume && !issue && !page ? <></> : <Separator />;
  ret.push(
    <>
      <Italic>{journalTitle}</Italic>
      {separator}
    </>
  );
  if (volume !== undefined) {
    ret.push(
      <>
        <Italic>{volume}</Italic>
      </>
    );
  }
  if (issue !== undefined) {
    ret.push(<>({issue})</>);
  }

  if (page !== undefined) {
    const separator = volume || issue ? <Separator /> : <></>;
    ret.push(<>{separator}</>);

    if (!otherType || otherType != "1") {
      ret.push(<>p. {page}</>);
    }
  }
  ret.push(
    <>
      <Dot />
    </>
  );
  return (
    <>
      {ret.map((val, i) => (
        <span key={i}>{val}</span>
      ))}
    </>
  );
};

const AuthorityInstitution: React.FC<{ authorityInstitution: string | undefined }> = ({ authorityInstitution }) => {
  const { noticeType } = React.useContext(NoticeTypeContext);
  if ((noticeType !== "THESE" && noticeType !== "HDR") || authorityInstitution === undefined) {
    return <></>;
  }
  return <>{authorityInstitution}</>;
};

const ConferenceTitleAndPage: React.FC<{
  journalTitle: string | undefined;
  scientificEditor: string | undefined;
  conferenceTitle: string | undefined;
  page: string | undefined;
}> = ({ journalTitle, scientificEditor, conferenceTitle, page }) => {
  const { noticeType } = React.useContext(NoticeTypeContext);
  if (
    !(
      noticeType === "COMM" ||
      noticeType === "POSTER" ||
      (noticeType === "DEFAULT" && conferenceTitle !== undefined && journalTitle === undefined)
    )
  ) {
    return <></>;
  }
  const ret: JSX.Element[] = [];
  ret.push(<>{"Dans "}</>);

  if (scientificEditor !== undefined) {
    ret.push(
      <>
        {scientificEditor} (dir.)
        <Separator />
      </>
    );
  }
  if (conferenceTitle !== undefined) {
    ret.push(
      <>
        <Italic>{conferenceTitle}</Italic>
      </>
    );
  }
  if (page !== undefined) {
    ret.push(
      <>
        {conferenceTitle ? <Separator /> : <></>} (p. {page})
      </>
    );
  }
  if (ret.length <= 1) {
    return <></>;
  }
  ret.push(
    <>
      <Dot />
    </>
  );
  return (
    <>
      {ret.map((val, i) => (
        <span key={i}>{val}</span>
      ))}
    </>
  );
};

const LocationAndPublisher: React.FC<{
  journalTitle: string | undefined;
  publicationLocation: string | undefined;
  city: string | undefined;
  country: string | undefined;
  publisher: string | undefined;
}> = ({ journalTitle, publicationLocation, city, country, publisher }) => {
  const { noticeType } = React.useContext(NoticeTypeContext);
  if (!((noticeType === "DOUV" && journalTitle === undefined) || noticeType !== "ART")) {
    return <></>;
  }
  const ret: JSX.Element[] = [];
  if (city !== undefined) {
    ret.push(<>{city}</>);
  } else if (publicationLocation !== undefined) {
    ret.push(<>{publicationLocation}</>);
  }

  if (country !== undefined) {
    ret.push(
      <>
        {city || publicationLocation ? <Separator /> : <></>}
        {countries.getName(country, "fr", { select: "official" })}
      </>
    );
  }
  if (publisher !== undefined) {
    const displaySeparator = city || publicationLocation || country;
    ret.push(
      <>
        {displaySeparator ? " : " : <></>}
        {publisher}
      </>
    );
  }
  if (ret.length > 0) {
    ret.push(
      <>
        <Dot />
      </>
    );
  }
  return (
    <>
      {ret.map((val, i) => (
        <span key={i}>{val}</span>
      ))}
    </>
  );
};

const Date: React.FC<{ date: string | undefined }> = ({ date }) => {
  return (
    <span>
      ({date ?? "s. d."})<Dot />
    </span>
  );
};

export const APANotice: React.FC<Notice> = (notice) => {
  return (
    <>
      <AuthorsAPA authLastName_s={notice.authLastName_s} authFirstName_s={notice.authFirstName_s} />{" "}
      <Date date={notice.producedDateY_i} />
      <Title
        title={notice.title_s}
        bookTitle={notice.bookTitle_s}
        journalTitle={notice.journalTitle_s}
        conferenceTitle={notice.conferenceTitle_s}
      />
      <BookTitleAndScientificEditorAndPage
        bookTitle={notice.bookTitle_s}
        journalTitle={notice.journalTitle_s}
        conferenceTitle={notice.conferenceTitle_s}
        scientificEditor={notice.scientificEditor_s}
        page={notice.page_s}
      />
      <JournalTitleAndVolumeAndIssueAndPage
        journalTitle={notice.journalTitle_s}
        volume={notice.volume_s}
        issue={notice.issue_s}
        page={notice.page_s}
        otherType={notice.otherType_s}
      />
      <AuthorityInstitution authorityInstitution={notice.authorityInstitution_s} />
      <ConferenceTitleAndPage
        journalTitle={notice.journalTitle_s}
        scientificEditor={notice.scientificEditor_s}
        conferenceTitle={notice.conferenceTitle_s}
        page={notice.page_s}
      />
      <LocationAndPublisher
        journalTitle={notice.journalTitle_s}
        publicationLocation={notice.publicationLocation_s}
        city={notice.city_s}
        country={notice.country_s}
        publisher={notice.publisher_s}
      />
    </>
  );
};
