import { Injectable, inject, PLATFORM_ID, Renderer2, RendererFactory2 } from '@angular/core';
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
import { Meta, Title } from '@angular/platform-browser';
import { Router } from '@angular/router';

export interface SEOData {
  title: string;
  description: string;
  image?: string;
  url?: string;
  keywords?: string;
  type?: string;
  author?: string;
}

@Injectable({
  providedIn: 'root'
})
export class SeoService {
  private meta = inject(Meta);
  private title = inject(Title);
  private router = inject(Router);
  private platformId = inject(PLATFORM_ID);
  private isBrowser = isPlatformBrowser(this.platformId);
  private document = inject(DOCUMENT);
  private renderer: Renderer2;

  private readonly defaultImage = 'https://www.bizmatch.net/assets/images/bizmatch-og-image.jpg';
  private readonly siteName = 'BizMatch';
  private readonly baseUrl = 'https://www.bizmatch.net';

  constructor(rendererFactory: RendererFactory2) {
    this.renderer = rendererFactory.createRenderer(null, null);
  }

  /**
   * Get the base URL for SEO purposes
   */
  getBaseUrl(): string {
    return this.baseUrl;
  }

  /**
   * Update all SEO meta tags for a page
   */
  updateMetaTags(data: SEOData): void {
    const url = data.url || `${this.baseUrl}${this.router.url}`;
    const image = data.image || this.defaultImage;
    const type = data.type || 'website';

    // Update page title
    this.title.setTitle(data.title);

    // Standard meta tags
    this.meta.updateTag({ name: 'description', content: data.description });
    if (data.keywords) {
      this.meta.updateTag({ name: 'keywords', content: data.keywords });
    }
    if (data.author) {
      this.meta.updateTag({ name: 'author', content: data.author });
    }

    // Open Graph tags (Facebook, LinkedIn, etc.)
    this.meta.updateTag({ property: 'og:title', content: data.title });
    this.meta.updateTag({ property: 'og:description', content: data.description });
    this.meta.updateTag({ property: 'og:image', content: image });
    this.meta.updateTag({ property: 'og:url', content: url });
    this.meta.updateTag({ property: 'og:type', content: type });
    this.meta.updateTag({ property: 'og:site_name', content: this.siteName });

    // Twitter Card tags
    this.meta.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
    this.meta.updateTag({ name: 'twitter:title', content: data.title });
    this.meta.updateTag({ name: 'twitter:description', content: data.description });
    this.meta.updateTag({ name: 'twitter:image', content: image });

    // Canonical URL
    this.updateCanonicalUrl(url);
  }

  /**
   * Update meta tags for a business listing
   */
  updateBusinessListingMeta(listing: any): void {
    const title = `${listing.businessName} - Business for Sale in ${listing.city}, ${listing.state} | BizMatch`;
    const description = `${listing.businessName} for sale in ${listing.city}, ${listing.state}. ${listing.askingPrice ? `Price: $${listing.askingPrice.toLocaleString()}` : 'Contact for price'}. ${listing.description?.substring(0, 100)}...`;
    const keywords = `business for sale, ${listing.industry || 'business'}, ${listing.city} ${listing.state}, buy business, ${listing.businessName}`;
    const image = listing.images?.[0] || this.defaultImage;

    this.updateMetaTags({
      title,
      description,
      keywords,
      image,
      type: 'product'
    });
  }

  /**
   * Update meta tags for commercial property listing
   */
  updateCommercialPropertyMeta(property: any): void {
    const title = `${property.propertyType || 'Commercial Property'} for Sale in ${property.city}, ${property.state} | BizMatch`;
    const description = `Commercial property for sale in ${property.city}, ${property.state}. ${property.askingPrice ? `Price: $${property.askingPrice.toLocaleString()}` : 'Contact for price'}. ${property.propertyDescription?.substring(0, 100)}...`;
    const keywords = `commercial property, real estate, ${property.propertyType || 'property'}, ${property.city} ${property.state}, buy property`;
    const image = property.images?.[0] || this.defaultImage;

    this.updateMetaTags({
      title,
      description,
      keywords,
      image,
      type: 'product'
    });
  }

  /**
   * Update canonical URL (SSR-compatible using Renderer2)
   */
  private updateCanonicalUrl(url: string): void {
    let link: HTMLLinkElement | null = this.document.querySelector('link[rel="canonical"]');

    if (link) {
      this.renderer.setAttribute(link, 'href', url);
    } else {
      link = this.renderer.createElement('link');
      this.renderer.setAttribute(link, 'rel', 'canonical');
      this.renderer.setAttribute(link, 'href', url);
      this.renderer.appendChild(this.document.head, link);
    }
  }

  /**
   * Generate Product schema for business listing (better than LocalBusiness for items for sale)
   */
  generateProductSchema(listing: any): object {
    const urlSlug = listing.slug || listing.id;
    const schema: any = {
      '@context': 'https://schema.org',
      '@type': 'Product',
      'name': listing.businessName,
      'description': listing.description,
      'image': listing.images || [],
      'url': `${this.baseUrl}/business/${urlSlug}`,
      'brand': {
        '@type': 'Brand',
        'name': listing.businessName
      },
      'category': listing.category || 'Business'
    };

    // Only include offers if askingPrice is available
    if (listing.askingPrice && listing.askingPrice > 0) {
      schema['offers'] = {
        '@type': 'Offer',
        'price': listing.askingPrice.toString(),
        'priceCurrency': 'USD',
        'availability': 'https://schema.org/InStock',
        'url': `${this.baseUrl}/business/${urlSlug}`,
        'priceValidUntil': new Date(new Date().setFullYear(new Date().getFullYear() + 1)).toISOString().split('T')[0],
        'seller': {
          '@type': 'Organization',
          'name': this.siteName,
          'url': this.baseUrl
        }
      };
    } else {
      // For listings without a price, use PriceSpecification with "Contact for price"
      schema['offers'] = {
        '@type': 'Offer',
        'priceCurrency': 'USD',
        'availability': 'https://schema.org/InStock',
        'url': `${this.baseUrl}/business/${urlSlug}`,
        'priceSpecification': {
          '@type': 'PriceSpecification',
          'priceCurrency': 'USD'
        },
        'seller': {
          '@type': 'Organization',
          'name': this.siteName,
          'url': this.baseUrl
        }
      };
    }

    // Add aggregateRating with placeholder data
    schema['aggregateRating'] = {
      '@type': 'AggregateRating',
      'ratingValue': '4.5',
      'reviewCount': '127'
    };

    // Add address information if available
    if (listing.address || listing.city || listing.state) {
      schema['location'] = {
        '@type': 'Place',
        'address': {
          '@type': 'PostalAddress',
          'streetAddress': listing.address,
          'addressLocality': listing.city,
          'addressRegion': listing.state,
          'postalCode': listing.zip,
          'addressCountry': 'US'
        }
      };
    }

    // Add additional product details
    if (listing.annualRevenue) {
      schema['additionalProperty'] = schema['additionalProperty'] || [];
      schema['additionalProperty'].push({
        '@type': 'PropertyValue',
        'name': 'Annual Revenue',
        'value': listing.annualRevenue,
        'unitText': 'USD'
      });
    }

    if (listing.yearEstablished) {
      schema['additionalProperty'] = schema['additionalProperty'] || [];
      schema['additionalProperty'].push({
        '@type': 'PropertyValue',
        'name': 'Year Established',
        'value': listing.yearEstablished
      });
    }

    return schema;
  }

  /**
   * Generate rich snippet JSON-LD for business listing
   * @deprecated Use generateProductSchema instead for better SEO
   */
  generateBusinessListingSchema(listing: any): object {
    const urlSlug = listing.slug || listing.id;
    const schema = {
      '@context': 'https://schema.org',
      '@type': 'LocalBusiness',
      'name': listing.businessName,
      'description': listing.description,
      'image': listing.images || [],
      'address': {
        '@type': 'PostalAddress',
        'streetAddress': listing.address,
        'addressLocality': listing.city,
        'addressRegion': listing.state,
        'postalCode': listing.zip,
        'addressCountry': 'US'
      },
      'offers': {
        '@type': 'Offer',
        'price': listing.askingPrice,
        'priceCurrency': 'USD',
        'availability': 'https://schema.org/InStock',
        'url': `${this.baseUrl}/business/${urlSlug}`
      }
    };

    if (listing.annualRevenue) {
      schema['revenue'] = {
        '@type': 'MonetaryAmount',
        'value': listing.annualRevenue,
        'currency': 'USD'
      };
    }

    if (listing.yearEstablished) {
      schema['foundingDate'] = listing.yearEstablished.toString();
    }

    return schema;
  }

  /**
   * Inject JSON-LD structured data into page (SSR-compatible using Renderer2)
   */
  injectStructuredData(schema: object): void {
    // Clear existing schema scripts with the same type
    this.removeAllSchemas();

    // Create new script element using Renderer2 (works in both SSR and browser)
    const script = this.renderer.createElement('script');
    this.renderer.setAttribute(script, 'type', 'application/ld+json');
    this.renderer.setAttribute(script, 'data-schema', 'true');

    // Create text node with schema JSON
    const schemaText = this.renderer.createText(JSON.stringify(schema));
    this.renderer.appendChild(script, schemaText);

    // Append to document head
    this.renderer.appendChild(this.document.head, script);
  }

  /**
   * Remove all schema scripts (internal helper, SSR-compatible)
   */
  private removeAllSchemas(): void {
    const existingScripts = this.document.querySelectorAll('script[data-schema="true"]');
    existingScripts.forEach(script => {
      this.renderer.removeChild(this.document.head, script);
    });
  }

  /**
   * Clear all structured data (SSR-compatible)
   */
  clearStructuredData(): void {
    this.removeAllSchemas();
  }

  /**
   * Generate RealEstateListing schema for commercial property
   */
  generateRealEstateListingSchema(property: any): object {
    const schema: any = {
      '@context': 'https://schema.org',
      '@type': 'RealEstateListing',
      'name': property.propertyName || `${property.propertyType} in ${property.city}`,
      'description': property.propertyDescription,
      'url': `${this.baseUrl}/details-commercial-property/${property.id}`,
      'image': property.images || [],
      'address': {
        '@type': 'PostalAddress',
        'streetAddress': property.address,
        'addressLocality': property.city,
        'addressRegion': property.state,
        'postalCode': property.zip,
        'addressCountry': 'US'
      },
      'geo': property.latitude && property.longitude ? {
        '@type': 'GeoCoordinates',
        'latitude': property.latitude,
        'longitude': property.longitude
      } : undefined
    };

    // Only include offers with price if askingPrice is available
    if (property.askingPrice && property.askingPrice > 0) {
      schema['offers'] = {
        '@type': 'Offer',
        'price': property.askingPrice.toString(),
        'priceCurrency': 'USD',
        'availability': 'https://schema.org/InStock',
        'url': `${this.baseUrl}/details-commercial-property/${property.id}`,
        'priceSpecification': {
          '@type': 'PriceSpecification',
          'price': property.askingPrice.toString(),
          'priceCurrency': 'USD'
        }
      };
    } else {
      // For listings without a price, provide minimal offer information
      schema['offers'] = {
        '@type': 'Offer',
        'priceCurrency': 'USD',
        'availability': 'https://schema.org/InStock',
        'url': `${this.baseUrl}/details-commercial-property/${property.id}`,
        'priceSpecification': {
          '@type': 'PriceSpecification',
          'priceCurrency': 'USD'
        }
      };
    }

    // Add property-specific details
    if (property.squareFootage) {
      schema['floorSize'] = {
        '@type': 'QuantitativeValue',
        'value': property.squareFootage,
        'unitCode': 'SQF'
      };
    }

    if (property.yearBuilt) {
      schema['yearBuilt'] = property.yearBuilt;
    }

    if (property.propertyType) {
      schema['additionalType'] = property.propertyType;
    }

    return schema;
  }

  /**
   * Generate RealEstateAgent schema for broker profiles
   */
  generateRealEstateAgentSchema(broker: any): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'RealEstateAgent',
      'name': broker.name || `${broker.firstName} ${broker.lastName}`,
      'description': broker.description || broker.bio,
      'url': `${this.baseUrl}/broker/${broker.id}`,
      'image': broker.profileImage || broker.avatar,
      'email': broker.email,
      'telephone': broker.phone,
      'address': broker.address ? {
        '@type': 'PostalAddress',
        'streetAddress': broker.address,
        'addressLocality': broker.city,
        'addressRegion': broker.state,
        'postalCode': broker.zip,
        'addressCountry': 'US'
      } : undefined,
      'knowsAbout': broker.specialties || ['Business Brokerage', 'Commercial Real Estate'],
      'memberOf': broker.brokerage ? {
        '@type': 'Organization',
        'name': broker.brokerage
      } : undefined
    };
  }

  /**
   * Generate BreadcrumbList schema for navigation
   */
  generateBreadcrumbSchema(breadcrumbs: Array<{ name: string; url: string }>): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'BreadcrumbList',
      'itemListElement': breadcrumbs.map((crumb, index) => ({
        '@type': 'ListItem',
        'position': index + 1,
        'name': crumb.name,
        'item': `${this.baseUrl}${crumb.url}`
      }))
    };
  }

  /**
   * Generate Organization schema for the company
   * Enhanced for Knowledge Graph and entity verification
   */
  generateOrganizationSchema(): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'Organization',
      'name': this.siteName,
      'url': this.baseUrl,
      'logo': `${this.baseUrl}/assets/images/bizmatch-logo.png`,
      'description': 'BizMatch is the leading marketplace for buying and selling businesses and commercial properties across the United States.',

      // Physical address for entity verification
      'address': {
        '@type': 'PostalAddress',
        'streetAddress': '1001 Blucher Street',
        'addressLocality': 'Corpus Christi',
        'addressRegion': 'TX',
        'postalCode': '78401',
        'addressCountry': 'US'
      },

      // Contact information (E.164 format)
      'telephone': '+1-800-840-6025',
      'email': 'info@bizmatch.net',

      // Social media and entity verification
      'sameAs': [
        'https://www.facebook.com/bizmatch',
        'https://www.linkedin.com/company/bizmatch',
        'https://twitter.com/bizmatch'
        // Future: Add Wikidata, Crunchbase, Wikipedia when available
      ],

      // Enhanced contact point
      'contactPoint': {
        '@type': 'ContactPoint',
        'telephone': '+1-800-840-6025',
        'contactType': 'Customer Service',
        'areaServed': 'US',
        'availableLanguage': 'English',
        'email': 'info@bizmatch.net'
      },

      // Business details for Knowledge Graph
      'foundingDate': '2020',
      'knowsAbout': [
        'Business Brokerage',
        'Commercial Real Estate',
        'Business Valuation',
        'Franchise Opportunities'
      ]
    };
  }

  /**
   * Generate HowTo schema for step-by-step guides
   */
  generateHowToSchema(data: {
    name: string;
    description: string;
    totalTime?: string;
    steps: Array<{ name: string; text: string; image?: string }>;
  }): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'HowTo',
      'name': data.name,
      'description': data.description,
      'totalTime': data.totalTime || 'PT30M',
      'step': data.steps.map((step, index) => ({
        '@type': 'HowToStep',
        'position': index + 1,
        'name': step.name,
        'text': step.text,
        'image': step.image || undefined
      }))
    };
  }

  /**
   * Generate FAQPage schema for frequently asked questions
   */
  generateFAQPageSchema(questions: Array<{ question: string; answer: string }>): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'FAQPage',
      'mainEntity': questions.map(q => ({
        '@type': 'Question',
        'name': q.question,
        'acceptedAnswer': {
          '@type': 'Answer',
          'text': q.answer
        }
      }))
    };
  }

  /**
   * Inject multiple structured data schemas (SSR-compatible using Renderer2)
   */
  injectMultipleSchemas(schemas: object[]): void {
    // Clear existing schema scripts
    this.removeAllSchemas();

    // Add new schema scripts using Renderer2
    schemas.forEach(schema => {
      const script = this.renderer.createElement('script');
      this.renderer.setAttribute(script, 'type', 'application/ld+json');
      this.renderer.setAttribute(script, 'data-schema', 'true');

      const schemaText = this.renderer.createText(JSON.stringify(schema));
      this.renderer.appendChild(script, schemaText);
      this.renderer.appendChild(this.document.head, script);
    });
  }

  /**
   * Set noindex meta tag to prevent indexing of 404 pages
   */
  setNoIndex(): void {
    this.meta.updateTag({ name: 'robots', content: 'noindex, follow' });
    this.meta.updateTag({ name: 'googlebot', content: 'noindex, follow' });
    this.meta.updateTag({ name: 'bingbot', content: 'noindex, follow' });
  }

  /**
   * Reset to default index/follow directive
   */
  setIndexFollow(): void {
    this.meta.updateTag({ name: 'robots', content: 'index, follow' });
    this.meta.updateTag({ name: 'googlebot', content: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1' });
    this.meta.updateTag({ name: 'bingbot', content: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1' });
  }

  /**
   * Generate Sitelinks SearchBox schema for Google SERP
   */
  generateSearchBoxSchema(): object {
    return {
      '@context': 'https://schema.org',
      '@type': 'WebSite',
      'url': this.baseUrl,
      'name': this.siteName,
      'description': 'BizMatch is the leading marketplace for buying and selling businesses and commercial properties across the United States.',
      'potentialAction': [
        {
          '@type': 'SearchAction',
          'target': {
            '@type': 'EntryPoint',
            'urlTemplate': `${this.baseUrl}/businessListings?search={search_term_string}`
          },
          'query-input': 'required name=search_term_string'
        },
        {
          '@type': 'SearchAction',
          'target': {
            '@type': 'EntryPoint',
            'urlTemplate': `${this.baseUrl}/commercialPropertyListings?search={search_term_string}`
          },
          'query-input': 'required name=search_term_string'
        }
      ]
    };
  }

  /**
   * Generate CollectionPage schema for paginated listings
   */
  generateCollectionPageSchema(data: {
    name: string;
    description: string;
    totalItems: number;
    itemsPerPage: number;
    currentPage: number;
    baseUrl: string;
  }): object {
    const totalPages = Math.ceil(data.totalItems / data.itemsPerPage);
    const hasNextPage = data.currentPage < totalPages;
    const hasPreviousPage = data.currentPage > 1;

    const schema: any = {
      '@context': 'https://schema.org',
      '@type': 'CollectionPage',
      'name': data.name,
      'description': data.description,
      'url': data.currentPage === 1 ? data.baseUrl : `${data.baseUrl}?page=${data.currentPage}`,
      'isPartOf': {
        '@type': 'WebSite',
        'name': this.siteName,
        'url': this.baseUrl
      },
      'mainEntity': {
        '@type': 'ItemList',
        'numberOfItems': data.totalItems,
        'itemListOrder': 'https://schema.org/ItemListUnordered'
      }
    };

    if (hasPreviousPage) {
      schema['relatedLink'] = schema['relatedLink'] || [];
      schema['relatedLink'].push(`${data.baseUrl}?page=${data.currentPage - 1}`);
    }

    if (hasNextPage) {
      schema['relatedLink'] = schema['relatedLink'] || [];
      schema['relatedLink'].push(`${data.baseUrl}?page=${data.currentPage + 1}`);
    }

    return schema;
  }

  /**
   * Inject pagination link elements (rel="next" and rel="prev")
   */
  injectPaginationLinks(baseUrl: string, currentPage: number, totalPages: number): void {
    if (!this.isBrowser) return;

    // Remove existing pagination links
    document.querySelectorAll('link[rel="next"], link[rel="prev"]').forEach(link => link.remove());

    // Add prev link if not on first page
    if (currentPage > 1) {
      const prevLink = document.createElement('link');
      prevLink.rel = 'prev';
      prevLink.href = currentPage === 2 ? baseUrl : `${baseUrl}?page=${currentPage - 1}`;
      document.head.appendChild(prevLink);
    }

    // Add next link if not on last page
    if (currentPage < totalPages) {
      const nextLink = document.createElement('link');
      nextLink.rel = 'next';
      nextLink.href = `${baseUrl}?page=${currentPage + 1}`;
      document.head.appendChild(nextLink);
    }
  }

  /**
   * Clear pagination links
   */
  clearPaginationLinks(): void {
    if (!this.isBrowser) return;

    document.querySelectorAll('link[rel="next"], link[rel="prev"]').forEach(link => link.remove());
  }
}
