<?php
require_once 'conexao.php';
session_start();

// Habilitar erros para debug
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

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

try {
    // Verificar CSRF token
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
        throw new Exception('Token CSRF inválido');
    }

    // Verificar se o usuário está logado
    if (!isset($_SESSION['logado'])) {
        throw new Exception('Usuário não autenticado');
    }

    // Verificar se o fluxo ID foi enviado
    if (!isset($_POST['id']) || !is_numeric($_POST['id'])) {
        throw new Exception('ID do fluxo inválido');
    }

    $fluxo_id = (int)$_POST['id'];
    $tenant_id = $_SESSION['tenant_id'] ?? null;
    $usuario_id = $_SESSION['usuario_id'] ?? null;

    if (!$tenant_id) {
        throw new Exception('Tenant ID não encontrado');
    }

    // Buscar o fluxo
    $sql = "SELECT * FROM fluxos_automatizados WHERE id = ? AND tenant_id = ?";
    $stmt = $conn->prepare($sql);
    if (!$stmt) {
        throw new Exception('Erro ao preparar consulta: ' . $conn->error);
    }
    
    $stmt->bind_param("ii", $fluxo_id, $tenant_id);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows === 0) {
        throw new Exception('Fluxo não encontrado');
    }

    $fluxo = $result->fetch_assoc();

    // Verificar se o fluxo está ativo
    if (!$fluxo['ativo']) {
        throw new Exception('Fluxo está desativado');
    }

    // Decodificar JSON
    $condicoes = json_decode($fluxo['condicoes'], true);
    $acoes = json_decode($fluxo['acoes'], true);

    if (!$condicoes || !$acoes) {
        throw new Exception('Erro ao decodificar condições ou ações do fluxo');
    }

    // Contadores
    $clientes_processados = 0;
    $clientes_recuperados = 0;
    $clientes_ignorados = 0;
    $mensagens = [];

    // Para execução MANUAL: processar imediatamente TODOS os clientes perdidos
    foreach ($condicoes as $condicao) {
        $tipo = $condicao['tipo'] ?? '';
        
        switch ($tipo) {
            case 'cliente_perdido':
                // Buscar TODOS os clientes perdidos não restaurados (sem filtro de tempo para execução manual)
                $sql_clientes = "SELECT cp.*, c.Nome_Cliente, c.funil_id as funil_original, c.etapa_funil_id as etapa_original 
                                FROM clientes_perdidos cp
                                JOIN clientes c ON cp.cliente_id = c.id
                                WHERE cp.tenant_id = ?
                                AND cp.restaurado = 0
                                AND (c.status = 'perdido' OR c.status = 0)
                                ORDER BY cp.data_perdido ASC";
                
                $stmt_c = $conn->prepare($sql_clientes);
                if ($stmt_c) {
                    $stmt_c->bind_param("i", $tenant_id);
                    $stmt_c->execute();
                    $clientes = $stmt_c->get_result();
                    
                    while ($cliente = $clientes->fetch_assoc()) {
                        $clientes_processados++;
                        
                        // Verificar se este fluxo tem ações de recuperação
                        $fluxo_tem_recuperacao = false;
                        $config_recuperacao = null;
                        
                        foreach ($acoes as $acao) {
                            if ((isset($acao['tipo']) && $acao['tipo'] === 'recuperacao') || 
                                (isset($acao['funil_destino_id']) && isset($acao['etapa_destino_id']))) {
                                $fluxo_tem_recuperacao = true;
                                $config_recuperacao = $acao;
                                
                                // Garantir compatibilidade
                                if (!isset($config_recuperacao['tipo'])) {
                                    $config_recuperacao['tipo'] = 'recuperacao';
                                }
                                break;
                            }
                        }
                        
                        if ($fluxo_tem_recuperacao && $config_recuperacao) {
                            // VERIFICAR SE O MOTIVO DO CLIENTE ESTÁ NA LISTA DO FLUXO
                            $motivo_cliente = $cliente['motivo'] ?? '';
                            $motivos_permitidos = $config_recuperacao['motivos_perda'] ?? [];
                            
                            if (deveRecuperarMotivo($motivo_cliente, $motivos_permitidos)) {
                                // Executar recuperação
                                $resultado = recuperarCliente($config_recuperacao, $cliente, $tenant_id, $usuario_id, $fluxo_id);
                                if ($resultado['success']) {
                                    $clientes_recuperados++;
                                    $mensagens[] = "✓ Cliente {$cliente['Nome_Cliente']} ({$cliente['cliente_id']}) recuperado";
                                } else {
                                    $mensagens[] = "✗ Erro com cliente {$cliente['cliente_id']}: " . $resultado['message'];
                                }
                            } else {
                                $clientes_ignorados++;
                                $mensagens[] = "➜ Cliente {$cliente['cliente_id']} ignorado - motivo '{$motivo_cliente}' não está na lista do fluxo";
                            }
                        } else {
                            $clientes_ignorados++;
                            $mensagens[] = "ℹ Fluxo não tem ação de recuperação configurada para cliente {$cliente['cliente_id']}";
                        }
                    }
                    $stmt_c->close();
                }
                break;
                
            // Adicione outros tipos de condições conforme necessário
            default:
                $mensagens[] = "Condição do tipo '$tipo' não processada nesta execução manual";
        }
    }

    // Atualizar última execução
    $sql_update = "UPDATE fluxos_automatizados SET ultima_execucao = NOW() WHERE id = ?";
    $stmt_update = $conn->prepare($sql_update);
    if ($stmt_update) {
        $stmt_update->bind_param("i", $fluxo_id);
        $stmt_update->execute();
        $stmt_update->close();
    }

    // Resposta
    $response = [
        'success' => true,
        'message' => "Fluxo '{$fluxo['nome']}' executado",
        'fluxo_nome' => $fluxo['nome'],
        'processados' => $clientes_processados,
        'recuperados' => $clientes_recuperados,
        'ignorados' => $clientes_ignorados,
        'mensagens' => $mensagens
    ];

    if ($clientes_processados === 0) {
        $response['message'] = 'Nenhum cliente encontrado para as condições deste fluxo';
    }

    echo json_encode($response);

} catch (Exception $e) {
    $response = [
        'success' => false,
        'message' => 'Erro: ' . $e->getMessage()
    ];
    
    // Log do erro
    error_log('Erro executar_fluxo.php: ' . $e->getMessage());
    
    echo json_encode($response);
}

// Função para verificar se o motivo do cliente deve ser recuperado
function deveRecuperarMotivo($motivo_cliente, $motivos_permitidos) {
    // Se não há motivos configurados ou está vazio, recupera todos
    if (empty($motivos_permitidos)) {
        return true;
    }
    
    // Se não é array, converte
    if (!is_array($motivos_permitidos)) {
        $motivos_permitidos = [$motivos_permitidos];
    }
    
    // Se "qualquer" está na lista, recupera todos
    if (in_array('qualquer', $motivos_permitidos)) {
        return true;
    }
    
    // Se o cliente não tem motivo, não recupera
    if (empty($motivo_cliente)) {
        return false;
    }
    
    $motivo_cliente = strtolower(trim($motivo_cliente));
    
    foreach ($motivos_permitidos as $motivo_permitido) {
        $motivo_permitido = strtolower(trim($motivo_permitido));
        
        // Verifica se há correspondência exata
        if ($motivo_cliente === $motivo_permitido) {
            return true;
        }
        
        // Verifica correspondência parcial
        if (strpos($motivo_cliente, $motivo_permitido) !== false ||
            strpos($motivo_permitido, $motivo_cliente) !== false) {
            return true;
        }
    }
    
    return false;
}

// Função para recuperar cliente
function recuperarCliente($acao, $cliente_perdido, $tenant_id, $usuario_id, $fluxo_id) {
    global $conn;
    
    try {
        $cliente_id = $cliente_perdido['cliente_id'];
        $funil_destino_id = $acao['funil_destino_id'] ?? null;
        $etapa_destino_id = $acao['etapa_destino_id'] ?? null;
        
        if (!$funil_destino_id || !$etapa_destino_id) {
            return ['success' => false, 'message' => 'Funil ou etapa não configurados'];
        }
        
        // Verificar se funil e etapa existem
        $sql_verificar = "SELECT COUNT(*) as total 
                         FROM etapas_funis ef
                         JOIN funis f ON ef.funil_id = f.id
                         WHERE ef.id = ? AND f.id = ? AND f.tenant_id = ?";
        
        $stmt_v = $conn->prepare($sql_verificar);
        $stmt_v->bind_param("iii", $etapa_destino_id, $funil_destino_id, $tenant_id);
        $stmt_v->execute();
        $result_v = $stmt_v->get_result()->fetch_assoc();
        
        if ($result_v['total'] == 0) {
            return ['success' => false, 'message' => 'Funil/etapa de destino não existe'];
        }
        
        // Iniciar transação
        $conn->begin_transaction();
        
        try {
            // 1. Atualizar cliente
            $sql_cliente = "UPDATE clientes 
                           SET status = 1, 
                               funil_id = ?, 
                               etapa_funil_id = ?,
                               atualizado_em = NOW()
                           WHERE id = ? AND tenant_id = ?";
            
            $stmt = $conn->prepare($sql_cliente);
            if (!$stmt) {
                throw new Exception('Erro ao preparar SQL cliente: ' . $conn->error);
            }
            
            $stmt->bind_param("iiii", $funil_destino_id, $etapa_destino_id, $cliente_id, $tenant_id);
            if (!$stmt->execute()) {
                throw new Exception('Erro ao atualizar cliente: ' . $stmt->error);
            }
            $stmt->close();
            
            // 2. Atualizar tabela clientes_perdidos
            $observacao = "Recuperado manualmente pelo fluxo #$fluxo_id em " . date('Y-m-d H:i:s');
            $sql_perdido = "UPDATE clientes_perdidos 
                           SET restaurado = 1, 
                               data_restaurado = NOW(),
                               observacoes = CONCAT(
                                   IFNULL(observacoes, ''), 
                                   ' | $observacao'
                               )
                           WHERE cliente_id = ? AND tenant_id = ? AND restaurado = 0";
            
            $stmt2 = $conn->prepare($sql_perdido);
            if ($stmt2) {
                $stmt2->bind_param("ii", $cliente_id, $tenant_id);
                if (!$stmt2->execute()) {
                    throw new Exception('Erro ao marcar como recuperado: ' . $stmt2->error);
                }
                $stmt2->close();
            }
            
            // 3. Registrar log
            if ($usuario_id) {
                $sql_usuario = "SELECT nome FROM usuarios WHERE id = ?";
                $stmt_u = $conn->prepare($sql_usuario);
                $stmt_u->bind_param("i", $usuario_id);
                $stmt_u->execute();
                $result_u = $stmt_u->get_result();
                $usuario_nome = $result_u->fetch_assoc()['nome'] ?? 'Sistema';
                $stmt_u->close();
                
                $detalhes = "Cliente recuperado manualmente por fluxo.\n";
                $detalhes .= "Motivo original: " . ($cliente_perdido['motivo'] ?? 'Desconhecido') . "\n";
                $detalhes .= "Destino: Funil $funil_destino_id, Etapa $etapa_destino_id";
                
                $sql_log = "INSERT INTO cliente_logs 
                           (cliente_id, usuario_id, nome_usuario, acao, detalhes, tenant_id, observacao_id) 
                           VALUES (?, ?, ?, 'cliente recuperado', ?, ?, 0)";
                
                $stmt3 = $conn->prepare($sql_log);
                if ($stmt3) {
                    $stmt3->bind_param("iisss", 
                        $cliente_id, 
                        $usuario_id,
                        $usuario_nome,
                        $detalhes,
                        $tenant_id
                    );
                    $stmt3->execute();
                    $stmt3->close();
                }
            }
            
            // Commit da transação
            $conn->commit();
            
            return ['success' => true, 'message' => 'Recuperado com sucesso'];
            
        } catch (Exception $e) {
            $conn->rollback();
            throw $e;
        }
        
    } catch (Exception $e) {
        return ['success' => false, 'message' => 'Exceção: ' . $e->getMessage()];
    }
}
?>