<?php

declare(strict_types=1);

namespace App\Services;

require_once __DIR__ . '/ApiService.php';
require_once __DIR__ . '/LogService.php';

use PDO;

class OperationDataService {

    /**
     * Prépare les données d'opération selon l'interface et le rôle utilisateur
     * 
     * @param PDO $db Instance de la base de données
     * @param int $entiteId ID de l'entité
     * @param string $interface 'user' ou 'admin'
     * @param int $userRole Rôle de l'utilisateur
     * @param int $userId ID de l'utilisateur connecté
     * @param int|null $specificOperationId ID d'opération spécifique (pour création d'opération)
     * @return array Données formatées avec operations, sectors, users_sectors, passages
     */
    public static function prepareOperationData(
        PDO $db,
        int $entiteId,
        string $interface,
        int $userRole,
        int $userId,
        ?int $specificOperationId = null
    ): array {

        $operationsData = [];
        $sectorsData = [];
        $passagesData = [];
        $usersSectorsData = [];

        // 1. Récupération des opérations selon les critères
        $operationLimit = 0;
        $activeOperationOnly = false;

        if ($interface === 'user') {
            // Interface utilisateur : seulement la dernière opération active
            $operationLimit = 1;
            $activeOperationOnly = true;
        } elseif ($interface === 'admin' && $userRole == 2) {
            // Interface admin avec rôle 2 : les 3 dernières opérations dont l'active
            $operationLimit = 3;
        } elseif ($interface === 'admin' && $userRole > 2) {
            // Super admin : les 3 dernières opérations
            $operationLimit = 3;
        } else {
            // Autres cas : pas d'opérations
            $operationLimit = 0;
        }

        // Si une opération spécifique est demandée (création d'opération)
        if ($specificOperationId) {
            $operationQuery = "SELECT id, fk_entite, libelle, date_deb, date_fin, chk_active 
                               FROM operations 
                               WHERE fk_entite = ?
                               ORDER BY id DESC LIMIT 3";

            $operationStmt = $db->prepare($operationQuery);
            $operationStmt->execute([$entiteId]);
            $operations = $operationStmt->fetchAll(PDO::FETCH_ASSOC);
            $activeOperationId = $specificOperationId;
        } elseif ($operationLimit > 0) {
            $operationQuery = "SELECT id, fk_entite, libelle, date_deb, date_fin, chk_active 
                               FROM operations 
                               WHERE fk_entite = ?";

            if ($activeOperationOnly) {
                $operationQuery .= " AND chk_active = 1";
            }

            $operationQuery .= " ORDER BY id DESC LIMIT " . $operationLimit;

            $operationStmt = $db->prepare($operationQuery);
            $operationStmt->execute([$entiteId]);
            $operations = $operationStmt->fetchAll(PDO::FETCH_ASSOC);

            // Récupérer l'ID de l'opération active (première opération retournée ou celle avec chk_active=1)
            $activeOperationId = null;
            if (!empty($operations)) {
                foreach ($operations as $operation) {
                    if ($operation['chk_active'] == 1) {
                        $activeOperationId = (int)$operation['id'];
                        break;
                    }
                }
                // Si aucune opération active trouvée, prendre la première
                if (!$activeOperationId) {
                    $activeOperationId = (int)$operations[0]['id'];
                }
            }
        } else {
            $operations = [];
            $activeOperationId = null;
        }

        if (!empty($operations)) {
            // Formater les données des opérations
            foreach ($operations as $operation) {
                $operationsData[] = [
                    'id' => $operation['id'],
                    'fk_entite' => $operation['fk_entite'],
                    'libelle' => $operation['libelle'],
                    'date_deb' => $operation['date_deb'],
                    'date_fin' => $operation['date_fin'],
                    'chk_active' => $operation['chk_active']
                ];
            }

            // 2. Récupérer les secteurs selon l'interface et le rôle
            if ($activeOperationId) {
                if ($interface === 'user') {
                    // Interface utilisateur : seulement les secteurs affectés à l'utilisateur
                    $sectorsStmt = $db->prepare(
                        'SELECT s.id, s.libelle, s.color, s.sector
                        FROM ope_sectors s 
                        JOIN ope_users_sectors us ON s.id = us.fk_sector 
                        WHERE us.fk_operation = ? AND us.fk_user = ? AND us.chk_active = 1 AND s.chk_active = 1'
                    );
                    $sectorsStmt->execute([$activeOperationId, $userId]);
                } elseif ($interface === 'admin' && ($userRole == 2 || $userRole > 2)) {
                    // Interface admin : tous les secteurs distincts de l'opération
                    $sectorsStmt = $db->prepare(
                        'SELECT DISTINCT s.id, s.libelle, s.color, s.sector
                        FROM ope_sectors s 
                        WHERE s.fk_operation = ? AND s.chk_active = 1'
                    );
                    $sectorsStmt->execute([$activeOperationId]);
                } else {
                    $sectors = [];
                }

                // Récupération des secteurs si une requête a été préparée
                if (isset($sectorsStmt)) {
                    $sectors = $sectorsStmt->fetchAll(PDO::FETCH_ASSOC);
                } else {
                    $sectors = [];
                }

                if (!empty($sectors)) {
                    $sectorsData = $sectors;

                    // 3. Récupérer les passages selon l'interface et le rôle
                    if ($interface === 'user' && !empty($sectors)) {
                        // Interface utilisateur : passages liés aux secteurs de l'utilisateur
                        $sectorIds = array_column($sectors, 'id');
                        $sectorIdsString = implode(',', $sectorIds);

                        if (!empty($sectorIdsString)) {
                            $passagesStmt = $db->prepare(
                                "SELECT id, fk_operation, fk_sector, fk_user, fk_type, fk_adresse, passed_at, numero, rue, rue_bis, ville, residence, fk_habitat, appt, niveau, 
                                gps_lat, gps_lng, nom_recu, encrypted_name, remarque, encrypted_email, encrypted_phone, montant, fk_type_reglement, email_erreur, nb_passages,
                                chk_email_sent, docremis, date_repasser, chk_mobile, anomalie, created_at, updated_at, chk_active
                                FROM ope_pass 
                                WHERE fk_operation = ? AND fk_sector IN ($sectorIdsString) AND chk_active = 1"
                            );
                            $passagesStmt->execute([$activeOperationId]);
                        }
                    } elseif ($interface === 'admin' && ($userRole == 2 || $userRole > 2)) {
                        // Interface admin : tous les passages de l'opération
                        $passagesStmt = $db->prepare(
                            "SELECT id, fk_operation, fk_sector, fk_user, fk_type, fk_adresse, passed_at, numero, rue, rue_bis, ville, residence, fk_habitat, appt, niveau, 
                            gps_lat, gps_lng, nom_recu, encrypted_name, remarque, encrypted_email, encrypted_phone, montant, fk_type_reglement, email_erreur, nb_passages,
                            chk_email_sent, docremis, date_repasser, chk_mobile, anomalie, created_at, updated_at, chk_active
                            FROM ope_pass 
                            WHERE fk_operation = ? AND chk_active = 1"
                        );
                        $passagesStmt->execute([$activeOperationId]);
                    } else {
                        $passages = [];
                    }

                    // Récupération des passages si une requête a été préparée
                    if (isset($passagesStmt)) {
                        $passages = $passagesStmt->fetchAll(PDO::FETCH_ASSOC);
                    } else {
                        $passages = [];
                    }

                    if (!empty($passages)) {
                        // Déchiffrer les données sensibles
                        foreach ($passages as &$passage) {
                            // Déchiffrement du nom
                            $passage['name'] = '';
                            if (!empty($passage['encrypted_name'])) {
                                $passage['name'] = ApiService::decryptData($passage['encrypted_name']);
                            }
                            unset($passage['encrypted_name']);

                            // Déchiffrement de l'email
                            $passage['email'] = '';
                            if (!empty($passage['encrypted_email'])) {
                                $decryptedEmail = ApiService::decryptSearchableData($passage['encrypted_email']);
                                if ($decryptedEmail) {
                                    $passage['email'] = $decryptedEmail;
                                }
                            }
                            unset($passage['encrypted_email']);

                            // Déchiffrement du téléphone
                            $passage['phone'] = '';
                            if (!empty($passage['encrypted_phone'])) {
                                $passage['phone'] = ApiService::decryptData($passage['encrypted_phone']);
                            }
                            unset($passage['encrypted_phone']);
                        }
                        $passagesData = $passages;
                    }

                    // 4. Récupérer les utilisateurs des secteurs partagés
                    if (($interface === 'user' || ($interface === 'admin' && ($userRole == 2 || $userRole > 2))) && !empty($sectors)) {
                        $sectorIds = array_column($sectors, 'id');
                        $sectorIdsString = implode(',', $sectorIds);

                        if (!empty($sectorIdsString)) {
                            // Utiliser ope_users au lieu de users pour avoir les données historiques
                            $usersSectorsStmt = $db->prepare(
                                "SELECT DISTINCT ou.fk_user as user_id, ou.id as ope_user_id, ou.first_name, ou.encrypted_name, ou.sect_name, us.fk_sector
                                FROM ope_users ou
                                JOIN ope_users_sectors us ON ou.id = us.fk_user AND ou.fk_operation = us.fk_operation
                                WHERE us.fk_sector IN ($sectorIdsString)
                                AND us.fk_operation = ?
                                AND us.chk_active = 1
                                AND ou.chk_active = 1
                                AND ou.fk_user != ?" // Exclure l'utilisateur connecté
                            );
                            $usersSectorsStmt->execute([$activeOperationId, $userId]);
                            $usersSectors = $usersSectorsStmt->fetchAll(PDO::FETCH_ASSOC);

                            if (!empty($usersSectors)) {
                                // Déchiffrer les noms des utilisateurs
                                foreach ($usersSectors as &$userSector) {
                                    if (!empty($userSector['encrypted_name'])) {
                                        $userSector['name'] = ApiService::decryptData($userSector['encrypted_name']);
                                        unset($userSector['encrypted_name']);
                                    }
                                }
                                $usersSectorsData = $usersSectors;
                            }
                        }
                    }
                }
            }
        }

        return [
            'operations' => $operationsData,
            'sectors' => $sectorsData,
            'users_sectors' => $usersSectorsData,
            'passages' => $passagesData
        ];
    }

    /**
     * Prépare la réponse complète pour la création d'opération
     * 
     * @param PDO $db Instance de la base de données
     * @param int $newOpeId ID de la nouvelle opération
     * @param int $entiteId ID de l'entité
     * @return array Réponse formatée avec status, message, operation_id et données
     */
    public static function prepareOperationResponse(PDO $db, int $newOpeId, int $entiteId): array {
        // Utiliser le rôle admin pour récupérer toutes les données
        $operationData = self::prepareOperationData($db, $entiteId, 'admin', 2, 0, $newOpeId);

        return [
            'status' => 'success',
            'message' => 'Opération créée avec succès',
            'operation_id' => $newOpeId,
            'operations' => $operationData['operations'],
            'sectors' => $operationData['sectors'],
            'users_sectors' => $operationData['users_sectors'],
            'passages' => $operationData['passages']
        ];
    }
}
