// src/services/gravity-forms-service.ts
import axios, { AxiosInstance } from "axios";
import qs from "qs";
import crypto from "crypto";
import {
  wpBaseUrl,
  gfApiKey,
  gfApiSecret,
  wpUsername,
  wpAppPassword,
} from "../utils/env";

export interface GFormEntry {
  id: string;
  form_id: string;
  date_created: string;
  [key: string]: any;
}

export interface FilteredFormEntry {
  id: string;
  form_id: string;
  date_created: string;
  nom?: string;
  prenom?: string;
  nationalite?: string;
  telephone?: string;
  email?: string;
  projet?: string;
  ville?: string;
  formation?: string;
  besoins?: string;
  is_legit: boolean;
  is_spam: boolean;
  status: "active" | "spam" | "trash";
  source: "gravity_forms";
}

export class GravityFormsService {
  private client: AxiosInstance;

  constructor() {
    const useKeySecret = !!gfApiKey && !!gfApiSecret;

    if (useKeySecret) {
      console.log(
        "🔑 Utilisation GF_API_KEY/GF_API_SECRET pour Gravity Forms"
      );
    } else {
      console.log(
        "🔑 Utilisation WP_USERNAME/WP_APP_PASSWORD pour Gravity Forms"
      );
    }

    this.client = axios.create({
      baseURL: `${wpBaseUrl}/wp-json/gf/v2`,
      timeout: 60000, // 60 secondes
      headers: {
        "Content-Type": "application/json",
        ...(useKeySecret
          ? {}
          : {
              Authorization:
                "Basic " +
                Buffer.from(`${wpUsername}:${wpAppPassword}`).toString(
                  "base64"
                ),
            }),
      },
      paramsSerializer: (params) =>
        qs.stringify(params, {
          arrayFormat: "indices",
          encode: true,
        }),
    });

    // Intercepteur pour signature HMAC (key/secret)
    if (useKeySecret) {
      this.client.interceptors.request.use((config) => {
        const method = (config.method || "get").toUpperCase();
        const route = config.url || "";
        const expires = Math.floor(Date.now() / 1000) + 60; // 60 secondes
        const stringToSign = `${gfApiKey}:${method}:${route}:${expires}`;
        const signature = crypto
          .createHmac("sha1", gfApiSecret)
          .update(stringToSign)
          .digest("base64");

        config.params = {
          ...(config.params || {}),
          api_key: gfApiKey,
          signature,
          expires,
        };

        return config;
      });
    }
  }

  /**
   * Détection simple de spam :
   *  - mots-clés BTC/bitcoin, graph.org, telegra.ph, carrotquest-mail.io, binance
   *  - présence d’emoji dans les textes
   */
   private detectSpam(entry: GFormEntry): boolean {
    const ignoredKeys = new Set(["id", "form_id", "date_created"]);

    const text = Object.keys(entry)
      .filter((k) => !ignoredKeys.has(k))
      .map((k) => {
        const v = entry[k];
        return typeof v === "string" ? v : JSON.stringify(v);
      })
      .join(" ")
      .toLowerCase();

    // Filtrage basé sur les spams observés (BTC, liens externes)
    const hasBtcKeywords =
      /btc|bitcoin|graph\.org|telegra\.ph|carrotquest-mail\.io|binance/i.test(
        text
      );

    // On ne bloque PAS sur la présence d’émojis, ni sur la langue (arabe, etc.)
    return hasBtcKeywords;
  }

  private cleanEntry(entry: GFormEntry, formId: string): FilteredFormEntry {
    const spamFromFields = this.detectSpam(entry);
    const spamFromFlags = !!entry["is_spam"] || !!entry["status_spam"];

    const is_spam = spamFromFields || spamFromFlags;
    const is_legit = !is_spam;

    // Mapping spécifique Business Plan (ID 7)
    if (formId === "7") {
      return {
        id: entry.id,
        form_id: entry.form_id,
        date_created: entry.date_created,
        nom: entry["1"] || entry["nom"] || "",
        prenom: entry["2"] || entry["prenom"] || "",
        nationalite: entry["3"] || entry["nationalite"] || "",
        telephone: entry["4"] || entry["telephone"] || "",
        email: entry["5"] || entry["email"] || "",
        projet: entry["6"] || entry["projet"] || "",
        ville: entry["7"] || entry["ville"] || "",
        formation: entry["8"] || entry["formation"] || "",
        besoins: entry["9"] || entry["besoins"] || "",
        is_legit,
        is_spam,
        status: is_spam ? "spam" : (entry["status"] as any) || "active",
        source: "gravity_forms",
      };
    }

    // Fallback générique (autres formulaires 6, 8, 9, 10, 11, etc.)
    return {
      id: entry.id,
      form_id: entry.form_id,
      date_created: entry.date_created,
      is_legit,
      is_spam,
      status: is_spam ? "spam" : (entry["status"] as any) || "active",
      source: "gravity_forms",
    };
  }

  async getFormEntries(formId: string): Promise<FilteredFormEntry[]> {
    try {
      console.log(`🔄 Récupération entrées formulaire ${formId}...`);

      const response = await this.client.get(`/forms/${formId}/entries`, {
        params: {
          paging: {
            page_size: 50,
            current_page: 1,
          },
        },
      });

      const entries: GFormEntry[] = response.data.entries || [];

      console.log(`📊 ${entries.length} entrées brutes récupérées`);

      const cleanedEntries = entries.map((entry) =>
        this.cleanEntry(entry, formId)
      );

      const legitEntries = cleanedEntries.filter((entry) => entry.is_legit);

      console.log(
        `✅ ${legitEntries.length}/${entries.length} entrées valides après filtrage (sans BTC / emojis)`
      );

      // On renvoie toutes les entrées, mais les contrôleurs filtrent sur is_legit
      return cleanedEntries;
    } catch (error: any) {
      if (error.code === "ECONNABORTED") {
        console.error(
          `⏱️ Timeout Gravity Forms pour le formulaire ${formId}`
        );
        throw new Error(`GF_TIMEOUT_FORM_${formId}`);
      }

      console.error(
        `❌ Erreur récupération entrées ${formId}:`,
        error.message
      );
      throw error;
    }
  }

  async getAllForms(): Promise<any> {
    try {
      console.log("🔍 Récupération liste des formulaires Gravity Forms...");

      const response = await this.client.get(`/forms`);
      const forms = response.data || [];

      console.log(`📋 ${Object.keys(forms).length} formulaires récupérés`);

      return forms;
    } catch (error: any) {
      if (error.code === "ECONNABORTED") {
        console.error("⏱️ Timeout Gravity Forms sur /forms");
        throw new Error("GF_TIMEOUT_FORMS");
      }

      console.error("❌ Erreur récupération formulaires:", error.message);
      throw error;
    }
  }
}

export const gravityFormsService = new GravityFormsService();
