import type { Metadata, MetadataRoute } from "next"
import siteData from "@/data/site.json"

type SiteSeoConfig = {
  siteUrl: string
  siteName: string
  defaultTitle: string
  titleTemplate: string
  description: string
  keywords: string[]
  canonicalPath: string
  locale?: string
  robots?: {
    index?: boolean
    follow?: boolean
  }
  openGraph?: {
    type?: "website" | "article"
    image?: string
  }
  twitter?: {
    card?: "summary" | "summary_large_image" | "app" | "player"
    site?: string
    creator?: string
  }
  verification?: {
    google?: string
    yandex?: string
    other?: Record<string, string>
  }
}

const seo = siteData.seo as SiteSeoConfig

function nonEmpty(value?: string) {
  if (!value) {
    return undefined
  }

  const trimmed = value.trim()

  return trimmed ? trimmed : undefined
}

function getMetadataBase() {
  return new URL(seo.siteUrl)
}

function getCanonicalPath() {
  return nonEmpty(seo.canonicalPath) ?? "/"
}

function getVerificationOther() {
  const otherEntries = Object.entries(seo.verification?.other ?? {}).filter(([, value]) => Boolean(nonEmpty(value)))

  return otherEntries.length > 0 ? Object.fromEntries(otherEntries) : undefined
}

function getOpenGraphImages() {
  const image = nonEmpty(seo.openGraph?.image)

  return image ? [{ url: image }] : undefined
}

export function buildSiteMetadata(): Metadata {
  const index = seo.robots?.index ?? true
  const follow = seo.robots?.follow ?? true
  const verificationOther = getVerificationOther()
  const canonicalPath = getCanonicalPath()
  const openGraphImages = getOpenGraphImages()

  return {
    metadataBase: getMetadataBase(),
    applicationName: seo.siteName,
    title: {
      default: seo.defaultTitle,
      template: seo.titleTemplate,
    },
    description: seo.description,
    keywords: seo.keywords,
    authors: [{ name: siteData.company.name }],
    creator: siteData.company.name,
    publisher: siteData.company.name,
    alternates: {
      canonical: canonicalPath,
    },
    robots: {
      index,
      follow,
      googleBot: {
        index,
        follow,
      },
    },
    verification: {
      google: nonEmpty(seo.verification?.google),
      yandex: nonEmpty(seo.verification?.yandex),
      other: verificationOther,
    },
    openGraph: {
      title: seo.defaultTitle,
      description: seo.description,
      url: canonicalPath,
      siteName: seo.siteName,
      locale: nonEmpty(seo.locale),
      type: seo.openGraph?.type ?? "website",
      images: openGraphImages,
    },
    twitter: {
      card: seo.twitter?.card ?? "summary_large_image",
      title: seo.defaultTitle,
      description: seo.description,
      images: openGraphImages?.map((image) => image.url),
      site: nonEmpty(seo.twitter?.site),
      creator: nonEmpty(seo.twitter?.creator),
    },
  }
}

export function buildRobots(): MetadataRoute.Robots {
  return {
    rules: [
      {
        userAgent: "*",
        allow: "/",
      },
    ],
    sitemap: `${seo.siteUrl.replace(/\/$/, "")}/sitemap.xml`,
    host: seo.siteUrl,
  }
}

export function buildSitemap(): MetadataRoute.Sitemap {
  const canonicalPath = getCanonicalPath()
  const normalizedSiteUrl = seo.siteUrl.replace(/\/$/, "")

  return [
    {
      url: `${normalizedSiteUrl}${canonicalPath}`,
      lastModified: new Date(),
      changeFrequency: "weekly",
      priority: 1,
    },
  ]
}
