const fs = require('fs');
const path = require('path');
// Assurez-vous que le chemin d'accès à votre pool de connexion DB est correct
const {
  pool
} = require('../db');

/**
 * Gère la logique de classification des véhicules selon les règles TARES
 * et la validation/lookup des VIN.
 * * NOTE: Les règles TARES (taresRules) et la classification s'attendent à être passées
 * par le contrôleur ou lues à l'initialisation du serveur,
 * car la classe n'est plus chargée statiquement par le constructeur.
 */
class TaresClassifier {

  // Suppression du constructeur qui lisait statiquement les fichiers.

  normalizeFuelType(fuelType) {
    if (!fuelType) return 'essence';
    const normalized = fuelType.toLowerCase().trim();

    // La nouvelle logique de normalisation est plus simple et utilise des sous-chaînes
    if (normalized.includes('plug')) return 'hybride_plugin';
    if (normalized.includes('hybr')) return 'hybride';
    if (normalized.includes('elec') || normalized.includes('élec')) return 'electrique';
    if (normalized.includes('dies')) return 'diesel';
    if (normalized.includes('ess') || normalized.includes('petrol') || normalized.includes('gasoline')) return 'essence';

    return normalized;
  }

  matchesRule(fuel, cylinder, weightEmpty, rule) {
    if (rule.fuel && rule.fuel !== fuel) return false;

    if (rule.cylinder_min !== undefined && cylinder < rule.cylinder_min) return false;
    if (rule.cylinder_max !== undefined && cylinder > rule.cylinder_max) return false;

    // Utilisation de weightEmpty (poids à vide) pour la classification
    if (rule.weight_min !== undefined && weightEmpty < rule.weight_min) return false;
    if (rule.weight_max !== undefined && weightEmpty > rule.weight_max) return false;

    return true;
  }

  /**
   * Tente de classer le véhicule en utilisant les règles de configuration fournies.
   * Si aucune correspondance n'est trouvée, retourne une erreur.
   * @param {object} vehicleData - Données du véhicule (fuel_type, cc, weight, etc.)
   * @param {object} taresRules - Les règles TARES lues depuis le fichier de configuration (passées par l'appelant)
   */
  async classify(vehicleData, taresRules = {}) {
    const fuelType = this.normalizeFuelType(vehicleData.fuel_type || 'essence');
    const cc = parseInt(vehicleData.cylinder_capacity || 0, 10);
    const wEmpty = parseInt(vehicleData.weight_empty || 0, 10);
    const wTotal = parseInt(vehicleData.weight_total || 0, 10);

    // 1. Tente d'appliquer les règles de configuration (Règles TARES)
    for (const [code, rule] of Object.entries(taresRules || {})) {
      if (this.matchesRule(fuelType, cc, wEmpty, rule)) {
        const {
          statistical_keys = {
            '911': 'Automobile'
          }, description = 'Véhicule'
        } = rule;
        const {
          key,
          needs_user_selection,
          description: skDesc,
          available_keys
        } = this.selectStatisticalKey(statistical_keys, wTotal);

        return {
          commodity_code: code,
          description,
          statistical_key: needs_user_selection ? null : key,
          statistical_key_description: needs_user_selection ? null : (skDesc || statistical_keys[key]),
          needs_user_selection,
          available_keys: needs_user_selection ? statistical_keys : null
        };
      }
    }

    // RETOUR D'ERREUR si aucune correspondance n'est trouvée dans les règles TARES
    return {
      error: "Correspondance non trouvée",
      message: "Aucune règle TARES fournie ne correspond aux données de ce véhicule."
    };
  }

  selectStatisticalKey(keys, weightTotal) {
    if (!keys || Object.keys(keys).length === 0) return {
      key: '911',
      description: 'Automobile',
      needs_user_selection: false,
      available_keys: null
    };

    // Cas 1: Une seule clé disponible
    if (Object.keys(keys).length === 1) {
      const k = Object.keys(keys)[0];
      return {
        key: k,
        description: keys[k],
        needs_user_selection: false,
        available_keys: null
      };
    }

    // Cas 2: Sélection automatique basée sur le Poids Total (ex: 921 > 3500kg, 923 <= 3500kg)
    if (keys['921'] && keys['923']) {
      return weightTotal > 3500 ?
        {
          key: '921',
          description: keys['921'],
          needs_user_selection: false,
          available_keys: null
        } :
        {
          key: '923',
          description: keys['923'],
          needs_user_selection: false,
          available_keys: null
        };
    }
    // Ajout d'une gestion pour les codes électriques 926/927
    if (keys['926'] && keys['927']) {
      return weightTotal > 3500 ?
        {
          key: '926',
          description: keys['926'],
          needs_user_selection: false,
          available_keys: null
        } :
        {
          key: '927',
          description: keys['927'],
          needs_user_selection: false,
          available_keys: null
        };
    }

    // Cas 3: Sélection manuelle requise (si plus d'une clé n'ayant pas de logique d'auto-sélection)
    return {
      key: null,
      description: null,
      needs_user_selection: true,
      available_keys: keys
    };
  }

  /**
   * Récupère le pays de fabrication (WMI) à partir du VIN en utilisant la base de données.
   * @param {string} vin - Numéro d'identification du véhicule.
   * @returns {Promise<string|null>} - Code pays (ex: 'FR') ou null.
   */
  async getCountryFromVIN_DB(vin) {
    if (!vin || vin.length < 2) return null;
    const wmi = vin.substring(0, 2).toUpperCase();

    // Utilisation du pool pour la connexion à la base de données
    const conn = await pool.getConnection();
    try {
      const [rows] = await conn.execute(`
		SELECT country_code FROM vin_wmi_country_codes
		WHERE ? BETWEEN wmi_start AND wmi_end
		LIMIT 1
		`, [wmi]);

      // Assurez-vous d'avoir des colonnes 'wmi_start', 'wmi_end' et 'country_code' dans votre table SQL.
      return rows?.[0]?.country_code || null;
    } catch (error) {
      console.error("Erreur DB WMI:", error.message);
      return null;
    } finally {
      if (conn) conn.release();
    }
  }
}

// Exportation en tant qu'instance unique (Singleton)
module.exports = new TaresClassifier();
