import type { IndustryContext } from "../synthesizers/industry-classifier";
import type { SchemaOpportunityForecast, PageData } from "../types";
import type { ContentSample } from "../scrapers/firecrawl-content";

interface SchemaMeta {
  priority: "critical" | "high" | "moderate" | "low";
  lift: number;
  difficulty: "easy" | "moderate" | "hard";
  impact: string;
  note: string;
}

const SCHEMA_METADATA: Record<string, SchemaMeta> = {
  LocalBusiness: { priority: "critical", lift: 18, difficulty: "easy", impact: "Unlocks Local Pack eligibility and star-rating rich results in AI Overviews", note: "Add JSON-LD LocalBusiness block to the homepage <head>" },
  Service: { priority: "high", lift: 12, difficulty: "easy", impact: "Enables service-specific AI citation and rich results for service queries", note: "Add one JSON-LD Service block per core service page" },
  AggregateRating: { priority: "high", lift: 22, difficulty: "moderate", impact: "Enables star ratings in SERPs and AI Overviews — typically +20-35% CTR lift when present", note: "Integrate with a review platform (Google, Yelp) and output review aggregate in JSON-LD" },
  FAQPage: { priority: "high", lift: 14, difficulty: "easy", impact: "Enables FAQ rich results and signals structured QA content to AI Overview parsers", note: "Mark up existing FAQ or Q&A sections with FAQPage and Question/Answer schema" },
  Review: { priority: "moderate", lift: 8, difficulty: "moderate", impact: "Supplements AggregateRating with individual review citations in search results", note: "Output individual reviews as JSON-LD Review blocks on testimonials or case study pages" },
  Organization: { priority: "moderate", lift: 6, difficulty: "easy", impact: "Establishes entity identity and brand knowledge graph signals for AI platforms", note: "Add Organization block to homepage with name, url, logo, contactPoint" },
  WebSite: { priority: "low", lift: 3, difficulty: "easy", impact: "Enables Sitelinks search box and confirms domain entity identity", note: "Add WebSite schema with SearchAction to homepage" },
  Product: { priority: "moderate", lift: 10, difficulty: "moderate", impact: "Enables product rich results including price, availability, and review stars", note: "Add Product schema with offers and aggregateRating to each product page" },
  Article: { priority: "low", lift: 4, difficulty: "easy", impact: "Signals editorial content to AI platforms and enables article rich results", note: "Add Article or NewsArticle schema to blog post pages" },
  BlogPosting: { priority: "low", lift: 4, difficulty: "easy", impact: "Signals blog content structure and author authority to AI content parsers", note: "Add BlogPosting schema with author, datePublished, and headline fields" },
  HowTo: { priority: "moderate", lift: 9, difficulty: "easy", impact: "Enables HowTo rich results and step-by-step AI Overview citations for procedural content", note: "Mark up process or step-by-step pages with HowTo and HowToStep schema" },
  Event: { priority: "moderate", lift: 7, difficulty: "easy", impact: "Enables event rich results and AI citation of upcoming events or webinars", note: "Add Event schema with startDate, location, and organizer to event pages" },
  MedicalOrganization: { priority: "critical", lift: 20, difficulty: "easy", impact: "Establishes medical credibility in AI health queries and Knowledge Panel eligibility", note: "Add MedicalOrganization block with medicalSpecialty and availableService fields" },
  Physician: { priority: "critical", lift: 16, difficulty: "easy", impact: "Enables individual physician profiles in AI health responses", note: "Add Physician schema per doctor page with specialty, affiliation, and qualification" },
  EducationalOrganization: { priority: "critical", lift: 15, difficulty: "easy", impact: "Establishes institutional identity for higher-ed AI citation", note: "Add EducationalOrganization block with accreditation and programType fields" },
  LegalService: { priority: "critical", lift: 17, difficulty: "easy", impact: "Enables legal service rich results and attorney AI citation", note: "Add LegalService block with areaServed, availableChannel, and priceRange" },
  FinancialProduct: { priority: "high", lift: 11, difficulty: "moderate", impact: "Enables financial product comparison citations in AI finance queries", note: "Add FinancialProduct schema with interestRate and feesAndCommissionsSpecification" },
  RealEstateListing: { priority: "high", lift: 13, difficulty: "moderate", impact: "Enables property listing rich results in AI real estate queries", note: "Add RealEstateListing schema with geo, address, and price fields" },
  JobPosting: { priority: "moderate", lift: 8, difficulty: "easy", impact: "Enables job posting rich results and AI job citation", note: "Add JobPosting schema with datePosted, employmentType, and hiringOrganization" },
  Recipe: { priority: "high", lift: 16, difficulty: "easy", impact: "Enables recipe rich results with nutrition, time, and rating display in SERPs", note: "Add Recipe schema with recipeIngredient, recipeInstructions, and nutrition fields" },
};

const FALLBACK_META: SchemaMeta = {
  priority: "low",
  lift: 3,
  difficulty: "easy",
  impact: "Establishes semantic type identity for this content category",
  note: "Add appropriate JSON-LD schema block matching the content type on relevant pages",
};

function detectSchemaPresence(
  schemaType: string,
  pages: PageData[],
  contentSamples: ContentSample[],
): { present: boolean; detectedOnUrls: string[] } {
  const lower = schemaType.toLowerCase();
  const regex = new RegExp(`"@type"\\s*:\\s*"${schemaType}"`, "i");

  const detectedOnUrls: string[] = [];

  for (const page of pages) {
    if (page.schemaTypes.some((t) => t.toLowerCase() === lower)) {
      detectedOnUrls.push(page.url);
    }
  }

  const inMarkdown = contentSamples.some((s) => regex.test(s.markdown));

  return {
    present: detectedOnUrls.length > 0 || inMarkdown,
    detectedOnUrls,
  };
}

export function aggregateSchemaOpportunityForecast(
  industryContext: IndustryContext,
  pages: PageData[],
  contentSamples: ContentSample[],
): SchemaOpportunityForecast | null {
  if (industryContext.schemaPriorities.length === 0) return null;

  const schemaConflicts: Array<{ url: string; issue: string }> = [];
  for (const page of pages) {
    if (page.hasSchema && page.schemaTypes.length === 0) {
      schemaConflicts.push({ url: page.url, issue: "Schema markup detected but no valid @type found — likely malformed JSON-LD" });
      break;
    }
  }

  const prioritySchemaTypes: SchemaOpportunityForecast["prioritySchemaTypes"] = [];
  let presentCount = 0;
  let missingLiftSum = 0;

  for (const schemaType of industryContext.schemaPriorities) {
    const meta = SCHEMA_METADATA[schemaType] ?? FALLBACK_META;
    const { present, detectedOnUrls } = detectSchemaPresence(schemaType, pages, contentSamples);

    if (present) {
      presentCount++;
    } else {
      missingLiftSum += meta.lift;
    }

    prioritySchemaTypes.push({
      schemaType,
      present,
      presentOnPages: detectedOnUrls,
      priority: meta.priority,
      estimatedLiftPercent: meta.lift,
      implementationDifficulty: meta.difficulty,
      expectedImpact: meta.impact,
      implementationNote: meta.note,
    });
  }

  const total = industryContext.schemaPriorities.length;
  const currentCoveragePercent = Math.round((presentCount / total) * 100);
  const cumulativeLiftEstimate = Math.min(missingLiftSum, 65);

  return {
    industryVertical: industryContext.industry,
    industrySubVertical: industryContext.subVertical,
    prioritySchemaTypes,
    currentCoveragePercent,
    potentialCoveragePercent: 100,
    cumulativeLiftEstimate,
    hasSchemaConflicts: schemaConflicts.length > 0,
    schemaConflicts,
  };
}
