<?php
/**
 * Script d'import des contours départementaux depuis un fichier GeoJSON local
 */

class DepartementContoursFileImporter {
    private PDO $db;
    private array $log = [];
    
    public function __construct(PDO $db) {
        $this->db = $db;
    }
    
    /**
     * Vérifie si la table existe
     */
    public function tableExists(): bool {
        try {
            $sql = "SHOW TABLES LIKE 'x_departements_contours'";
            $stmt = $this->db->query($sql);
            return $stmt->rowCount() > 0;
        } catch (Exception $e) {
            return false;
        }
    }
    
    /**
     * Vérifie si la table est vide
     */
    private function isTableEmpty(): bool {
        try {
            $sql = "SELECT COUNT(*) as count FROM x_departements_contours";
            $stmt = $this->db->query($sql);
            $result = $stmt->fetch();
            return $result['count'] == 0;
        } catch (Exception $e) {
            return true;
        }
    }
    
    /**
     * Importe les départements depuis un fichier GeoJSON
     */
    public function importFromFile(string $filePath): array {
        $this->log[] = "Début de l'import depuis le fichier : $filePath";
        $this->log[] = "";
        
        // Vérifier que le fichier existe
        if (!file_exists($filePath)) {
            $this->log[] = "✗ Fichier non trouvé : $filePath";
            return $this->log;
        }
        
        // Vérifier que la table existe
        if (!$this->tableExists()) {
            $this->log[] = "✗ La table x_departements_contours n'existe pas";
            return $this->log;
        }
        
        // Vérifier que la table est vide
        if (!$this->isTableEmpty()) {
            $this->log[] = "✗ La table x_departements_contours contient déjà des données";
            return $this->log;
        }
        
        // Lire le fichier GeoJSON
        $this->log[] = "Lecture du fichier GeoJSON...";
        $jsonContent = file_get_contents($filePath);
        
        if ($jsonContent === false) {
            $this->log[] = "✗ Impossible de lire le fichier";
            return $this->log;
        }
        
        // Parser le JSON
        $geojson = json_decode($jsonContent, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->log[] = "✗ Erreur JSON : " . json_last_error_msg();
            return $this->log;
        }
        
        if (!isset($geojson['features']) || !is_array($geojson['features'])) {
            $this->log[] = "✗ Format GeoJSON invalide : pas de features";
            return $this->log;
        }
        
        $this->log[] = "✓ Fichier chargé : " . count($geojson['features']) . " départements trouvés";
        $this->log[] = "";
        
        // Préparer la requête d'insertion
        $sql = "INSERT INTO x_departements_contours 
                (code_dept, nom_dept, contour, bbox_min_lat, bbox_max_lat, bbox_min_lng, bbox_max_lng) 
                VALUES 
                (:code, :nom, ST_GeomFromText(:polygon, 4326), :min_lat, :max_lat, :min_lng, :max_lng)";
        
        $stmt = $this->db->prepare($sql);
        
        $success = 0;
        $errors = 0;
        
        // Démarrer une transaction
        $this->db->beginTransaction();
        
        try {
            foreach ($geojson['features'] as $feature) {
                // Extraire les informations
                $code = $feature['properties']['code'] ?? null;
                $nom = $feature['properties']['nom'] ?? null;
                $geometry = $feature['geometry'] ?? null;
                
                if (!$code || !$nom || !$geometry) {
                    $this->log[] = "✗ Données manquantes pour un département";
                    $errors++;
                    continue;
                }
                
                // Convertir la géométrie en WKT
                $wktData = $this->geometryToWkt($geometry);
                
                if (!$wktData) {
                    $this->log[] = "✗ Conversion échouée pour $code ($nom)";
                    $errors++;
                    continue;
                }
                
                try {
                    $stmt->execute([
                        'code' => $code,
                        'nom' => $nom,
                        'polygon' => $wktData['wkt'],
                        'min_lat' => $wktData['bbox']['min_lat'],
                        'max_lat' => $wktData['bbox']['max_lat'],
                        'min_lng' => $wktData['bbox']['min_lng'],
                        'max_lng' => $wktData['bbox']['max_lng']
                    ]);
                    
                    $this->log[] = "✓ $code - $nom importé";
                    $success++;
                    
                } catch (Exception $e) {
                    $this->log[] = "✗ Erreur SQL pour $code ($nom) : " . $e->getMessage();
                    $errors++;
                }
            }
            
            // Valider ou annuler la transaction
            if ($success > 0) {
                $this->db->commit();
                $this->log[] = "";
                $this->log[] = "✓ Transaction validée";
            } else {
                $this->db->rollBack();
                $this->log[] = "";
                $this->log[] = "✗ Transaction annulée (aucun import réussi)";
            }
            
        } catch (Exception $e) {
            $this->db->rollBack();
            $this->log[] = "";
            $this->log[] = "✗ Erreur fatale : " . $e->getMessage();
            $this->log[] = "✗ Transaction annulée";
        }
        
        $this->log[] = "";
        $this->log[] = "Import terminé : $success réussis, $errors erreurs";
        
        return $this->log;
    }
    
    /**
     * Convertit une géométrie GeoJSON en WKT
     */
    private function geometryToWkt(array $geometry): ?array {
        $type = $geometry['type'] ?? null;
        $coordinates = $geometry['coordinates'] ?? null;
        
        if (!$type || !$coordinates) {
            return null;
        }
        
        $wkt = null;
        $allPoints = [];
        
        switch ($type) {
            case 'Polygon':
                // Un seul polygone
                $ring = $coordinates[0]; // Anneau extérieur
                $points = [];
                foreach ($ring as $point) {
                    $points[] = $point[0] . ' ' . $point[1];
                    $allPoints[] = $point;
                }
                $wkt = 'POLYGON((' . implode(',', $points) . '))';
                break;
                
            case 'MultiPolygon':
                // Plusieurs polygones
                $polygons = [];
                foreach ($coordinates as $polygon) {
                    $ring = $polygon[0]; // Anneau extérieur du polygone
                    $points = [];
                    foreach ($ring as $point) {
                        $points[] = $point[0] . ' ' . $point[1];
                        $allPoints[] = $point;
                    }
                    $polygons[] = '((' . implode(',', $points) . '))';
                }
                $wkt = 'MULTIPOLYGON(' . implode(',', $polygons) . ')';
                break;
                
            default:
                return null;
        }
        
        if (!$wkt || empty($allPoints)) {
            return null;
        }
        
        // Calculer la bounding box
        $lats = array_map(function($p) { return $p[1]; }, $allPoints);
        $lngs = array_map(function($p) { return $p[0]; }, $allPoints);
        
        return [
            'wkt' => $wkt,
            'bbox' => [
                'min_lat' => min($lats),
                'max_lat' => max($lats),
                'min_lng' => min($lngs),
                'max_lng' => max($lngs)
            ]
        ];
    }
}

// Si le script est exécuté directement
if (php_sapi_name() === 'cli' && basename(__FILE__) === basename($_SERVER['PHP_SELF'] ?? __FILE__)) {
    require_once __DIR__ . '/../src/Config/AppConfig.php';
    require_once __DIR__ . '/../src/Core/Database.php';
    
    // Chemin vers le fichier GeoJSON
    $filePath = __DIR__ . '/../docs/contour-des-departements.geojson';
    
    // Vérifier les arguments
    if ($argc > 1) {
        $filePath = $argv[1];
    }
    
    echo "Import des contours départementaux depuis un fichier\n";
    echo "==================================================\n\n";
    echo "Fichier : $filePath\n\n";
    
    $appConfig = AppConfig::getInstance();
    Database::init($appConfig->getDatabaseConfig());
    $db = Database::getInstance();
    
    $importer = new DepartementContoursFileImporter($db);
    $log = $importer->importFromFile($filePath);
    
    foreach ($log as $line) {
        echo $line . "\n";
    }
}