<?php
// includes/page-flow.php

class PageFlow {
    private $db;
    
    // Mapa do fluxo de páginas
    private $flowMap = [
        'landing' => 'step1',
        'step1' => 'registration',
        'registration' => null // Página final
    ];
    
    // Nomes amigáveis dos tipos
    private $typeNames = [
        'landing' => 'Página de Aterrisagem',
        'step1' => 'Primeira Etapa',
        'registration' => 'Página de Registro'
    ];
    
    public function __construct() {
        global $db;
        $this->db = $db;
    }
    
    /**
     * Cria a tabela de configurações de fluxo se não existir
     */
    public function createFlowSettingsTable() {
        try {
            $tableExists = $this->db->tableExists('flow_settings');
            
            if (!$tableExists) {
                $sql = "CREATE TABLE `flow_settings` (
                    `id` int(11) NOT NULL AUTO_INCREMENT,
                    `landing_page_id` int(11) NOT NULL,
                    `require_sequential_access` tinyint(1) NOT NULL DEFAULT 1,
                    `allow_skip_steps` tinyint(1) NOT NULL DEFAULT 0,
                    `session_timeout` int(11) NOT NULL DEFAULT 3600,
                    `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
                    `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                    PRIMARY KEY (`id`),
                    UNIQUE KEY `landing_page_id` (`landing_page_id`),
                    FOREIGN KEY (`landing_page_id`) REFERENCES `pages` (`id`) ON DELETE CASCADE
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
                
                $this->db->query($sql);
                $this->db->execute();
                
                logInfo("Tabela flow_settings criada com sucesso");
                return true;
            }
            
            return true;
        } catch (Exception $e) {
            logError("Erro ao criar tabela flow_settings: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Gera URL para próxima etapa no fluxo
     */
    public function generateNextStepUrl($currentType, $landingPageId) {
        $nextType = $this->getNextStepType($currentType);
        
        if (!$nextType) {
            return '#'; // Página final
        }
        
        // Se for landing page, usar auto como ID
        if ($currentType === 'landing') {
            return "/pages/{$nextType}?landing=auto";
        }
        
        return "/pages/{$nextType}?landing={$landingPageId}";
    }
    
    /**
     * Gera link CTA padrão baseado no tipo e fluxo
     */
    public function generateDefaultCtaLink($type, $landingPageId, $currentSlug = null) {
        switch ($type) {
            case 'landing':
                // Para landing page, link para step1 com ID da própria landing
                return $currentSlug ? "/pages/step1?landing={$currentSlug}" : "/pages/step1?landing=auto";
                
            case 'step1':
                // Para step1, link para registration
                return $landingPageId ? "/pages/registration?landing={$landingPageId}" : "/pages/registration";
                
            case 'registration':
                // Página final, sem próximo passo
                return "#";
                
            default:
                return "#";
        }
    }
    
    /**
     * Obtém próximo tipo no fluxo
     */
    public function getNextStepType($currentType) {
        return isset($this->flowMap[$currentType]) ? $this->flowMap[$currentType] : null;
    }
    
    /**
     * Obtém tipo anterior no fluxo
     */
    public function getPreviousStepType($currentType) {
        $reversed = array_flip($this->flowMap);
        return isset($reversed[$currentType]) ? $reversed[$currentType] : null;
    }
    
    /**
     * Verifica se um tipo é válido
     */
    public function isValidPageType($type) {
        return array_key_exists($type, $this->typeNames);
    }
    
    /**
     * Obtém nome amigável do tipo
     */
    public function getTypeName($type) {
        return isset($this->typeNames[$type]) ? $this->typeNames[$type] : ucfirst($type);
    }
    
    /**
     * Obtém todas as páginas de um fluxo específico
     */
    public function getFlowPages($landingPageId) {
        try {
            $this->db->query("SELECT * FROM pages 
                             WHERE (id = :landing_id AND type = 'landing') 
                                OR (landing_page_id = :landing_id AND type IN ('step1', 'registration'))
                             ORDER BY 
                                CASE type 
                                    WHEN 'landing' THEN 1 
                                    WHEN 'step1' THEN 2 
                                    WHEN 'registration' THEN 3 
                                END");
            
            $this->db->bind(':landing_id', $landingPageId);
            return $this->db->resultSet();
        } catch (Exception $e) {
            logError("Erro ao buscar páginas do fluxo: " . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Verifica se um fluxo está completo
     */
    public function isFlowComplete($landingPageId) {
        $pages = $this->getFlowPages($landingPageId);
        $types = array_column($pages, 'type');
        
        // Um fluxo completo deve ter pelo menos landing e registration
        $requiredTypes = ['landing', 'registration'];
        
        foreach ($requiredTypes as $type) {
            if (!in_array($type, $types)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Busca configurações de fluxo
     */
    public function getFlowSettings($landingPageId) {
        try {
            $this->createFlowSettingsTable();
            
            $this->db->query("SELECT * FROM flow_settings WHERE landing_page_id = :landing_id");
            $this->db->bind(':landing_id', $landingPageId);
            $result = $this->db->single();
            
            if (!$result) {
                // Retornar configurações padrão
                return [
                    'landing_page_id' => $landingPageId,
                    'require_sequential_access' => true,
                    'allow_skip_steps' => false,
                    'session_timeout' => 3600
                ];
            }
            
            return $result;
        } catch (Exception $e) {
            logError("Erro ao buscar configurações de fluxo: " . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Atualiza configurações de fluxo
     */
    public function updateFlowSettings($landingPageId, $settings) {
        try {
            $this->createFlowSettingsTable();
            
            // Verificar se já existe
            $this->db->query("SELECT id FROM flow_settings WHERE landing_page_id = :landing_id");
            $this->db->bind(':landing_id', $landingPageId);
            $existing = $this->db->single();
            
            if ($existing) {
                // Atualizar
                $this->db->query("UPDATE flow_settings SET 
                                 require_sequential_access = :sequential,
                                 allow_skip_steps = :skip,
                                 session_timeout = :timeout,
                                 updated_at = NOW()
                                 WHERE landing_page_id = :landing_id");
            } else {
                // Inserir
                $this->db->query("INSERT INTO flow_settings 
                                 (landing_page_id, require_sequential_access, allow_skip_steps, session_timeout) 
                                 VALUES (:landing_id, :sequential, :skip, :timeout)");
            }
            
            $this->db->bind(':landing_id', $landingPageId);
            $this->db->bind(':sequential', $settings['require_sequential_access'] ? 1 : 0);
            $this->db->bind(':skip', $settings['allow_skip_steps'] ? 1 : 0);
            $this->db->bind(':timeout', $settings['session_timeout']);
            
            return $this->db->execute();
        } catch (Exception $e) {
            logError("Erro ao atualizar configurações de fluxo: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Atualiza CTAs da landing page após criação
     */
    public function updateLandingPageCtas($landingPageId) {
        try {
            // Atualizar o CTA da landing page para incluir seu próprio ID
            $this->db->query("UPDATE pages SET 
                             cta_link = REPLACE(cta_link, '?landing=auto', CONCAT('?landing=', :landing_id))
                             WHERE id = :landing_id AND type = 'landing'");
            
            $this->db->bind(':landing_id', $landingPageId);
            return $this->db->execute();
        } catch (Exception $e) {
            logError("Erro ao atualizar CTAs da landing page: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Valida acesso sequencial (se habilitado)
     */
    public function validateSequentialAccess($landingPageId, $requestedType, $userSession = null) {
        $settings = $this->getFlowSettings($landingPageId);
        
        if (!$settings || !$settings['require_sequential_access']) {
            return true; // Acesso livre
        }
        
        // Verificar se o usuário já passou pelas etapas anteriores
        if (!$userSession) {
            $userSession = $_SESSION;
        }
        
        $sessionKey = "flow_progress_{$landingPageId}";
        $progress = isset($userSession[$sessionKey]) ? $userSession[$sessionKey] : [];
        
        switch ($requestedType) {
            case 'landing':
                return true; // Sempre pode acessar landing
                
            case 'step1':
                return in_array('landing', $progress);
                
            case 'registration':
                return in_array('step1', $progress) || $settings['allow_skip_steps'];
                
            default:
                return false;
        }
    }
    
    /**
     * Registra progresso do usuário no fluxo
     */
    public function registerProgress($landingPageId, $pageType) {
        $sessionKey = "flow_progress_{$landingPageId}";
        
        if (!isset($_SESSION[$sessionKey])) {
            $_SESSION[$sessionKey] = [];
        }
        
        if (!in_array($pageType, $_SESSION[$sessionKey])) {
            $_SESSION[$sessionKey][] = $pageType;
        }
        
        // Definir timestamp da última atividade
        $_SESSION[$sessionKey . '_last_activity'] = time();
    }
    
    /**
     * Verifica se a sessão do fluxo expirou
     */
    public function isFlowSessionExpired($landingPageId) {
        $settings = $this->getFlowSettings($landingPageId);
        $sessionKey = "flow_progress_{$landingPageId}_last_activity";
        
        if (!isset($_SESSION[$sessionKey])) {
            return true;
        }
        
        $lastActivity = $_SESSION[$sessionKey];
        $timeout = $settings ? $settings['session_timeout'] : 3600;
        
        return (time() - $lastActivity) > $timeout;
    }
    
    /**
     * Limpa progresso do fluxo
     */
    public function clearFlowProgress($landingPageId) {
        $sessionKey = "flow_progress_{$landingPageId}";
        unset($_SESSION[$sessionKey]);
        unset($_SESSION[$sessionKey . '_last_activity']);
    }
    
    /**
     * Obtém estatísticas de um fluxo
     */
    public function getFlowStats($landingPageId) {
        try {
            // Total de visualizações por tipo
            $this->db->query("SELECT p.type, COUNT(pv.id) as views
                             FROM pages p
                             LEFT JOIN page_views pv ON p.id = pv.page_id
                             WHERE (p.id = :landing_id AND p.type = 'landing')
                                OR (p.landing_page_id = :landing_id)
                             GROUP BY p.type");
            
            $this->db->bind(':landing_id', $landingPageId);
            $views = $this->db->resultSet();
            
            $stats = [
                'total_views' => 0,
                'conversion_rate' => 0,
                'pages' => []
            ];
            
            foreach ($views as $view) {
                $stats['pages'][$view['type']] = [
                    'views' => $view['views'],
                    'type_name' => $this->getTypeName($view['type'])
                ];
                $stats['total_views'] += $view['views'];
            }
            
            // Calcular taxa de conversão (registration / landing)
            if (isset($stats['pages']['landing']) && isset($stats['pages']['registration'])) {
                $landingViews = $stats['pages']['landing']['views'];
                $registrationViews = $stats['pages']['registration']['views'];
                
                if ($landingViews > 0) {
                    $stats['conversion_rate'] = round(($registrationViews / $landingViews) * 100, 2);
                }
            }
            
            return $stats;
        } catch (Exception $e) {
            logError("Erro ao buscar estatísticas do fluxo: " . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Gera breadcrumb do fluxo
     */
    public function generateFlowBreadcrumb($landingPageId, $currentType) {
        $pages = $this->getFlowPages($landingPageId);
        $breadcrumb = [];
        
        $flowOrder = ['landing', 'step1', 'registration'];
        
        foreach ($flowOrder as $type) {
            $page = array_filter($pages, function($p) use ($type) {
                return $p['type'] === $type;
            });
            
            if (!empty($page)) {
                $page = reset($page);
                $breadcrumb[] = [
                    'type' => $type,
                    'title' => $page['title'],
                    'slug' => $page['slug'],
                    'active' => $type === $currentType,
                    'accessible' => $this->validateSequentialAccess($landingPageId, $type)
                ];
            }
        }
        
        return $breadcrumb;
    }
    
    /**
     * Debug das configurações de fluxo
     */
    public function diagnose($landingPageId = null) {
        $issues = [];
        
        try {
            // Verificar se a tabela de configurações existe
            $tableExists = $this->db->tableExists('flow_settings');
            $issues[] = $tableExists ? "✓ Tabela flow_settings existe" : "❌ Tabela flow_settings não existe";
            
            if ($landingPageId) {
                $pages = $this->getFlowPages($landingPageId);
                $issues[] = "✓ Encontradas " . count($pages) . " páginas no fluxo {$landingPageId}";
                
                $complete = $this->isFlowComplete($landingPageId);
                $issues[] = $complete ? "✓ Fluxo está completo" : "⚠️ Fluxo incompleto";
                
                $settings = $this->getFlowSettings($landingPageId);
                if ($settings) {
                    $issues[] = "✓ Configurações carregadas";
                    $issues[] = "  - Acesso sequencial: " . ($settings['require_sequential_access'] ? 'Sim' : 'Não');
                    $issues[] = "  - Permitir pular: " . ($settings['allow_skip_steps'] ? 'Sim' : 'Não');
                    $issues[] = "  - Timeout: " . $settings['session_timeout'] . "s";
                } else {
                    $issues[] = "⚠️ Nenhuma configuração encontrada";
                }
            }
            
        } catch (Exception $e) {
            $issues[] = "❌ Erro: " . $e->getMessage();
        }
        
        return $issues;
    }
}

// Instanciar a classe globalmente
try {
    $pageFlow = new PageFlow();
} catch (Exception $e) {
    logError("Erro ao instanciar PageFlow: " . $e->getMessage());
    // Criar um objeto mock para evitar erros
    $pageFlow = new class {
        public function generateNextStepUrl($currentType, $landingPageId) { return '#'; }
        public function generateDefaultCtaLink($type, $landingPageId, $currentSlug = null) { return '#'; }
        public function updateLandingPageCtas($landingPageId) { return false; }
        public function getTypeName($type) { return ucfirst($type); }
        public function isValidPageType($type) { return true; }
        public function diagnose($landingPageId = null) { return ['❌ PageFlow não pôde ser inicializado']; }
    };
}