import {
  SEO_KEYWORDS_POOL,
  type SeoKeywordEntry,
  type SeoKeywordIntent,
} from "@/data/seo/keywords-pool";
import type { SeoPageContext, SeoPageKind } from "./types";

const MAX_KEYWORDS_PER_PAGE = 12;
const POOL_SLOTS_PER_PAGE = 6;

const SERVICE_SLUG_TAGS: Record<string, string[]> = {
  "criacao-de-app": ["app", "aplicativo", "mobile"],
  "desenvolvimento-de-app": ["app", "aplicativo", "software"],
  "sistema-delivery": ["delivery", "app", "pedido"],
  "cardapio-digital": ["cardapio", "restaurante", "app"],
  "aplicativo-empresarial": ["empresarial", "corporativo", "sistema"],
  "automacao-comercial": ["automacao", "crm", "vendas"],
  "sistema-saas": ["saas", "plataforma", "software"],
  "painel-administrativo": ["painel", "dashboard", "sistema"],
  "app-mobile": ["mobile", "android", "ios", "app"],
  "plataforma-web": ["web", "portal", "plataforma"],
};

const SEGMENT_SLUG_TAGS: Record<string, string[]> = {
  restaurante: ["restaurante", "delivery", "food"],
  pizzaria: ["pizzaria", "delivery", "food"],
  loja: ["loja", "ecommerce", "varejo"],
  clinica: ["clinica", "saude"],
  barbearia: ["barbearia", "agendamento"],
};

const KIND_INTENT_PRIORITY: Record<SeoPageKind, SeoKeywordIntent[]> = {
  "service-city": ["service", "hire", "location", "technology", "problem"],
  "service-state": ["location", "service", "hire", "technology"],
  "segment": ["problem", "service", "hire"],
  "segment-city": ["problem", "location", "service"],
  "segment-state": ["location", "problem", "service"],
  "service-segment": ["problem", "service", "hire"],
  "service-segment-city": ["problem", "service", "location", "hire"],
  "service-segment-state": ["location", "problem", "service"],
};

function hashSlug(slug: string): number {
  let h = 0;
  for (let i = 0; i < slug.length; i++) {
    h = (h * 31 + slug.charCodeAt(i)) >>> 0;
  }
  return h;
}

function inferTags(phrase: string): string[] {
  const p = phrase.toLowerCase();
  const tags = new Set<string>(["geral"]);
  if (/delivery|pedido/.test(p)) tags.add("delivery");
  if (/ecommerce|loja online|loja virtual|varejo/.test(p)) tags.add("ecommerce");
  if (/restaurante|cardápio|cardapio|pizzaria|food/.test(p)) tags.add("restaurante");
  if (/saas/.test(p)) tags.add("saas");
  if (/painel|dashboard|administrativo/.test(p)) tags.add("painel");
  if (/crm|vendas|comercial|gestão|gestao|gerenciamento/.test(p)) tags.add("vendas");
  if (/sistema|software/.test(p)) tags.add("sistema");
  if (/aplicativo|app |app para|android|ios|mobile/.test(p)) tags.add("app");
  if (/plataforma|portal|web/.test(p)) tags.add("plataforma");
  if (/empresarial|corporativo/.test(p)) tags.add("empresarial");
  if (/brasil|nacional/.test(p)) tags.add("brasil");
  return [...tags];
}

function pageTags(ctx: SeoPageContext): Set<string> {
  const tags = new Set<string>(["geral"]);
  if (ctx.service) {
    SERVICE_SLUG_TAGS[ctx.service.slug]?.forEach((t) => tags.add(t));
    tags.add("app");
  }
  if (ctx.segment) {
    SEGMENT_SLUG_TAGS[ctx.segment.slug]?.forEach((t) => tags.add(t));
  }
  if (ctx.city || ctx.state) tags.add("brasil");
  return tags;
}

function scoreEntry(entry: SeoKeywordEntry, ctx: SeoPageContext, priorities: SeoKeywordIntent[]): number {
  if (entry.intent === "brand") return -1;
  const intentIdx = priorities.indexOf(entry.intent);
  if (intentIdx < 0) return 0;
  const tags = inferTags(entry.phrase);
  const page = pageTags(ctx);
  let overlap = 0;
  for (const t of tags) {
    if (page.has(t)) overlap += 1;
  }
  return (priorities.length - intentIdx) * 10 + overlap * 3;
}

function pickFromPool(ctx: SeoPageContext): string[] {
  const priorities = KIND_INTENT_PRIORITY[ctx.kind] ?? ["service", "hire", "technology"];
  const scored = SEO_KEYWORDS_POOL.map((entry, index) => ({
    entry,
    index,
    score: scoreEntry(entry, ctx, priorities),
  }))
    .filter((x) => x.score > 0)
    .sort((a, b) => b.score - a.score || a.index - b.index);

  const hash = hashSlug(ctx.slug);
  const picked: string[] = [];
  const used = new Set<string>();

  for (let i = 0; i < scored.length && picked.length < POOL_SLOTS_PER_PAGE; i++) {
    const idx = (hash + i * 37) % scored.length;
    const phrase = scored[idx].entry.phrase;
    if (!used.has(phrase)) {
      used.add(phrase);
      picked.push(phrase);
    }
  }

  return picked;
}

function localKeywords(ctx: SeoPageContext): string[] {
  const out: string[] = [];
  if (ctx.city) {
    const city = ctx.city.name;
    if (ctx.service) {
      out.push(`${ctx.service.shortName} ${city}`);
      out.push(`empresa de aplicativos ${city}`);
    } else if (ctx.segment) {
      out.push(`app para ${ctx.segment.name.toLowerCase()} ${city}`);
    }
  }
  if (ctx.state && !ctx.city) {
    const prep = ctx.state.preposition === "no" ? "no" : "na";
    out.push(`desenvolvimento de aplicativos ${prep} ${ctx.state.name}`);
  }
  return out;
}

/**
 * Monta keywords únicas por URL: base do serviço/segmento + pool rotacionado por slug
 * (reduz canibalização entre landing pages programáticas).
 */
export function assignKeywordsForPage(ctx: SeoPageContext): string[] {
  const keys = new Set<string>();

  ctx.service?.keywords.forEach((k) => keys.add(k));
  ctx.segment?.keywords.forEach((k) => keys.add(k));
  localKeywords(ctx).forEach((k) => keys.add(k));
  pickFromPool(ctx).forEach((k) => keys.add(k));

  return [...keys].slice(0, MAX_KEYWORDS_PER_PAGE);
}

/** Sugestões para o painel admin ao editar uma página no banco. */
export function suggestKeywordsForAdminSlug(
  slug: string,
  serviceSlug?: string | null,
  segmentSlug?: string | null,
): string {
  const ctx: SeoPageContext = {
    kind: "service-city",
    slug,
    service: serviceSlug
      ? {
          slug: serviceSlug,
          name: serviceSlug,
          shortName: serviceSlug,
          description: "",
          keywords: [],
          features: [],
        }
      : undefined,
    segment: segmentSlug
      ? {
          slug: segmentSlug,
          name: segmentSlug,
          plural: segmentSlug,
          description: "",
          relatedSlugs: [],
          keywords: [],
        }
      : undefined,
  };

  return assignKeywordsForPage(ctx).join(", ");
}
