<?php
namespace Modules\GestorY\Services;

use Gestoreasy\Core\Tenant\ConnectionManager;
use Gestoreasy\Core\Tenant\TenantContext;
use PDO;
use Exception;

/**
 * Serviço para notificações sobre mudanças, erros e alertas
 */
class NotificationService {
    private PDO $pdo;
    private string $tenantId;

    public function __construct() {
        $this->pdo = ConnectionManager::forTenant();
        $this->tenantId = TenantContext::getTenantId();
    }

    /**
     * Cria notificação
     */
    public function criarNotificacao(string $tipo, string $titulo, string $mensagem, array $dados = []): int {
        try {
            // Verificar se tabela existe, criar se não existir
            $this->ensureTable();
            
            $stmt = $this->pdo->prepare('INSERT INTO gestory_notificacoes 
                (tenant_id, tipo, titulo, mensagem, dados_json, lida, created_at)
                VALUES (?, ?, ?, ?, ?, 0, NOW())');
            
            $stmt->execute([
                $this->tenantId,
                $tipo,
                $titulo,
                $mensagem,
                json_encode($dados)
            ]);
            
            return (int)$this->pdo->lastInsertId();
        } catch (Exception $e) {
            error_log("[GestorY] Erro ao criar notificação: " . $e->getMessage());
            return 0;
        }
    }

    /**
     * Notifica sobre mudança no site
     */
    public function notificarMudancaSite(string $detalhes): void {
        $this->criarNotificacao(
            'aviso',
            'Mudança detectada no site Yamaha',
            "O site Yamaha pode ter mudado sua estrutura. Detalhes: $detalhes",
            ['tipo' => 'mudanca_site', 'detalhes' => $detalhes]
        );
    }

    /**
     * Notifica sobre erro de scraping
     */
    public function notificarErroScraping(string $erro, array $contexto = []): void {
        $this->criarNotificacao(
            'erro',
            'Erro no web scraping',
            "Erro ao realizar scraping: $erro",
            array_merge(['tipo' => 'erro_scraping', 'erro' => $erro], $contexto)
        );
    }

    /**
     * Notifica sobre limite de requisições
     */
    public function notificarLimiteRequisicoes(): void {
        $this->criarNotificacao(
            'aviso',
            'Limite de requisições atingido',
            'O limite de requisições por hora foi atingido. Aguarde antes de continuar.',
            ['tipo' => 'limite_requisicoes']
        );
    }

    /**
     * Notifica sobre atualização concluída
     */
    public function notificarAtualizacaoConcluida(int $sucesso, int $erros, int $atualizadas, int $novas): void {
        $this->criarNotificacao(
            'atualizacao',
            'Atualização automática concluída',
            "Processadas: $sucesso sucesso, $erros erros. Atualizadas: $atualizadas, Novas: $novas",
            [
                'tipo' => 'atualizacao_concluida',
                'sucesso' => $sucesso,
                'erros' => $erros,
                'atualizadas' => $atualizadas,
                'novas' => $novas
            ]
        );
    }

    /**
     * Notifica sobre API oficial disponível
     */
    public function notificarApiOficial(): void {
        $this->criarNotificacao(
            'info',
            'API oficial Yamaha disponível',
            'Uma API oficial do Yamaha foi detectada. Considere migrar do web scraping para a API oficial.',
            ['tipo' => 'api_oficial_disponivel']
        );
    }

    /**
     * Lista notificações não lidas
     */
    public function listarNaoLidas(int $limite = 10): array {
        try {
            $this->ensureTable();
            
            $stmt = $this->pdo->prepare('SELECT * FROM gestory_notificacoes 
                WHERE tenant_id = ? AND lida = 0 
                ORDER BY created_at DESC 
                LIMIT ?');
            $stmt->execute([$this->tenantId, $limite]);
            $notificacoes = $stmt->fetchAll();
            
            foreach ($notificacoes as &$notif) {
                if (!empty($notif['dados_json'])) {
                    $notif['dados'] = json_decode($notif['dados_json'], true);
                }
            }
            
            return $notificacoes;
        } catch (Exception $e) {
            return [];
        }
    }

    /**
     * Marca notificação como lida
     */
    public function marcarComoLida(int $id): void {
        try {
            $this->ensureTable();
            
            $stmt = $this->pdo->prepare('UPDATE gestory_notificacoes 
                SET lida = 1, lida_em = NOW() 
                WHERE id = ? AND tenant_id = ?');
            $stmt->execute([$id, $this->tenantId]);
        } catch (Exception $e) {
            error_log("[GestorY] Erro ao marcar notificação como lida: " . $e->getMessage());
        }
    }

    /**
     * Garante que a tabela existe
     */
    private function ensureTable(): void {
        try {
            $this->pdo->exec('CREATE TABLE IF NOT EXISTS gestory_notificacoes (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                tenant_id VARCHAR(100) NOT NULL,
                tipo ENUM("info", "aviso", "erro", "atualizacao", "sucesso") NOT NULL,
                titulo VARCHAR(255) NOT NULL,
                mensagem TEXT,
                dados_json JSON NULL,
                lida BOOLEAN DEFAULT FALSE,
                lida_em DATETIME NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                KEY idx_tenant_lida (tenant_id, lida),
                KEY idx_created (created_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
        } catch (Exception $e) {
            // Tabela já existe ou erro de permissão
        }
    }
}

