import { PortalModel } from "../models/portalModel";
import { SCRAPER_REGISTRY, getScraperClassNames } from "../config/scraperRegistry";
import { PORTAL_PROBE_TARGETS } from "../config/portalProbeConfig";
import { probePortal, probeAllPortals, type ProbeResult } from "./portalProbeService";
import {
  supervisorConfig,
  getSupervisorHealth,
  dispatchChat,
  recommendTask,
  buildBridgeDeepLink,
} from "./supervisorAiService";
import pool from "../config/db";
import { RowDataPacket } from "mysql2";

export interface LabOverview {
  supervisor: { online: boolean; baseUrl: string; bridgeUrl: string };
  portals: Awaited<ReturnType<typeof PortalModel.findAll>>;
  registry: typeof SCRAPER_REGISTRY;
  probeTargets: typeof PORTAL_PROBE_TARGETS;
  unregisteredScrapers: string[];
  recentRuns: Record<string, unknown>[];
}

export async function getLabOverview(): Promise<LabOverview> {
  const [portals, health] = await Promise.all([PortalModel.findAll(), getSupervisorHealth()]);
  const cfg = supervisorConfig();
  const usedClasses = new Set(portals.map((p) => p.scraper_class));
  const unregisteredScrapers = getScraperClassNames().filter((c) => !usedClasses.has(c));

  const [runRows] = await pool.query<RowDataPacket[]>(
    `SELECT portal, operation_type, status, properties_found, error, started_at, finished_at
       FROM scraping_portal_runs
      WHERE started_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
      ORDER BY started_at DESC
      LIMIT 40`
  );

  return {
    supervisor: { online: health.ok, baseUrl: cfg.baseUrl, bridgeUrl: cfg.bridgeUrl },
    portals,
    registry: SCRAPER_REGISTRY,
    probeTargets: PORTAL_PROBE_TARGETS,
    unregisteredScrapers,
    recentRuns: runRows as Record<string, unknown>[],
  };
}

function summarizeProbes(results: ProbeResult[]): string {
  const lines = results.map((r) => {
    const flag = r.ok ? "OK" : "FAIL";
    return `- [${flag}] ${r.portal} (${r.operation}): ${r.diagnosis} | HTTP ${r.httpStatus ?? "n/a"} | matches=${r.matchCount} | engine=${r.engine}${r.challenge ? " | CHALLENGE" : ""}`;
  });
  const failed = results.filter((r) => !r.ok);
  const header = `Probe ${results.length} portales — ${results.filter((r) => r.ok).length} OK, ${failed.length} fallos`;
  return [header, "", ...lines].join("\n");
}

export async function analyzeProbesWithAi(results: ProbeResult[], focus?: string) {
  const summary = summarizeProbes(results);
  const message = [
    "Eres el analista de scrapers del proyecto Captajaus (Llíria/Valencia, España).",
    "Analiza estos resultados de probe en vivo y responde en español con:",
    "1) Diagnóstico por portal fallido (causa probable)",
    "2) Acciones concretas de fix (selector, Playwright, proxy, JSON fallback…)",
    "3) Prioridad (alta/media/baja)",
    focus ? `\nEnfoque del operador: ${focus}` : "",
    "",
    summary,
  ]
    .filter(Boolean)
    .join("\n");

  const chat = await dispatchChat(message, "ops");
  if (chat.ok && chat.data) {
    return { source: "supervisor" as const, data: chat.data, bridgeUrl: null };
  }

  const rec = await recommendTask(message, "ops");
  if (rec.ok && rec.data) {
    const bridgeUrl = buildBridgeDeepLink(
      ["MODO REVISIÓN — Portal Lab Captajaus", "", message].join("\n")
    );
    return { source: "bridge" as const, data: rec.data, bridgeUrl };
  }

  return {
    source: "offline" as const,
    data: null,
    bridgeUrl: buildBridgeDeepLink(message),
    summary,
  };
}

export async function discoverPortalsWithAi() {
  const overview = await getLabOverview();
  const activeNames = overview.portals.filter((p) => p.active).map((p) => p.name).join(", ");
  const available = overview.unregisteredScrapers.join(", ");
  const message = [
    "Proyecto Captajaus: agregador inmobiliario Llíria + Valencia.",
    `Portales activos en BD: ${activeNames || "ninguno"}`,
    `Scrapers implementados sin registrar: ${available || "ninguno"}`,
    `Clases en registry: ${overview.registry.map((r) => r.className).join(", ")}`,
    "",
    "Responde en español:",
    "1) Qué portales nuevos conviene añadir para Llíria/comarca (priorizados)",
    "2) Qué scraper_class usar de las ya implementadas",
    "3) Riesgo anti-bot estimado",
    "4) Si falta scraper, describe URL patrón y engine recomendado (cheerio/playwright)",
  ].join("\n");

  const chat = await dispatchChat(message, "research");
  if (chat.ok && chat.data) {
    return { source: "supervisor" as const, data: chat.data, bridgeUrl: null };
  }
  return {
    source: "bridge" as const,
    data: recFallback(message),
    bridgeUrl: buildBridgeDeepLink(message),
  };
}

function recFallback(message: string) {
  return { hint: "Supervisor offline — usa Cursor Bridge", prompt: message.slice(0, 500) };
}

export async function commercializeWithAi() {
  const overview = await getLabOverview();
  const stats = overview.portals.map((p) => `${p.name}: ${p.property_count ?? 0} props`).join("; ");
  const message = [
    "Producto: Captajaus / Lliria Properties — scraper + alertas email + dashboard PWA para compradores/inversores inmobiliarios en Llíria y Valencia.",
    `Datos actuales: ${stats}`,
    "",
    "Responde en español como consultor de producto:",
    "1) Público objetivo principal y secundario (personas concretas, no genérico)",
    "2) Propuesta de valor en 2 frases",
    "3) Canales de comercialización (SEO, agencias, WhatsApp, B2B…)",
    "4) Pricing sugerido (freemium, suscripción, white-label)",
    "5) Primer experimento de validación en 7 días",
  ].join("\n");

  const chat = await dispatchChat(message, "research");
  if (chat.ok && chat.data) {
    return { source: "supervisor" as const, data: chat.data, bridgeUrl: null };
  }
  return {
    source: "bridge" as const,
    data: recFallback(message),
    bridgeUrl: buildBridgeDeepLink(message),
  };
}

export { probePortal, probeAllPortals, type ProbeResult };
