<?php

namespace App\Controllers;

use Core\Controller;
use App\Models\Denonciation;
use App\Models\Entreprise;
use App\Models\Client;

require_once APP_PATH . '/Models/Denonciation.php';
require_once APP_PATH . '/Models/Entreprise.php';
require_once APP_PATH . '/Models/Client.php';

class DenonciationController extends Controller
{
    private Denonciation $denonciationModel;
    private Entreprise $entrepriseModel;
    private Client $clientModel;
    
    public function __construct()
    {
        parent::__construct();
        $this->denonciationModel = new Denonciation();
        $this->entrepriseModel = new Entreprise();
        $this->clientModel = new Client();
    }
    
    /**
     * API: Soumettre une dénonciation (depuis widget)
     */
    public function submit(): void
    {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
            exit(0);
        }

        header('Content-Type: application/json');

        $contentLength = (int)($_SERVER['CONTENT_LENGTH'] ?? 0);
        $postMax = $this->toBytes((string)ini_get('post_max_size'));
        if ($postMax > 0 && $contentLength > $postMax) {
            http_response_code(413);
            echo json_encode([
                'success' => false,
                'error' => 'Fichier trop volumineux (limite serveur dépassée).'
            ]);
            return;
        }

        try {
            // Handle multipart form data for file uploads
            $token = $_POST['token'] ?? '';
            $type = $_POST['type'] ?? 'texte';
            $titre = $_POST['titre'] ?? '';
            $description = $_POST['description'] ?? '';
            $categorie = $_POST['categorie'] ?? '';
            $localisation = $_POST['localisation'] ?? '';
            $anonyme = isset($_POST['anonyme']) && $_POST['anonyme'] === 'true';
            $clientId = $_POST['client_id'] ?? null;

            // Validate token
            $entreprise = $this->entrepriseModel->findByToken($token);
            if (!$entreprise) {
                echo json_encode(['success' => false, 'error' => 'Token invalide']);
                return;
            }

            // Check if denonciations are enabled
            if (isset($entreprise['denonciations_enabled']) && !$entreprise['denonciations_enabled']) {
                echo json_encode(['success' => false, 'error' => 'Les dénonciations ne sont pas activées']);
                return;
            }

            $data = [
                'entreprise_id' => $entreprise['id'],
                'client_id' => $clientId ?: null,
                'type' => $type,
                'titre' => $titre,
                'description' => $description,
                'categorie' => $categorie,
                'localisation' => $localisation,
                'anonyme' => $anonyme ? 1 : 0,
                'canal' => 'widget',
                'statut' => 'nouveau',
                'priorite' => 'normale'
            ];

            // Handle file upload
            if (isset($_FILES['fichier']) && $_FILES['fichier']['error'] === UPLOAD_ERR_OK) {
                $uploadResult = $this->handleFileUpload($_FILES['fichier'], $entreprise['id'], $type);
                if ($uploadResult['success']) {
                    $data['fichier_path'] = $uploadResult['path'];
                    $data['fichier_type'] = $uploadResult['mime'];
                    $data['fichier_taille'] = $uploadResult['size'];
                } else {
                    echo json_encode(['success' => false, 'error' => $uploadResult['error']]);
                    return;
                }
            }

            $id = $this->denonciationModel->createDenonciation($data);

            if ($id) {
                echo json_encode([
                    'success' => true,
                    'message' => 'Votre dénonciation a été enregistrée avec succès',
                    'id' => $id
                ]);
                return;
            }

            http_response_code(500);
            echo json_encode(['success' => false, 'error' => "Erreur lors de l'enregistrement"]);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode([
                'success' => false,
                'error' => "Erreur serveur lors de l'envoi du signalement.",
                'debug' => $e->getMessage()
            ]);
        }
    }
    
    /**
     * API: Vérifier si les dénonciations sont activées
     */
    public function checkEnabled(): void
    {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

        if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
            exit(0);
        }

        header('Content-Type: application/json');
        
        $data = json_decode(file_get_contents('php://input'), true);
        $token = $data['token'] ?? '';
        
        $entreprise = $this->entrepriseModel->findByToken($token);
        if (!$entreprise) {
            echo json_encode(['enabled' => false]);
            return;
        }
        
        $enabled = !isset($entreprise['denonciations_enabled']) || $entreprise['denonciations_enabled'];
        echo json_encode(['enabled' => $enabled]);
    }
    
    /**
     * Handle file upload
     */
    private function handleFileUpload(array $file, int $entrepriseId, string $type): array
    {
        $allowedTypes = [
            'audio' => ['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/webm', 'audio/mp4'],
            'photo' => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
            'video' => ['video/mp4', 'video/webm', 'video/ogg', 'video/quicktime']
        ];
        
        $maxSizes = [
            'audio' => 10 * 1024 * 1024,  // 10MB
            'photo' => 5 * 1024 * 1024,   // 5MB
            'video' => 50 * 1024 * 1024   // 50MB
        ];
        
        // Validate file type
        if ($type !== 'texte' && isset($allowedTypes[$type])) {
            if (!in_array($file['type'], $allowedTypes[$type])) {
                return ['success' => false, 'error' => 'Type de fichier non autorisé'];
            }
        }
        
        // Validate file size
        if (isset($maxSizes[$type]) && $file['size'] > $maxSizes[$type]) {
            return ['success' => false, 'error' => 'Fichier trop volumineux'];
        }
        
        // Create upload directory
        $uploadBase = defined('UPLOADS_PATH') ? UPLOADS_PATH : (ROOT_PATH . '/public/uploads');
        $uploadDir = rtrim($uploadBase, '/') . '/denonciations/' . $entrepriseId;
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        
        // Generate unique filename
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = uniqid('denon_') . '_' . time() . '.' . $ext;
        $filepath = $uploadDir . '/' . $filename;
        
        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            return [
                'success' => true,
                'path' => 'uploads/denonciations/' . $entrepriseId . '/' . $filename,
                'mime' => $file['type'],
                'size' => $file['size']
            ];
        }
        
        return ['success' => false, 'error' => 'Erreur lors du téléchargement'];
    }

    private function toBytes(string $value): int
    {
        $value = trim($value);
        if ($value === '') {
            return 0;
        }

        $last = strtolower(substr($value, -1));
        $num = (int)$value;

        switch ($last) {
            case 'g':
                $num *= 1024;
                // no break
            case 'm':
                $num *= 1024;
                // no break
            case 'k':
                $num *= 1024;
                break;
        }

        return $num;
    }
    
    /**
     * Admin: Liste des dénonciations
     */
    public function index(): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin']);

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        if ($entrepriseId <= 0) {
            $this->redirect('/auth/login');
            return;
        }

        $filters = [
            'statut' => $_GET['statut'] ?? null,
            'type' => $_GET['type'] ?? null,
            'priorite' => $_GET['priorite'] ?? null
        ];
        
        $denonciations = $this->denonciationModel->getByEntreprise($entrepriseId, $filters);
        $stats = $this->denonciationModel->getStats($entrepriseId);
        
        $this->view('admin/denonciations/index', [
            'denonciations' => $denonciations,
            'stats' => $stats,
            'filters' => $filters,
            'user' => $this->currentUser()
        ]);
    }
    
    /**
     * Admin: Voir une dénonciation avec détails complets
     */
    public function viewDenonciation(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        if ($entrepriseId <= 0) {
            $this->redirect('/auth/login');
            return;
        }
        
        $denonciation = $this->denonciationModel->getWithDetails((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            header('Location: ' . BASE_URL . '/admin/denonciations');
            return;
        }
        
        // Charger les données associées
        $historique = $this->denonciationModel->getHistorique((int)$id);
        $pieces = $this->denonciationModel->getPieces((int)$id);
        
        // Charger les agents pour l'assignation
        require_once APP_PATH . '/Models/User.php';
        $userModel = new \App\Models\User();
        $agents = $userModel->getByEntreprise($entrepriseId);
        
        $this->view('admin/denonciations/view', [
            'denonciation' => $denonciation,
            'historique' => $historique,
            'pieces' => $pieces,
            'agents' => $agents
            , 'user' => $this->currentUser()
        ]);
    }
    
    /**
     * Admin: Mettre à jour le statut
     */
    public function updateStatus(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $statut = $data['statut'] ?? '';
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->updateStatut(
            (int)$id, 
            $statut, 
            $userId
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Activer/Désactiver les dénonciations
     */
    public function toggleEnabled(): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        if ($entrepriseId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $enabled = $data['enabled'] ?? true;
        
        $success = $this->entrepriseModel->update($entrepriseId, [
            'denonciations_enabled' => $enabled
        ]);
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Mettre à jour le statut avec historique
     */
    public function updateStatut(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $statut = $data['statut'] ?? '';
        $commentaire = $data['commentaire'] ?? null;
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->updateStatutWithHistory(
            (int)$id, 
            $statut, 
            $userId,
            $commentaire
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Mettre à jour la priorité
     */
    public function updatePriorite(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $priorite = $data['priorite'] ?? 'normale';
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->updatePriorite(
            (int)$id, 
            $priorite, 
            $userId
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Assigner un agent
     */
    public function assigner(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $agentId = (int)($data['agent_id'] ?? 0);
        
        if (!$agentId) {
            echo json_encode(['success' => false, 'error' => 'Agent non spécifié']);
            return;
        }
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->assignerAgent(
            (int)$id, 
            $agentId, 
            $userId
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Ajouter une note interne
     */
    public function addNote(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $note = $data['note'] ?? '';
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->addNoteInterne(
            (int)$id, 
            $userId,
            $note
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Clôturer un dossier
     */
    public function cloturer(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $data = json_decode(file_get_contents('php://input'), true);
        $resolution = $data['resolution'] ?? '';
        $statut = $data['statut'] ?? 'traite';
        
        if (empty($resolution)) {
            echo json_encode(['success' => false, 'error' => 'Résolution requise']);
            return;
        }
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $success = $this->denonciationModel->cloturer(
            (int)$id, 
            $userId,
            $resolution,
            $statut
        );
        
        echo json_encode(['success' => $success]);
    }
    
    /**
     * Admin: Ajouter une pièce jointe
     */
    public function addPiece(string $id): void
    {
        $this->requireRoles(['admin_entreprise', 'super_admin', 'agent']);
        header('Content-Type: application/json');

        $entrepriseId = (int)($_SESSION['entreprise_id'] ?? 0);
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($entrepriseId <= 0 || $userId <= 0) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        $denonciation = $this->denonciationModel->find((int)$id);
        
        if (!$denonciation || (int)$denonciation['entreprise_id'] !== $entrepriseId) {
            echo json_encode(['success' => false, 'error' => 'Non autorisé']);
            return;
        }
        
        if (!isset($_FILES['fichier']) || $_FILES['fichier']['error'] !== UPLOAD_ERR_OK) {
            echo json_encode(['success' => false, 'error' => 'Aucun fichier uploadé']);
            return;
        }
        
        $file = $_FILES['fichier'];
        $description = $_POST['description'] ?? '';
        
        // Determine file type
        $mime = $file['type'];
        $type = 'document';
        if (strpos($mime, 'image/') === 0) $type = 'photo';
        elseif (strpos($mime, 'audio/') === 0) $type = 'audio';
        elseif (strpos($mime, 'video/') === 0) $type = 'video';
        
        // Upload file
        $uploadBase = defined('UPLOADS_PATH') ? UPLOADS_PATH : (ROOT_PATH . '/public/uploads');
        $uploadDir = rtrim($uploadBase, '/') . '/denonciations/' . $denonciation['entreprise_id'] . '/pieces';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = 'piece_' . $id . '_' . time() . '.' . $ext;
        $filepath = $uploadDir . '/' . $filename;
        
        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            $cheminFichier = 'uploads/denonciations/' . $denonciation['entreprise_id'] . '/pieces/' . $filename;
            
            $pieceId = $this->denonciationModel->addPiece(
                (int)$id,
                $userId,
                $type,
                $file['name'],
                $cheminFichier,
                $description
            );
            
            echo json_encode(['success' => true, 'piece_id' => $pieceId]);
        } else {
            echo json_encode(['success' => false, 'error' => 'Erreur upload']);
        }
    }
}
