---
import OpenGraphArticleTags from "./components/OpenGraphArticleTags.astro";
import OpenGraphBasicTags from "./components/OpenGraphBasicTags.astro";
import OpenGraphImageTags from "./components/OpenGraphImageTags.astro";
import OpenGraphOptionalTags from "./components/OpenGraphOptionalTags.astro";
import ExtendedTags from "./components/ExtendedTags.astro";
import TwitterTags from "./components/TwitterTags.astro";
import LanguageAlternatesTags from "./components/LanguageAlternatesTags.astro";

export type TwitterCardType = "summary" | "summary_large_image" | "app" | "player";

export interface Link extends Omit<HTMLLinkElement, 'sizes'> {
  prefetch: boolean;
  crossorigin: string;
  sizes: string;
}

export interface Meta extends HTMLMetaElement {
  property: string;
}

export interface Props {
  title?: string;
  titleTemplate?: string;
  titleDefault?: string;
  charset?: string;
  description?: string;
  canonical?: URL | string;
  nofollow?: boolean;
  noindex?: boolean;
  languageAlternates?: {
    href: URL | string;
    hrefLang: string;
  }[];
  openGraph?: {
    basic: {
      title: string;
      type: string;
      image: string;
      url?: URL | string;
    };
    optional?: {
      audio?: string;
      description?: string;
      determiner?: string;
      locale?: string;
      localeAlternate?: string[];
      siteName?: string;
      video?: string;
    };
    image?: {
      url?: URL | string;
      secureUrl?: URL | string;
      type?: string;
      width?: number;
      height?: number;
      alt?: string;
    };
    article?: {
      publishedTime?: string;
      modifiedTime?: string;
      expirationTime?: string;
      authors?: string[];
      section?: string;
      tags?: string[];
    };
  };
  twitter?: {
    card?: TwitterCardType;
    site?: string;
    creator?: string;
    title?: string;
    description?: string;
    image?: URL | string;
    imageAlt?: string;
  };
  extend?: {
    link?: Partial<Link>[];
    meta?: Partial<Meta>[];
  };
  surpressWarnings?: boolean;
}

Astro.props.surpressWarnings = true;

function validateProps(props: Props) {
  if (props.openGraph) {
    if (
      !props.openGraph.basic ||
      (props.openGraph.basic.title ?? undefined) == undefined ||
      (props.openGraph.basic.type ?? undefined) == undefined ||
      (props.openGraph.basic.image ?? undefined) == undefined
    ) {
      throw new Error(
        "If you pass the openGraph prop, you have to at least define the title, type, and image basic properties!"
      );
    }
  }

  if (props.title && props.openGraph?.basic.title) {
    if (props.title == props.openGraph.basic.title && !props.surpressWarnings) {
      console.warn(
        "WARNING(astro-seo): You passed the same value to `title` and `openGraph.optional.title`. This is most likely not what you want. See docs for more."
      );
    }
  }

  if (
    props.openGraph?.basic?.image &&
    !props.openGraph?.image?.alt &&
    !props.surpressWarnings
  ) {
    console.warn(
      "WARNING(astro-seo): You defined `openGraph.basic.image`, but didn't define `openGraph.image.alt`. This is strongly discouraged.'"
    );
  }
}

validateProps(Astro.props);

let updatedTitle = "";

if (Astro.props.title) {
  updatedTitle = Astro.props.title;
  if (Astro.props.titleTemplate) {
    updatedTitle = Astro.props.titleTemplate.replace(/%s/g, updatedTitle);
  }
} else if (Astro.props.titleDefault) {
  updatedTitle = Astro.props.titleDefault;
}

const baseUrl = Astro.site ?? Astro.url;
const defaultCanonicalUrl = new URL(Astro.url.pathname + Astro.url.search, baseUrl);
---

{updatedTitle ? <title set:html={updatedTitle} /> : null}

{Astro.props.charset ? <meta charset={Astro.props.charset} /> : null}

<link rel="canonical" href={Astro.props.canonical || defaultCanonicalUrl.href} />

{
  Astro.props.description ? (
    <meta name="description" content={Astro.props.description} />
  ) : null
}

<meta
  name="robots"
  content={`${Astro.props.noindex ? "noindex" : "index"}, ${
    Astro.props.nofollow ? "nofollow" : "follow"
  }`}
/>

{Astro.props.openGraph && <OpenGraphBasicTags {...Astro.props} />}
{Astro.props.openGraph?.optional && <OpenGraphOptionalTags {...Astro.props} />}
{Astro.props.openGraph?.image && <OpenGraphImageTags {...Astro.props} />}
{Astro.props.openGraph?.article && <OpenGraphArticleTags {...Astro.props} />}
{Astro.props.twitter && <TwitterTags {...Astro.props} />}
{Astro.props.extend && <ExtendedTags {...Astro.props} />}
{Astro.props.languageAlternates && <LanguageAlternatesTags {...Astro.props} />}
