<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Headers CORS
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
// Gestion des requêtes OPTIONS (Preflight)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}
// Inclusions des dépendances
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../models/OperationModel.php';
require_once __DIR__ . '/NotificationController.php';
class OperationController {
    private $model;
    private $pdo;
    private $notificationController;
    public function __construct($pdo) {
        $this->pdo = $pdo;
        $this->model = new OperationModel($pdo);
        $this->notificationController = new NotificationController($pdo);
    }
    /**
     * Routeur principal
     */
    public function handleRequest() {
        try {
            $method = $_SERVER['REQUEST_METHOD'];
            $action = $_GET['action'] ?? '';
            $id = $_GET['id'] ?? null;
            // Log pour le débogage
            error_log("Method: $method, Action: $action, ID: " . ($id ?? 'null'));
            switch ($method) {
                case 'GET':
                    $this->handleGetRequest($action, $id);
                    break;
                case 'POST':
                    $this->handlePostRequest($action);
                    break;
                case 'DELETE':
                    $this->handleDeleteRequest($action, $id);
                    break;
                default:
                    $this->sendResponse(405, false, "Méthode non autorisée");
            }
        } catch (Exception $e) {
            error_log("Erreur dans handleRequest: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur serveur: " . $e->getMessage());
        }
    }
    /**
     * Gestion des requêtes GET
     */
    private function handleGetRequest($action, $id) {
        switch ($action) {
            case 'all':
                $this->getAll();
                break;
            case 'details':
                $this->getById($id);
                break;
            case 'stats':
                $this->getStats();
                break;
            case 'by_date':
                $this->getByDateRange();
                break;
            default:
                $this->sendResponse(404, false, "Action GET inconnue");
        }
    }
    /**
     * Gestion des requêtes POST
     */
    private function handlePostRequest($action) {
        $input = $this->getJsonInput();
        
        switch ($action) {
            case 'add':
                $this->add($input);
                break;
            case 'update':
                $this->update($input);
                break;
            case 'delete': // Alternative pour la suppression via POST
                $this->delete($input['id'] ?? null);
                break;
            case 'generer_cotisations_initiales':
                $this->genererCotisationsInitiales($input);
                break;
            default:
                $this->sendResponse(404, false, "Action POST inconnue");
        }
    }
    /**
     * Gestion des requêtes DELETE
     */
    private function handleDeleteRequest($action, $id) {
        switch ($action) {
            case 'delete':
                $this->delete($id);
                break;
            default:
                $this->sendResponse(404, false, "Action DELETE inconnue");
        }
    }
    /**
     * Récupère toutes les opérations
     */
    public function getAll() {
        try {
            $excludeDons = filter_var($_GET['exclude_dons'] ?? false, FILTER_VALIDATE_BOOLEAN);
            $data = $this->model->getAll($excludeDons);
            $this->sendResponse(200, true, "Opérations récupérées", $data);
        } catch (Exception $e) {
            error_log("Erreur dans getAll: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur lors de la récupération");
        }
    }
    /**
     * Récupère une opération par ID
     */
    public function getById($id) {
        if (!$this->validateId($id)) {
            $this->sendResponse(400, false, "ID invalide");
        }
        try {
            $data = $this->model->getById($id);
            if ($data) {
                $this->sendResponse(200, true, "Opération trouvée", $data);
            } else {
                $this->sendResponse(404, false, "Opération non trouvée");
            }
        } catch (Exception $e) {
            error_log("Erreur dans getById: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur lors de la recherche");
        }
    }
    /**
     * Récupère les statistiques
     */
    public function getStats() {
        try {
            $stats = $this->model->getFinancialStats();
            $this->sendResponse(200, true, "Statistiques récupérées", $stats);
        } catch (Exception $e) {
            error_log("Erreur dans getStats: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur lors du calcul des stats");
        }
    }
    /**
     * Récupère les opérations par période
     */
    public function getByDateRange() {
        $startDate = $_GET['start'] ?? null;
        $endDate = $_GET['end'] ?? null;
        if (!$startDate || !$endDate) {
            $this->sendResponse(400, false, "Dates start et end requises");
        }
        try {
            $excludeDons = filter_var($_GET['exclude_dons'] ?? true, FILTER_VALIDATE_BOOLEAN);
            $data = $this->model->getByDateRange($startDate, $endDate, $excludeDons);
            $this->sendResponse(200, true, "Opérations par période", $data);
        } catch (Exception $e) {
            error_log("Erreur dans getByDateRange: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur lors de la recherche");
        }
    }
    /**
     * Ajoute une nouvelle opération
     */
    public function add($data) {
        // Validation des champs requis
        $required = ['type', 'categorie_id', 'montant', 'date_operation'];
        foreach ($required as $field) {
            if (!isset($data[$field]) || $data[$field] === '') {
                $this->sendResponse(400, false, "Champ requis manquant: $field");
            }
        }
        // Extraction et validation des données
        $type = $data['type'];
        $categorieId = (int)$data['categorie_id'];
        $membreId = isset($data['membre_id']) ? (int)$data['membre_id'] : null;
        $montant = (float)$data['montant'];
        $dateOperation = $data['date_operation'];
        $description = $data['description'] ?? null;
        // Validation des données
        if ($montant < 0) {
            $this->sendResponse(400, false, "Le montant doit être positif");
        }
        if ($categorieId <= 0) {
            $this->sendResponse(400, false, "Catégorie invalide");
        }
        // Vérification pour les cotisations mensuelles
        if ($this->isCotisationMensuelle($categorieId)) {
            if (!$membreId || $membreId <= 0) {
                $this->sendResponse(400, false, "Membre requis pour une cotisation");
            }
            if (!$this->membreExists($membreId)) {
                $this->sendResponse(400, false, "Membre non trouvé");
            }
        }
        try {
            $result = $this->model->add(
                $type,
                $categorieId,
                $membreId,
                $montant,
                $dateOperation,
                $description
            );
            if ($result["success"]) {
                // Notification si membre associé
                if ($membreId) {
                    $this->sendNotification(
                        $membreId,
                        "Nouvelle Opération",
                        "Une opération de {$montant} FCFA a été ajoutée",
                        'operation_ajoutee',
                        $result['id'] ?? null
                    );
                }
                $this->sendResponse(201, true, "Opération ajoutée", $result);
            } else {
                $this->sendResponse(500, false, "Erreur lors de l'ajout");
            }
        } catch (Exception $e) {
            error_log("Erreur dans add: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur serveur: " . $e->getMessage());
        }
    }
    /**
     * Met à jour une opération
     */
    public function update($data) {
        // Validation des champs requis
        if (!isset($data['id']) || $data['id'] <= 0) {
            $this->sendResponse(400, false, "ID d'opération invalide");
        }
        $required = ['type', 'categorie_id', 'montant', 'date_operation'];
        foreach ($required as $field) {
            if (!isset($data[$field]) || $data[$field] === '') {
                $this->sendResponse(400, false, "Champ requis manquant: $field");
            }
        }
        // Extraction des données
        $id = (int)$data['id'];
        $type = $data['type'];
        $categorieId = (int)$data['categorie_id'];
        $membreId = isset($data['membre_id']) ? (int)$data['membre_id'] : null;
        $montant = (float)$data['montant'];
        $dateOperation = $data['date_operation'];
        $description = $data['description'] ?? null;
        // Validation des données
        if ($montant < 0) {
            $this->sendResponse(400, false, "Le montant doit être positif");
        }
        // Vérification pour les cotisations mensuelles
        if ($this->isCotisationMensuelle($categorieId)) {
            if (!$membreId || $membreId <= 0) {
                $this->sendResponse(400, false, "Membre requis pour une cotisation");
            }
            if (!$this->membreExists($membreId)) {
                $this->sendResponse(400, false, "Membre non trouvé");
            }
        }
        try {
            $result = $this->model->update(
                $id,
                $type,
                $categorieId,
                $membreId,
                $montant,
                $dateOperation,
                $description
            );
            if ($result["success"]) {
                // Notification si membre associé
                if ($membreId) {
                    $this->sendNotification(
                        $membreId,
                        "Opération Modifiée",
                        "Une opération a été mise à jour",
                        'operation_modifiee',
                        $id
                    );
                }
                $this->sendResponse(200, true, "Opération modifiée", $result);
            } else {
                $this->sendResponse(500, false, "Erreur lors de la modification");
            }
        } catch (Exception $e) {
            error_log("Erreur dans update: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur serveur: " . $e->getMessage());
        }
    }
    /**
     * Supprime une opération
     */
    public function delete($id) {
        if (!$this->validateId($id)) {
            $this->sendResponse(400, false, "ID invalide pour la suppression");
        }
        try {
            // Vérifier si l'opération existe
            $operation = $this->model->getById($id);
            if (!$operation) {
                $this->sendResponse(404, false, "Opération non trouvée");
            }
            $result = $this->model->delete($id);
            
            if ($result["success"]) {
                $this->sendResponse(200, true, "Opération supprimée");
            } else {
                $this->sendResponse(500, false, "Erreur lors de la suppression");
            }
        } catch (Exception $e) {
            error_log("Erreur dans delete: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur serveur: " . $e->getMessage());
        }
    }
    /**
     * Génère automatiquement les cotisations initiales pour un membre
     * depuis Janvier 2025 jusqu'à la date spécifiée
     */
    public function genererCotisationsInitiales($data) {
        // Validation des champs requis
        if (!isset($data['membre_id']) || !isset($data['date_debut_cotisation'])) {
            $this->sendResponse(400, false, "Paramètres manquants: membre_id et date_debut_cotisation requis");
        }
        $membreId = (int)$data['membre_id'];
        $dateDebutCotisation = trim($data['date_debut_cotisation']);
        
        // Lecture du paramètre optionnel comptabiliser
        $comptabiliser = isset($data['comptabiliser']) ? filter_var($data['comptabiliser'], FILTER_VALIDATE_BOOLEAN) : true;
        // Validation du format YYYY-MM
        if (!preg_match('/^\d{4}-\d{2}$/', $dateDebutCotisation)) {
            $this->sendResponse(400, false, "Format de date invalide. Utilisez YYYY-MM (ex: 2026-12)");
        }
        // Vérifier que le membre existe
        if (!$this->membreExists($membreId)) {
            $this->sendResponse(404, false, "Membre non trouvé");
        }
        try {
            $result = $this->model->genererCotisationsInitiales($membreId, $dateDebutCotisation, $comptabiliser);
            
            if ($result['success']) {
                // Notification au membre
                $this->sendNotification(
                    $membreId,
                    "Cotisations Générées",
                    $result['message'],
                    'cotisations_generees',
                    null
                );
                
                $this->sendResponse(200, true, $result['message'], [
                    'mois_generes' => $result['mois_generes'] ?? 0
                ]);
            } else {
                $this->sendResponse(400, false, $result['message']);
            }
        } catch (Exception $e) {
            error_log("Erreur dans genererCotisationsInitiales: " . $e->getMessage());
            $this->sendResponse(500, false, "Erreur serveur: " . $e->getMessage());
        }
    }
    /**
     * Méthodes utilitaires
     */
    private function getJsonInput() {
        $input = file_get_contents("php://input");
        error_log("Input reçu: " . $input);
        
        $data = json_decode($input, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->sendResponse(400, false, "JSON invalide");
        }
        return $data;
    }
    private function sendResponse($code, $success, $message, $data = null) {
        http_response_code($code);
        $response = [
            'success' => $success,
            'message' => $message,
            'timestamp' => date('c')
        ];
        
        if ($data !== null) {
            $response['data'] = $data;
        }
        
        echo json_encode($response);
        exit();
    }
    private function validateId($id) {
        return $id !== null && is_numeric($id) && $id > 0;
    }
    private function sendNotification($membreId, $title, $message, $type, $operationId = null) {
        try {
            $this->notificationController->sendNotificationToMember(
                $membreId,
                $title,
                $message,
                ['type' => $type, 'operation_id' => $operationId]
            );
            error_log("Notification envoyée au membre $membreId");
        } catch (Exception $e) {
            error_log("Échec notification: " . $e->getMessage());
        }
    }
    private function isCotisationMensuelle($categorieId) {
        try {
            $stmt = $this->pdo->prepare("SELECT nom FROM categories WHERE id = ? LIMIT 1");
            $stmt->execute([$categorieId]);
            $category = $stmt->fetch(PDO::FETCH_ASSOC);
            return $category && strtolower(trim($category['nom'])) === 'cotisations membres';
        } catch (Exception $e) {
            error_log("Erreur isCotisationMensuelle: " . $e->getMessage());
            return false;
        }
    }
    private function membreExists($membreId) {
        try {
            $stmt = $this->pdo->prepare("SELECT id FROM membres WHERE id = ? AND statut = 'actif' LIMIT 1");
            $stmt->execute([$membreId]);
            return $stmt->fetch() !== false;
        } catch (Exception $e) {
            error_log("Erreur membreExists: " . $e->getMessage());
            return false;
        }
    }
}
// Exécution de l'application
try {
    $database = new Database();
    $pdo = $database->getConnection();
    $controller = new OperationController($pdo);
    $controller->handleRequest();
} catch (Exception $e) {
    error_log("Erreur initialisation: " . $e->getMessage());
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Erreur initialisation serveur',
        'timestamp' => date('c')
    ]);
}