// src/metadata/generatePageMetadata.ts
function generatePageMetadata(input) {
  const { page, site, path, siteUrl, overrides, googleSiteVerification, titleMode = "append-site-title" } = input;
  const pageTitle = overrides?.title ?? page.name;
  const fullTitle = titleMode === "exact" || pageTitle === site.title ? pageTitle : `${pageTitle} | ${site.title}`;
  const description = overrides?.description ?? page.purpose;
  const canonicalUrl = siteUrl ? overrides?.canonicalUrl ?? `${siteUrl}${path}` : void 0;
  const openGraphUrl = canonicalUrl;
  const metadata = {
    title: fullTitle,
    description: description ?? void 0,
    ...canonicalUrl ? {
      alternates: {
        canonical: canonicalUrl
      }
    } : {},
    openGraph: {
      title: pageTitle,
      description: description ?? void 0,
      ...openGraphUrl ? { url: openGraphUrl } : {},
      siteName: site.title,
      type: "website",
      ...overrides?.ogImage ? {
        images: [
          {
            url: overrides.ogImage,
            alt: pageTitle
          }
        ]
      } : {}
    },
    twitter: {
      card: "summary_large_image",
      title: pageTitle,
      description: description ?? void 0,
      ...overrides?.ogImage ? {
        images: [overrides.ogImage]
      } : {}
    }
  };
  if (overrides?.robots) {
    metadata.robots = {
      index: overrides.robots.index ?? true,
      follow: overrides.robots.follow ?? true
    };
  }
  if (googleSiteVerification) {
    metadata.verification = {
      google: googleSiteVerification
    };
  }
  return metadata;
}
function generatePreviewMetadata(input) {
  return generatePageMetadata({
    ...input,
    overrides: {
      ...input.overrides,
      robots: {
        index: false,
        follow: false
      }
    }
  });
}

// src/metadata/schema.ts
function toAbsoluteUrl(value) {
  if (typeof value !== "string") return null;
  const trimmed = value.trim();
  if (/^https?:\/\/.+/i.test(trimmed)) {
    return trimmed;
  }
  return null;
}
function toIsoDateTime(value) {
  if (typeof value !== "string" || value.trim().length === 0) return null;
  const timestamp = Date.parse(value);
  if (!Number.isFinite(timestamp)) return null;
  return value;
}
function toCurrencyCode(value) {
  if (typeof value !== "string") return null;
  const trimmed = value.trim().toUpperCase();
  if (/^[A-Z]{3}$/.test(trimmed)) {
    return trimmed;
  }
  return null;
}
function deriveSchemaNodes(subject) {
  switch (subject.kind) {
    case "website":
      return [toWebSiteNode(subject)];
    case "webpage":
      return [toWebPageNode(subject), ...toBreadcrumbNodes(subject.breadcrumbs)];
    case "article":
      return [
        toWebPageNode(subject),
        toArticleNode(subject),
        ...toBreadcrumbNodes(subject.breadcrumbs)
      ];
    case "event":
      return [
        toWebPageNode(subject),
        toEventNode(subject),
        ...toBreadcrumbNodes(subject.breadcrumbs)
      ];
    case "product":
      return [
        toWebPageNode(subject),
        toProductNode(subject),
        ...toBreadcrumbNodes(subject.breadcrumbs)
      ];
  }
}
function toWebSiteNode(subject) {
  return {
    "@context": "https://schema.org",
    "@type": "WebSite",
    name: subject.site.name,
    url: subject.site.url
  };
}
function toWebPageNode(subject) {
  return {
    "@context": "https://schema.org",
    "@type": "WebPage",
    name: subject.page.title,
    url: subject.page.url,
    ...subject.page.description ? { description: subject.page.description } : {},
    isPartOf: {
      "@type": "WebSite",
      name: subject.site.name,
      url: subject.site.url
    }
  };
}
function toBreadcrumbNodes(breadcrumbs) {
  if (!breadcrumbs || breadcrumbs.length < 2) return [];
  return [
    {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      itemListElement: breadcrumbs.map((breadcrumb, index) => ({
        "@type": "ListItem",
        position: index + 1,
        name: breadcrumb.name,
        ...breadcrumb.url ? { item: breadcrumb.url } : {}
      }))
    }
  ];
}
function toArticleNode(subject) {
  return {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: subject.article.headline,
    mainEntityOfPage: subject.page.url,
    url: subject.page.url,
    datePublished: subject.article.publishedAt,
    ...subject.article.modifiedAt ? { dateModified: subject.article.modifiedAt } : {},
    ...subject.article.description ? { description: subject.article.description } : {},
    ...subject.article.imageUrls?.length ? { image: subject.article.imageUrls } : {},
    author: {
      "@type": "Organization",
      name: subject.article.authorName
    },
    publisher: {
      "@type": "Organization",
      name: subject.site.name,
      url: subject.site.url
    }
  };
}
function toEventNode(subject) {
  return {
    "@context": "https://schema.org",
    "@type": "Event",
    name: subject.event.name,
    url: subject.page.url,
    startDate: subject.event.startDate,
    ...subject.event.endDate ? { endDate: subject.event.endDate } : {},
    ...subject.event.description ? { description: subject.event.description } : {},
    ...subject.event.imageUrls?.length ? { image: subject.event.imageUrls } : {},
    location: {
      "@type": "Place",
      name: subject.event.locationName,
      ...subject.event.locationAddress ? { address: subject.event.locationAddress } : {}
    },
    ...subject.event.offer ? {
      offers: {
        "@type": "Offer",
        price: subject.event.offer.price,
        priceCurrency: subject.event.offer.currency,
        availability: subject.event.offer.availability,
        url: subject.page.url
      }
    } : {}
  };
}
function toProductNode(subject) {
  return {
    "@context": "https://schema.org",
    "@type": "Product",
    name: subject.product.name,
    url: subject.page.url,
    ...subject.product.description ? { description: subject.product.description } : {},
    image: subject.product.imageUrls,
    offers: {
      "@type": "Offer",
      price: subject.product.offer.price,
      priceCurrency: subject.product.offer.currency,
      availability: subject.product.offer.availability,
      url: subject.page.url
    }
  };
}
export {
  deriveSchemaNodes,
  generatePageMetadata,
  generatePreviewMetadata,
  toAbsoluteUrl,
  toCurrencyCode,
  toIsoDateTime
};
