import { useMetaData } from '@websolutespa/bom-mixer-hooks';
import { IMetaData, OpenGraphArticle, OpenGraphBook, OpenGraphImage, OpenGraphProduct, OpenGraphProfile, OpenGraphType } from '@websolutespa/bom-mixer-models';
import Head from 'next/head';
import React from 'react';

function generateImageTags(image: OpenGraphImage, index?: number): React.ReactElement[] {
  const tags: React.ReactElement[] = [];
  const suffix = index !== undefined ? `:${index}` : '';

  tags.push(<meta key={`og:image${suffix}`} property="og:image" content={image.url} />);

  if (image.secureUrl) {
    tags.push(<meta key={`og:image:secure_url${suffix}`} property="og:image:secure_url" content={image.secureUrl} />);
  }
  if (image.type) {
    tags.push(<meta key={`og:image:type${suffix}`} property="og:image:type" content={image.type} />);
  }
  if (image.width) {
    tags.push(<meta key={`og:image:width${suffix}`} property="og:image:width" content={image.width.toString()} />);
  }
  if (image.height) {
    tags.push(<meta key={`og:image:height${suffix}`} property="og:image:height" content={image.height.toString()} />);
  }
  if (image.alt) {
    tags.push(<meta key={`og:image:alt${suffix}`} property="og:image:alt" content={image.alt} />);
  }

  return tags;
}

export function renderOpenGraph(data: OpenGraphType): React.ReactElement[] {
  const tags: React.ReactElement[] = [];

  // Basic Open Graph tags
  if (data.title) {
    tags.push(<meta key="og:title" property="og:title" content={data.title} />);
  }

  if (data.type) {
    tags.push(<meta key="og:type" property="og:type" content={data.type} />);
  }

  if (data.url) {
    tags.push(<meta key="og:url" property="og:url" content={data.url} />);
  }

  if (data.description) {
    tags.push(<meta key="og:description" property="og:description" content={data.description} />);
  }

  if (data.siteName) {
    tags.push(<meta key="og:site_name" property="og:site_name" content={data.siteName} />);
  }

  if (data.locale) {
    tags.push(<meta key="og:locale" property="og:locale" content={data.locale} />);
  }

  if (data.localeAlternate) {
    data.localeAlternate.forEach((locale, index) => {
      tags.push(<meta key={`og:locale:alternate:${index}`} property="og:locale:alternate" content={locale} />);
    });
  }

  // Handle images
  if (data.image) {
    if (typeof data.image === 'string') {
      tags.push(<meta key="og:image" property="og:image" content={data.image} />);
    } else if (Array.isArray(data.image)) {
      data.image.forEach((img, index) => {
        if (typeof img === 'string') {
          tags.push(<meta key={`og:image:${index}`} property="og:image" content={img} />);
        } else {
          tags.push(...generateImageTags(img, index));
        }
      });
    } else {
      tags.push(...generateImageTags(data.image));
    }
  }

  // Type-specific tags
  switch (data.type) {
    case 'article': {
      const articleData = data as OpenGraphArticle;
      if (articleData.publishedTime) {
        tags.push(
          <meta key="article:published_time" property="article:published_time" content={articleData.publishedTime} />
        );
      }
      if (articleData.modifiedTime) {
        tags.push(
          <meta key="article:modified_time" property="article:modified_time" content={articleData.modifiedTime} />
        );
      }
      if (articleData.expirationTime) {
        tags.push(
          <meta
            key="article:expiration_time"
            property="article:expiration_time"
            content={articleData.expirationTime}
          />
        );
      }
      if (articleData.author) {
        const authors = Array.isArray(articleData.author) ? articleData.author : [articleData.author];
        authors.forEach((author, index) => {
          tags.push(<meta key={`article:author:${index}`} property="article:author" content={author} />);
        });
      }
      if (articleData.section) {
        tags.push(<meta key="article:section" property="article:section" content={articleData.section} />);
      }
      if (articleData.tag) {
        const articleTags = Array.isArray(articleData.tag) ? articleData.tag : [articleData.tag];
        articleTags.forEach((tag, index) => {
          tags.push(<meta key={`article:tag:${index}`} property="article:tag" content={tag} />);
        });
      }
      break;
    }
    case 'book': {
      const bookData = data as OpenGraphBook;
      if (bookData.author) {
        const authors = Array.isArray(bookData.author) ? bookData.author : [bookData.author];
        authors.forEach((author, index) => {
          tags.push(<meta key={`book:author:${index}`} property="book:author" content={author} />);
        });
      }
      if (bookData.isbn) {
        tags.push(<meta key="book:isbn" property="book:isbn" content={bookData.isbn} />);
      }
      if (bookData.releaseDate) {
        tags.push(<meta key="book:release_date" property="book:release_date" content={bookData.releaseDate} />);
      }
      if (bookData.tag) {
        const bookTags = Array.isArray(bookData.tag) ? bookData.tag : [bookData.tag];
        bookTags.forEach((tag, index) => {
          tags.push(<meta key={`book:tag:${index}`} property="book:tag" content={tag} />);
        });
      }
      break;
    }
    case 'profile': {
      const profileData = data as OpenGraphProfile;
      if (profileData.firstName) {
        tags.push(<meta key="profile:first_name" property="profile:first_name" content={profileData.firstName} />);
      }
      if (profileData.lastName) {
        tags.push(<meta key="profile:last_name" property="profile:last_name" content={profileData.lastName} />);
      }
      if (profileData.username) {
        tags.push(<meta key="profile:username" property="profile:username" content={profileData.username} />);
      }
      if (profileData.gender) {
        tags.push(<meta key="profile:gender" property="profile:gender" content={profileData.gender} />);
      }
      break;
    }
    case 'product': {
      const productData = data as OpenGraphProduct;
      if (productData.price) {
        tags.push(
          <meta
            key="product:price:amount"
            property="product:price:amount"
            content={productData.price.amount.toString()}
          />
        );
        tags.push(
          <meta key="product:price:currency" property="product:price:currency" content={productData.price.currency} />
        );
      }
      if (productData.availability) {
        tags.push(
          <meta key="product:availability" property="product:availability" content={productData.availability} />
        );
      }
      if (productData.condition) {
        tags.push(<meta key="product:condition" property="product:condition" content={productData.condition} />);
      }
      if (productData.retailerItemId) {
        tags.push(
          <meta
            key="product:retailer_item_id"
            property="product:retailer_item_id"
            content={productData.retailerItemId}
          />
        );
      }
      if (productData.brand) {
        tags.push(<meta key="product:brand" property="product:brand" content={productData.brand} />);
      }
      break;
    }
  }
  return tags;
}

export function OpenGraph({ item }: { item?: (metaData: IMetaData) => OpenGraphType }) {
  const metaData = useMetaData();
  const openGraph = item ? item(metaData) : metaData.openGraph;
  if (openGraph) {
    return (
      <Head>
        {renderOpenGraph(openGraph)}
      </Head>
    );
  }
  return <></>;
}
