<?php
namespace Modules\Fiscal\Services;

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

/**
 * Serviço para detecção automática de notas fiscais emitidas contra a empresa
 */
class NFeDeteccaoService {
    private PDO $pdo;
    private string $tenantId;

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

    /**
     * Configura detecção automática
     */
    public function configurar(string $cnpj, array $opcoes): array {
        try {
            // Buscar configuração existente
            $stmt = $this->pdo->prepare('SELECT * FROM nfe_entrada_deteccao WHERE tenant_id = ? AND cnpj_empresa = ? LIMIT 1');
            $stmt->execute([$this->tenantId, $cnpj]);
            $config = $stmt->fetch();
            
            if ($config) {
                // Atualizar
                $stmt = $this->pdo->prepare('UPDATE nfe_entrada_deteccao SET
                    ambiente = ?,
                    ativo = ?,
                    intervalo_minutos = ?,
                    auto_processar = ?,
                    auto_criar_fornecedor = ?,
                    auto_criar_produto = ?,
                    webhook_token = ?,
                    webhook_url = ?,
                    updated_at = NOW()
                    WHERE id = ?');
                $stmt->execute([
                    $opcoes['ambiente'] ?? 'producao',
                    $opcoes['ativo'] ?? true ? 1 : 0,
                    (int)($opcoes['intervalo_minutos'] ?? 60),
                    $opcoes['auto_processar'] ?? false ? 1 : 0,
                    $opcoes['auto_criar_fornecedor'] ?? false ? 1 : 0,
                    $opcoes['auto_criar_produto'] ?? false ? 1 : 0,
                    $opcoes['webhook_token'] ?? null,
                    $opcoes['webhook_url'] ?? null,
                    $config['id']
                ]);
                $id = $config['id'];
            } else {
                // Criar
                $stmt = $this->pdo->prepare('INSERT INTO nfe_entrada_deteccao
                    (tenant_id, cnpj_empresa, ambiente, ativo, intervalo_minutos, auto_processar, auto_criar_fornecedor, auto_criar_produto, webhook_token, webhook_url)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
                $stmt->execute([
                    $this->tenantId,
                    $cnpj,
                    $opcoes['ambiente'] ?? 'producao',
                    $opcoes['ativo'] ?? true ? 1 : 0,
                    (int)($opcoes['intervalo_minutos'] ?? 60),
                    $opcoes['auto_processar'] ?? false ? 1 : 0,
                    $opcoes['auto_criar_fornecedor'] ?? false ? 1 : 0,
                    $opcoes['auto_criar_produto'] ?? false ? 1 : 0,
                    $opcoes['webhook_token'] ?? null,
                    $opcoes['webhook_url'] ?? null
                ]);
                $id = (int)$this->pdo->lastInsertId();
            }
            
            // Buscar config atualizada
            $stmt = $this->pdo->prepare('SELECT * FROM nfe_entrada_deteccao WHERE id = ? LIMIT 1');
            $stmt->execute([$id]);
            return $stmt->fetch();
        } catch (Exception $e) {
            throw new Exception('Erro ao configurar detecção: ' . $e->getMessage());
        }
    }

    /**
     * Executa detecção automática
     */
    public function executar(): array {
        try {
            // Buscar configurações ativas
            $stmt = $this->pdo->prepare('SELECT * FROM nfe_entrada_deteccao 
                WHERE tenant_id = ? AND ativo = 1');
            $stmt->execute([$this->tenantId]);
            $configs = $stmt->fetchAll();
            
            if (empty($configs)) {
                return ['detectadas' => 0, 'processadas' => 0, 'erros' => 0, 'mensagem' => 'Nenhuma configuração ativa'];
            }
            
            $totalDetectadas = 0;
            $totalProcessadas = 0;
            $totalErros = 0;
            
            foreach ($configs as $config) {
                // Verificar se é hora de verificar
                $proximaVerificacao = $config['proxima_verificacao'] ?? null;
                if ($proximaVerificacao && strtotime($proximaVerificacao) > time()) {
                    continue; // Ainda não é hora
                }
                
                try {
                    // Verificar notas recebidas recentemente via webhook
                    $cnpjLimpo = preg_replace('/\D/', '', $config['cnpj_empresa']);
                    
                    $stmt = $this->pdo->prepare('SELECT COUNT(*) AS total FROM nfe_entrada 
                        WHERE tenant_id = ? AND destinatario_cnpj = ? 
                        AND forma_entrada = "automatica" 
                        AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)');
                    $stmt->execute([$this->tenantId, $cnpjLimpo]);
                    $result = $stmt->fetch();
                    $novasNotas = (int)($result['total'] ?? 0);
                    
                    $totalDetectadas += $novasNotas;
                    
                    // Processar notas pendentes se auto_processar estiver ativo
                    $processadasNesteCiclo = 0;
                    if ($config['auto_processar'] && $novasNotas > 0) {
                        $stmt = $this->pdo->prepare('SELECT id FROM nfe_entrada 
                            WHERE tenant_id = ? AND destinatario_cnpj = ? 
                            AND status = "pendente" AND forma_entrada = "automatica"
                            ORDER BY created_at DESC LIMIT 10');
                        $stmt->execute([$this->tenantId, $cnpjLimpo]);
                        $notasPendentes = $stmt->fetchAll();
                        
                        $service = new \Modules\Fiscal\Services\NFeEntradaService();
                        foreach ($notasPendentes as $nota) {
                            try {
                                $service->processarNota($nota['id'], true);
                                $processadasNesteCiclo++;
                                $totalProcessadas++;
                            } catch (Exception $e) {
                                $totalErros++;
                                error_log("[NFeDeteccao] Erro ao processar nota {$nota['id']}: " . $e->getMessage());
                            }
                        }
                    }
                    
                    // Atualizar última verificação
                    $intervalo = (int)($config['intervalo_minutos'] ?? 60);
                    $proxima = date('Y-m-d H:i:s', strtotime("+$intervalo minutes"));
                    
                    $stmt = $this->pdo->prepare('UPDATE nfe_entrada_deteccao SET
                        ultima_verificacao = NOW(),
                        proxima_verificacao = ?,
                        total_detectadas = total_detectadas + ?,
                        total_processadas = total_processadas + ?,
                        total_erros = total_erros + ?
                        WHERE id = ?');
                    $stmt->execute([
                        $proxima,
                        $novasNotas,
                        $processadasNesteCiclo,
                        $totalErros,
                        $config['id']
                    ]);
                } catch (Exception $e) {
                    $totalErros++;
                    error_log("[NFeDeteccao] Erro na detecção: " . $e->getMessage());
                }
            }
            
            return [
                'detectadas' => $totalDetectadas,
                'processadas' => $totalProcessadas,
                'erros' => $totalErros,
                'mensagem' => 'Detecção executada com sucesso'
            ];
        } catch (Exception $e) {
            throw new Exception('Erro ao executar detecção: ' . $e->getMessage());
        }
    }

    /**
     * Obtém configuração atual
     */
    public function obterConfiguracao(): ?array {
        $stmt = $this->pdo->prepare('SELECT * FROM nfe_entrada_deteccao WHERE tenant_id = ? LIMIT 1');
        $stmt->execute([$this->tenantId]);
        return $stmt->fetch() ?: null;
    }
}

