/**
 * Structured Data (JSON-LD) Helpers
 *
 * Diese Funktionen generieren Schema.org-konforme JSON-LD Daten
 * für verschiedene Content-Typen.
 *
 * Verwendung in Next.js:
 * ```tsx
 * import { generateArticleSchema } from '@/lib/structuredData'
 *
 * export default function BlogPost({ post }) {
 *   return (
 *     <>
 *       <script
 *         type="application/ld+json"
 *         dangerouslySetInnerHTML={{
 *           __html: JSON.stringify(generateArticleSchema(post))
 *         }}
 *       />
 *       <article>...</article>
 *     </>
 *   )
 * }
 * ```
 */

export interface OrganizationData {
  name: string
  url: string
  logo?: string
  description?: string
  email?: string
  phone?: string
  address?: {
    street?: string
    city?: string
    postalCode?: string
    country?: string
  }
  socialProfiles?: string[]
}

export interface ArticleData {
  title: string
  description?: string
  slug: string
  publishedAt?: string
  updatedAt?: string
  author?: string
  featuredImage?: {
    url?: string
    alt?: string
    width?: number
    height?: number
  }
  categories?: string[]
}

export interface WebPageData {
  title: string
  description?: string
  url: string
  updatedAt?: string
  image?: {
    url?: string
    alt?: string
  }
}

export interface BreadcrumbItem {
  name: string
  url: string
}

export interface FAQItem {
  question: string
  answer: string
}

export interface TestimonialData {
  author: string
  quote: string
  rating?: number
  company?: string
  date?: string
}

/**
 * Generiert Organization Schema
 */
export function generateOrganizationSchema(data: OrganizationData) {
  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': 'Organization',
    name: data.name,
    url: data.url,
  }

  if (data.logo) {
    schema.logo = {
      '@type': 'ImageObject',
      url: data.logo,
    }
  }

  if (data.description) {
    schema.description = data.description
  }

  if (data.email) {
    schema.email = data.email
  }

  if (data.phone) {
    schema.telephone = data.phone
  }

  if (data.address) {
    schema.address = {
      '@type': 'PostalAddress',
      streetAddress: data.address.street,
      addressLocality: data.address.city,
      postalCode: data.address.postalCode,
      addressCountry: data.address.country || 'DE',
    }
  }

  if (data.socialProfiles && data.socialProfiles.length > 0) {
    schema.sameAs = data.socialProfiles
  }

  return schema
}

/**
 * Generiert Article Schema für Blog-Posts und News
 */
export function generateArticleSchema(
  data: ArticleData,
  baseUrl: string,
  organization?: OrganizationData
) {
  const articleUrl = `${baseUrl}/blog/${data.slug}`

  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: data.title,
    url: articleUrl,
    mainEntityOfPage: {
      '@type': 'WebPage',
      '@id': articleUrl,
    },
  }

  if (data.description) {
    schema.description = data.description
  }

  if (data.publishedAt) {
    schema.datePublished = data.publishedAt
  }

  if (data.updatedAt) {
    schema.dateModified = data.updatedAt
  }

  if (data.author) {
    schema.author = {
      '@type': 'Person',
      name: data.author,
    }
  } else if (organization) {
    schema.author = {
      '@type': 'Organization',
      name: organization.name,
    }
  }

  if (organization) {
    schema.publisher = {
      '@type': 'Organization',
      name: organization.name,
      url: organization.url,
      ...(organization.logo && {
        logo: {
          '@type': 'ImageObject',
          url: organization.logo,
        },
      }),
    }
  }

  if (data.featuredImage?.url) {
    schema.image = {
      '@type': 'ImageObject',
      url: data.featuredImage.url,
      ...(data.featuredImage.alt && { caption: data.featuredImage.alt }),
      ...(data.featuredImage.width && { width: data.featuredImage.width }),
      ...(data.featuredImage.height && { height: data.featuredImage.height }),
    }
  }

  if (data.categories && data.categories.length > 0) {
    schema.keywords = data.categories.join(', ')
  }

  return schema
}

/**
 * Generiert NewsArticle Schema für News und Pressemitteilungen
 */
export function generateNewsArticleSchema(
  data: ArticleData,
  baseUrl: string,
  organization?: OrganizationData
) {
  const baseSchema = generateArticleSchema(data, baseUrl, organization)
  return {
    ...baseSchema,
    '@type': 'NewsArticle',
  }
}

/**
 * Generiert WebPage Schema
 */
export function generateWebPageSchema(data: WebPageData, organization?: OrganizationData) {
  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': 'WebPage',
    name: data.title,
    url: data.url,
  }

  if (data.description) {
    schema.description = data.description
  }

  if (data.updatedAt) {
    schema.dateModified = data.updatedAt
  }

  if (data.image?.url) {
    schema.image = {
      '@type': 'ImageObject',
      url: data.image.url,
      ...(data.image.alt && { caption: data.image.alt }),
    }
  }

  if (organization) {
    schema.publisher = {
      '@type': 'Organization',
      name: organization.name,
    }
  }

  return schema
}

/**
 * Generiert BreadcrumbList Schema
 */
export function generateBreadcrumbSchema(items: BreadcrumbItem[]) {
  return {
    '@context': 'https://schema.org',
    '@type': 'BreadcrumbList',
    itemListElement: items.map((item, index) => ({
      '@type': 'ListItem',
      position: index + 1,
      name: item.name,
      item: item.url,
    })),
  }
}

/**
 * Generiert FAQPage Schema
 */
export function generateFAQSchema(items: FAQItem[]) {
  return {
    '@context': 'https://schema.org',
    '@type': 'FAQPage',
    mainEntity: items.map((item) => ({
      '@type': 'Question',
      name: item.question,
      acceptedAnswer: {
        '@type': 'Answer',
        text: item.answer,
      },
    })),
  }
}

/**
 * Generiert Review/Testimonial Schema
 */
export function generateReviewSchema(
  testimonial: TestimonialData,
  organization: OrganizationData
) {
  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': 'Review',
    reviewBody: testimonial.quote,
    author: {
      '@type': 'Person',
      name: testimonial.author,
    },
    itemReviewed: {
      '@type': 'Organization',
      name: organization.name,
    },
  }

  if (testimonial.rating) {
    schema.reviewRating = {
      '@type': 'Rating',
      ratingValue: testimonial.rating,
      bestRating: 5,
      worstRating: 1,
    }
  }

  if (testimonial.date) {
    schema.datePublished = testimonial.date
  }

  return schema
}

/**
 * Generiert AggregateRating Schema für Testimonials
 */
export function generateAggregateRatingSchema(
  testimonials: TestimonialData[],
  organization: OrganizationData
) {
  const ratingsWithScore = testimonials.filter((t) => t.rating)
  if (ratingsWithScore.length === 0) return null

  const totalRating = ratingsWithScore.reduce((sum, t) => sum + (t.rating || 0), 0)
  const averageRating = totalRating / ratingsWithScore.length

  return {
    '@context': 'https://schema.org',
    '@type': 'Organization',
    name: organization.name,
    url: organization.url,
    aggregateRating: {
      '@type': 'AggregateRating',
      ratingValue: averageRating.toFixed(1),
      bestRating: 5,
      worstRating: 1,
      ratingCount: ratingsWithScore.length,
    },
  }
}

/**
 * Generiert LocalBusiness Schema
 */
export function generateLocalBusinessSchema(
  data: OrganizationData & {
    type?: string
    openingHours?: string[]
    priceRange?: string
    geo?: {
      latitude: number
      longitude: number
    }
  }
) {
  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': data.type || 'LocalBusiness',
    name: data.name,
    url: data.url,
  }

  if (data.logo) {
    schema.image = data.logo
  }

  if (data.description) {
    schema.description = data.description
  }

  if (data.email) {
    schema.email = data.email
  }

  if (data.phone) {
    schema.telephone = data.phone
  }

  if (data.address) {
    schema.address = {
      '@type': 'PostalAddress',
      streetAddress: data.address.street,
      addressLocality: data.address.city,
      postalCode: data.address.postalCode,
      addressCountry: data.address.country || 'DE',
    }
  }

  if (data.openingHours && data.openingHours.length > 0) {
    schema.openingHours = data.openingHours
  }

  if (data.priceRange) {
    schema.priceRange = data.priceRange
  }

  if (data.geo) {
    schema.geo = {
      '@type': 'GeoCoordinates',
      latitude: data.geo.latitude,
      longitude: data.geo.longitude,
    }
  }

  if (data.socialProfiles && data.socialProfiles.length > 0) {
    schema.sameAs = data.socialProfiles
  }

  return schema
}

/**
 * Generiert WebSite Schema mit SearchAction
 */
export function generateWebSiteSchema(
  name: string,
  url: string,
  searchUrl?: string
) {
  const schema: Record<string, unknown> = {
    '@context': 'https://schema.org',
    '@type': 'WebSite',
    name,
    url,
  }

  if (searchUrl) {
    schema.potentialAction = {
      '@type': 'SearchAction',
      target: {
        '@type': 'EntryPoint',
        urlTemplate: `${searchUrl}?q={search_term_string}`,
      },
      'query-input': 'required name=search_term_string',
    }
  }

  return schema
}

/**
 * Kombiniert mehrere Schemas in ein Array
 */
export function combineSchemas(...schemas: (Record<string, unknown> | null)[]) {
  const validSchemas = schemas.filter((s) => s !== null)

  if (validSchemas.length === 0) return null
  if (validSchemas.length === 1) return validSchemas[0]

  return validSchemas
}

/**
 * Hilfsfunktion zum sicheren Rendern von JSON-LD
 */
export function renderJsonLd(schema: Record<string, unknown> | Record<string, unknown>[] | null) {
  if (!schema) return null

  return JSON.stringify(schema, null, process.env.NODE_ENV === 'development' ? 2 : 0)
}
