import { ResultSetHeader } from "mysql2";
import pool from "../config/db";

export type PortalRunStatus = "running" | "success" | "empty" | "error";

export const ScrapingPortalRunModel = {
  async start(input: {
    portal: string;
    scraperClass: string;
    operation: "sale" | "rent";
    triggerMode: "manual" | "scheduled";
    zoneScope?: string | null;
  }): Promise<number> {
    const [result] = await pool.query<ResultSetHeader>(
      `INSERT INTO scraping_portal_runs
        (portal, scraper_class, operation_type, trigger_mode, zone_scope, status, started_at)
       VALUES (?, ?, ?, ?, ?, 'running', NOW())`,
      [input.portal, input.scraperClass, input.operation, input.triggerMode, input.zoneScope || null]
    );
    return result.insertId;
  },

  async finish(id: number, input: {
    status: Exclude<PortalRunStatus, "running">;
    totalFound: number;
    newSaved: number;
    partialCoverage: boolean;
    error?: string | null;
  }): Promise<void> {
    if (!id) return;
    await pool.query(
      `UPDATE scraping_portal_runs
          SET finished_at = NOW(), status = ?, total_found = ?, new_saved = ?,
              partial_coverage = ?, error = ?
        WHERE id = ?`,
      [input.status, input.totalFound, input.newSaved, input.partialCoverage ? 1 : 0, input.error || null, id]
    );
  },

  /**
   * Cierra runs huérfanos (status=running sin finished_at), p.ej. tras reinicio del proceso.
   * Prefiere cerrar todos los stuck running; no exige antigüedad mínima.
   */
  async closeInterrupted(errorMessage: string): Promise<number> {
    const [result] = await pool.query<ResultSetHeader>(
      `UPDATE scraping_portal_runs
          SET status = 'error', finished_at = NOW(), error = ?
        WHERE status = 'running' AND finished_at IS NULL`,
      [errorMessage]
    );
    return result.affectedRows;
  },
};
