<?php
/**
 * FeedbackController — Sistema Segnalazioni & Risoluzione AI
 *
 * Adattato da alltax.it/docs/sistema-segnalazioni-standard.html
 *
 * Endpoint (tutti richiedono auth JWT + X-Organization-Id):
 *   POST /api/feedback/submit        → crea segnalazione + classifica con AI
 *   GET  /api/feedback/mine          → ultime 20 segnalazioni dell'utente
 *   GET  /api/feedback/list          → lista admin (org_admin, compliance_manager, auditor)
 *   GET  /api/feedback/{id}          → dettaglio (admin o autore)
 *   PUT  /api/feedback/{id}          → aggiorna status/nota_admin (admin)
 *   POST /api/feedback/{id}/resolve  → chiusura manuale con password gate
 */

require_once APP_PATH . '/controllers/BaseController.php';
require_once APP_PATH . '/services/FeedbackService.php';

class FeedbackController extends BaseController
{
    private FeedbackService $feedbackService;

    public function __construct()
    {
        $this->feedbackService = new FeedbackService();
    }

    /**
     * POST /api/feedback/submit
     * Crea segnalazione + classifica con AI (10s timeout)
     */
    public function submit(): void
    {
        $this->requireOrgAccess();

        $body = $this->getJsonBody();

        $tipo       = trim($body['tipo']       ?? 'bug');
        $priorita   = trim($body['priorita']   ?? 'media');
        $descrizione = trim($body['descrizione'] ?? '');
        $pageUrl    = trim($body['page_url']   ?? '');
        $attachment = $body['attachment'] ?? null; // base64 string

        if (strlen($descrizione) < 10) {
            $this->jsonError('Descrizione troppo breve (minimo 10 caratteri).', 422);
            return;
        }

        $validTipi = ['bug', 'ux', 'funzionalita', 'domanda', 'altro'];
        if (!in_array($tipo, $validTipi)) {
            $tipo = 'bug';
        }

        $validPriorita = ['alta', 'media', 'bassa'];
        if (!in_array($priorita, $validPriorita)) {
            $priorita = 'media';
        }

        $report = $this->feedbackService->createReport(
            $this->currentOrgId,
            $this->getCurrentUserId(),
            $this->currentUser['email'],
            $this->currentOrgRole ?? 'employee',
            [
                'tipo'        => $tipo,
                'priorita'    => $priorita,
                'descrizione' => $descrizione,
                'page_url'    => $pageUrl,
                'attachment'  => $attachment,
            ]
        );

        $this->jsonSuccess($report, 'Segnalazione inviata. L\'AI ha analizzato il problema.');
    }

    /**
     * GET /api/feedback/mine
     * Ultime 20 segnalazioni dell'utente corrente per questa org
     */
    public function mine(): void
    {
        $this->requireOrgAccess();

        $reports = Database::fetchAll(
            'SELECT id, tipo, priorita, descrizione, status,
                    ai_categoria, ai_priorita, ai_risposta, ai_processed,
                    created_at, updated_at
             FROM feedback_reports
             WHERE organization_id = ? AND user_id = ?
             ORDER BY created_at DESC
             LIMIT 20',
            [$this->currentOrgId, $this->getCurrentUserId()]
        );

        $this->jsonSuccess($reports);
    }

    /**
     * GET /api/feedback/list
     * Lista admin con filtri opzionali: status, tipo, priorita
     */
    public function list(): void
    {
        $this->requireOrgRole(['org_admin', 'compliance_manager', 'auditor']);

        $pagination = $this->getPagination(20);
        $status     = $this->getParam('status', '');
        $tipo       = $this->getParam('tipo', '');
        $priorita   = $this->getParam('priorita', '');

        $where  = ['r.organization_id = ?'];
        $params = [$this->currentOrgId];

        if ($status) {
            $where[]  = 'r.status = ?';
            $params[] = $status;
        }
        if ($tipo) {
            $where[]  = 'r.tipo = ?';
            $params[] = $tipo;
        }
        if ($priorita) {
            $where[]  = 'r.priorita = ?';
            $params[] = $priorita;
        }

        $whereSql = implode(' AND ', $where);

        $total = (int) Database::fetchOne(
            "SELECT COUNT(*) AS cnt FROM feedback_reports r WHERE {$whereSql}",
            $params
        )['cnt'];

        $countParams = $params;
        $params[] = $pagination['per_page'];
        $params[] = $pagination['offset'];

        $items = Database::fetchAll(
            "SELECT r.id, r.tipo, r.priorita, r.descrizione, r.status,
                    r.page_url, r.nota_admin,
                    r.ai_categoria, r.ai_priorita, r.ai_risposta, r.ai_processed,
                    r.user_email, r.user_role, r.created_at, r.updated_at,
                    u.full_name AS user_name
             FROM feedback_reports r
             LEFT JOIN users u ON u.id = r.user_id
             WHERE {$whereSql}
             ORDER BY
               FIELD(r.priorita,'alta','media','bassa'),
               FIELD(r.status,'aperto','in_lavorazione','risolto','chiuso'),
               r.created_at DESC
             LIMIT ? OFFSET ?",
            $params
        );

        $this->jsonPaginated($items, $total, $pagination['page'], $pagination['per_page']);
    }

    /**
     * GET /api/feedback/{id}
     * Dettaglio segnalazione (admin o autore)
     */
    public function show(int $id): void
    {
        $this->requireOrgAccess();

        $report = Database::fetchOne(
            'SELECT r.*, u.full_name AS user_name
             FROM feedback_reports r
             LEFT JOIN users u ON u.id = r.user_id
             WHERE r.id = ? AND r.organization_id = ?',
            [$id, $this->currentOrgId]
        );

        if (!$report) {
            $this->jsonError('Segnalazione non trovata.', 404, 'NOT_FOUND');
            return;
        }

        // Solo admin o autore possono vedere il dettaglio
        $isAdmin = in_array($this->currentOrgRole, ['org_admin', 'compliance_manager', 'auditor', 'super_admin']);
        if (!$isAdmin && $report['user_id'] != $this->getCurrentUserId()) {
            $this->jsonError('Accesso non autorizzato.', 403, 'ACCESS_DENIED');
            return;
        }

        $this->jsonSuccess($report);
    }

    /**
     * PUT /api/feedback/{id}
     * Aggiorna status e/o nota_admin (solo admin)
     */
    public function update(int $id): void
    {
        $this->requireOrgRole(['org_admin', 'compliance_manager']);

        $report = Database::fetchOne(
            'SELECT id, status FROM feedback_reports WHERE id = ? AND organization_id = ?',
            [$id, $this->currentOrgId]
        );

        if (!$report) {
            $this->jsonError('Segnalazione non trovata.', 404, 'NOT_FOUND');
            return;
        }

        $body   = $this->getJsonBody();
        $fields = [];
        $params = [];

        $validStatus = ['aperto', 'in_lavorazione', 'risolto', 'chiuso'];
        if (isset($body['status']) && in_array($body['status'], $validStatus)) {
            $fields[] = 'status = ?';
            $params[] = $body['status'];
        }

        if (isset($body['nota_admin'])) {
            $fields[] = 'nota_admin = ?';
            $params[] = htmlspecialchars(trim($body['nota_admin']), ENT_QUOTES, 'UTF-8');
        }

        if (empty($fields)) {
            $this->jsonError('Nessun campo da aggiornare.', 422);
            return;
        }

        $params[] = $id;
        $params[] = $this->currentOrgId;

        Database::query(
            'UPDATE feedback_reports SET ' . implode(', ', $fields) . ' WHERE id = ? AND organization_id = ?',
            $params
        );

        // Broadcast se risolto
        if (isset($body['status']) && $body['status'] === 'risolto') {
            $this->feedbackService->broadcastResolution($id, $this->currentOrgId);
        }

        $updated = Database::fetchOne(
            'SELECT * FROM feedback_reports WHERE id = ?',
            [$id]
        );

        $this->jsonSuccess($updated, 'Segnalazione aggiornata.');
    }

    /**
     * POST /api/feedback/{id}/resolve
     * Chiusura manuale con password gate (utente dice "sì, risolto")
     */
    public function resolve(int $id): void
    {
        $this->requireOrgAccess();

        $body     = $this->getJsonBody();
        $password = trim($body['password'] ?? '');

        if (empty($password)) {
            $this->jsonError('Password di conferma richiesta.', 422);
            return;
        }

        $resolvePassword = defined('FEEDBACK_RESOLVE_PASSWORD') ? FEEDBACK_RESOLVE_PASSWORD : '';
        if (empty($resolvePassword) || $password !== $resolvePassword) {
            $this->jsonError('Password non corretta.', 403, 'INVALID_PASSWORD');
            return;
        }

        $report = Database::fetchOne(
            'SELECT id, status, user_id FROM feedback_reports WHERE id = ? AND organization_id = ?',
            [$id, $this->currentOrgId]
        );

        if (!$report) {
            $this->jsonError('Segnalazione non trovata.', 404, 'NOT_FOUND');
            return;
        }

        // Solo l'autore o un admin possono risolvere
        $isAdmin = in_array($this->currentOrgRole, ['org_admin', 'compliance_manager', 'super_admin']);
        if (!$isAdmin && $report['user_id'] != $this->getCurrentUserId()) {
            $this->jsonError('Accesso non autorizzato.', 403, 'ACCESS_DENIED');
            return;
        }

        if ($report['status'] === 'chiuso') {
            $this->jsonError('Segnalazione già chiusa.', 422);
            return;
        }

        Database::query(
            'UPDATE feedback_reports SET status = ? WHERE id = ?',
            ['risolto', $id]
        );

        $this->feedbackService->broadcastResolution($id, $this->currentOrgId);

        $this->jsonSuccess(null, 'Ottimo! Segnalazione marcata come risolta. Grazie per il feedback.');
    }
}
