<?php
namespace Modules\Ecommerce\Controllers;

use Gestoreasy\Core\Http\Request;
use Gestoreasy\Core\Http\Response;
use Gestoreasy\Core\View\View;
use Gestoreasy\Core\Tenant\ConnectionManager;
use Gestoreasy\Core\Tenant\TenantContext;

class EcommercePublicController {
    private function getTenantId(): string {
        return TenantContext::getTenantId();
    }

    private function getConfig(): ?array {
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        
        $stmt = $pdo->prepare('SELECT * FROM ecommerce_config WHERE tenant_id = ? AND enabled = TRUE LIMIT 1');
        $stmt->execute([$tenantId]);
        return $stmt->fetch() ?: null;
    }

    // Views públicas
    public function viewHome(Request $req): Response {
        $config = $this->getConfig();
        if (!$config) {
            return new Response(404, 'E-commerce não configurado');
        }
        
        // Obter template configurado
        $templateId = $config['template_id'] ?? 'default';
        $templatePath = __DIR__ . '/../../../public/ecommerce/templates/' . $templateId . '/index.php';
        
        // Se template não existir, usar default
        if (!file_exists($templatePath)) {
            $templatePath = __DIR__ . '/../../../public/ecommerce/templates/default/index.php';
        }
        
        // Renderizar template
        extract(['config' => $config, 'title' => $config['store_name'] ?? 'Loja']);
        ob_start();
        include $templatePath;
        $content = ob_get_clean();
        
        return new Response(200, $content, ['Content-Type' => 'text/html; charset=utf-8']);
    }

    public function viewProduto(Request $req): Response {
        $config = $this->getConfig();
        if (!$config) {
            return new Response(404, 'E-commerce não configurado');
        }
        
        $productId = $req->get('params')[0] ?? null;
        if (!$productId) {
            return new Response(404, 'Produto não encontrado');
        }
        
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        
        $stmt = $pdo->prepare('SELECT p.*, ep.custom_price, ep.seo_title, ep.seo_description 
            FROM products p
            LEFT JOIN ecommerce_produtos ep ON ep.product_id = p.id AND ep.tenant_id = ?
            WHERE p.id = ? AND (ep.visible = TRUE OR ep.visible IS NULL)
            LIMIT 1');
        $stmt->execute([$tenantId, $productId]);
        $produto = $stmt->fetch();
        
        if (!$produto) {
            return new Response(404, 'Produto não encontrado');
        }
        
        // Usar template configurado
        $templateId = $config['template_id'] ?? 'default';
        $templatePath = __DIR__ . '/../../../public/ecommerce/templates/' . $templateId . '/produto.php';
        
        if (!file_exists($templatePath)) {
            $templatePath = __DIR__ . '/../../../public/ecommerce/templates/default/produto.php';
        }
        
        // Se não existir template específico de produto, usar view padrão
        if (!file_exists($templatePath)) {
            return View::render('ecommerce/public/produto.php', [
                'config' => $config,
                'produto' => $produto,
                'title' => $produto['nome'] ?? 'Produto'
            ]);
        }
        
        extract(['config' => $config, 'produto' => $produto, 'title' => $produto['nome'] ?? 'Produto']);
        ob_start();
        include $templatePath;
        $content = ob_get_clean();
        
        return new Response(200, $content, ['Content-Type' => 'text/html; charset=utf-8']);
    }

    public function viewCategoria(Request $req): Response {
        $config = $this->getConfig();
        if (!$config) {
            return new Response(404, 'E-commerce não configurado');
        }
        
        $slug = $req->get('params')[0] ?? null;
        // Implementar busca por categoria
        return View::render('ecommerce/public/categoria', [
            'config' => $config,
            'slug' => $slug,
            'title' => 'Categoria'
        ]);
    }

    public function viewCarrinho(Request $req): Response {
        $config = $this->getConfig();
        if (!$config) {
            return new Response(404, 'E-commerce não configurado');
        }
        
        return View::render('ecommerce/public/carrinho', [
            'config' => $config,
            'title' => 'Carrinho de Compras'
        ]);
    }

    public function viewCheckout(Request $req): Response {
        $config = $this->getConfig();
        if (!$config) {
            return new Response(404, 'E-commerce não configurado');
        }
        
        return View::render('ecommerce/public/checkout', [
            'config' => $config,
            'title' => 'Finalizar Compra'
        ]);
    }

    // API Pública
    public function listProdutos(Request $req): Response {
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        
        $page = (int)($req->get('page') ?? 1);
        $perPage = (int)($req->get('per_page') ?? 20);
        $offset = ($page - 1) * $perPage;
        $categoria = $req->get('categoria');
        $busca = $req->get('q');
        
        $sql = 'SELECT 
            p.id, p.codigo, p.nome, p.preco, p.estoque,
            COALESCE(ep.custom_price, p.preco) as preco_final,
            ep.seo_title, ep.seo_description
        FROM products p
        INNER JOIN ecommerce_produtos ep ON ep.product_id = p.id AND ep.tenant_id = ?
        WHERE ep.visible = TRUE AND p.estoque > 0';
        
        $params = [$tenantId];
        
        if ($categoria) {
            $sql .= ' AND EXISTS (
                SELECT 1 FROM ecommerce_produto_categorias epc
                INNER JOIN ecommerce_categorias ec ON ec.id = epc.categoria_id
                WHERE epc.produto_id = ep.id AND ec.slug = ?
            )';
            $params[] = $categoria;
        }
        
        if ($busca) {
            $sql .= ' AND (p.nome LIKE ? OR p.codigo LIKE ?)';
            $buscaParam = "%$busca%";
            $params[] = $buscaParam;
            $params[] = $buscaParam;
        }
        
        $sql .= ' ORDER BY ep.featured DESC, ep.order_index ASC, p.created_at DESC LIMIT ? OFFSET ?';
        $params[] = $perPage;
        $params[] = $offset;
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $produtos = $stmt->fetchAll();
        
        // Contar total
        $countSql = 'SELECT COUNT(*) as total
        FROM products p
        INNER JOIN ecommerce_produtos ep ON ep.product_id = p.id AND ep.tenant_id = ?
        WHERE ep.visible = TRUE AND p.estoque > 0';
        
        $countParams = [$tenantId];
        if ($categoria) {
            $countSql .= ' AND EXISTS (
                SELECT 1 FROM ecommerce_produto_categorias epc
                INNER JOIN ecommerce_categorias ec ON ec.id = epc.categoria_id
                WHERE epc.produto_id = ep.id AND ec.slug = ?
            )';
            $countParams[] = $categoria;
        }
        if ($busca) {
            $countSql .= ' AND (p.nome LIKE ? OR p.codigo LIKE ?)';
            $buscaParam = "%$busca%";
            $countParams[] = $buscaParam;
            $countParams[] = $buscaParam;
        }
        
        $stmt = $pdo->prepare($countSql);
        $stmt->execute($countParams);
        $total = (int)$stmt->fetch()['total'];
        
        return Response::json([
            'data' => $produtos,
            'page' => $page,
            'per_page' => $perPage,
            'total' => $total,
            'total_pages' => ceil($total / $perPage)
        ]);
    }

    public function getProduto(Request $req): Response {
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        $productId = $req->get('params')[0] ?? null;
        
        if (!$productId) {
            return new Response(422, ['error' => ['code' => 'invalid_id', 'message' => 'ID do produto inválido']]);
        }
        
        $stmt = $pdo->prepare('SELECT 
            p.*,
            COALESCE(ep.custom_price, p.preco) as preco_final,
            ep.seo_title, ep.seo_description, ep.seo_keywords
        FROM products p
        LEFT JOIN ecommerce_produtos ep ON ep.product_id = p.id AND ep.tenant_id = ?
        WHERE p.id = ? AND (ep.visible = TRUE OR ep.visible IS NULL)
        LIMIT 1');
        $stmt->execute([$tenantId, $productId]);
        $produto = $stmt->fetch();
        
        if (!$produto) {
            return new Response(404, ['error' => ['code' => 'not_found', 'message' => 'Produto não encontrado']]);
        }
        
        return Response::json(['data' => $produto]);
    }

    public function listCategorias(Request $req): Response {
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        
        $stmt = $pdo->prepare('SELECT * FROM ecommerce_categorias WHERE tenant_id = ? AND enabled = TRUE ORDER BY order_index ASC, name ASC');
        $stmt->execute([$tenantId]);
        $categorias = $stmt->fetchAll();
        
        return Response::json(['data' => $categorias]);
    }

    public function calcularFrete(Request $req): Response {
        $body = $req->body;
        $cepDestino = preg_replace('/\D/', '', $body['cep'] ?? '');
        $produtos = $body['produtos'] ?? [];
        
        if (empty($cepDestino) || strlen($cepDestino) !== 8) {
            return new Response(422, ['error' => ['code' => 'invalid_cep', 'message' => 'CEP inválido']]);
        }
        
        if (empty($produtos)) {
            return new Response(422, ['error' => ['code' => 'no_products', 'message' => 'Nenhum produto informado']]);
        }
        
        // Reutilizar lógica do controller administrativo
        $ctrl = new EcommerceController();
        return $ctrl->calcularFrete($req);
    }

    public function criarPedido(Request $req): Response {
        $pdo = ConnectionManager::forTenant();
        $tenantId = $this->getTenantId();
        $body = $req->body;
        
        // Validar dados
        $cliente = $body['cliente'] ?? [];
        $produtos = $body['produtos'] ?? [];
        $endereco = $body['endereco'] ?? [];
        
        if (empty($cliente['nome']) || empty($cliente['email'])) {
            return new Response(422, ['error' => ['code' => 'invalid_cliente', 'message' => 'Dados do cliente incompletos']]);
        }
        
        if (empty($produtos)) {
            return new Response(422, ['error' => ['code' => 'no_products', 'message' => 'Nenhum produto no pedido']]);
        }
        
        // Usar serviço de integração para validar estoque
        $integrationService = new \Modules\Ecommerce\Services\EcommerceIntegrationService();
        $validacaoEstoque = $integrationService->validateEstoque($produtos);
        
        if (!$validacaoEstoque['valid']) {
            return new Response(422, [
                'error' => [
                    'code' => 'insufficient_stock',
                    'message' => 'Estoque insuficiente para alguns produtos',
                    'details' => $validacaoEstoque['errors']
                ]
            ]);
        }
        
        // Calcular totais usando produtos validados
        $subtotal = 0;
        $itens = [];
        
        foreach ($validacaoEstoque['produtos'] as $item) {
            $produto = $item['produto'];
            $quantidade = $item['quantidade'];
            
            // Buscar preço customizado do e-commerce
            $stmt = $pdo->prepare('SELECT COALESCE(ep.custom_price, p.preco) as preco_final
                FROM products p
                LEFT JOIN ecommerce_produtos ep ON ep.product_id = p.id AND ep.tenant_id = ?
                WHERE p.id = ? LIMIT 1');
            $stmt->execute([$tenantId, $produto['id']]);
            $precoData = $stmt->fetch();
            $preco = (float)($precoData['preco_final'] ?? $produto['preco']);
            
            $itemSubtotal = $preco * $quantidade;
            
            $itens[] = [
                'product_id' => $produto['id'],
                'codigo' => $produto['codigo'],
                'nome' => $produto['nome'],
                'quantidade' => $quantidade,
                'preco_unitario' => $preco,
                'subtotal' => $itemSubtotal
            ];
            
            $subtotal += $itemSubtotal;
        }
        
        $frete = (float)($body['frete'] ?? 0);
        $desconto = (float)($body['desconto'] ?? 0);
        $total = $subtotal + $frete - $desconto;
        
        // Gerar número do pedido
        $numeroPedido = 'PED-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -6));
        
        try {
            $pdo->beginTransaction();
            
            // Criar pedido
            $stmt = $pdo->prepare('INSERT INTO ecommerce_pedidos 
                (tenant_id, numero_pedido, cliente_nome, cliente_email, cliente_telefone, cliente_cpf, 
                 endereco_entrega, subtotal, frete, desconto, total, status)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
            $stmt->execute([
                $tenantId,
                $numeroPedido,
                $cliente['nome'],
                $cliente['email'],
                $cliente['telefone'] ?? null,
                $cliente['cpf'] ?? null,
                json_encode($endereco),
                $subtotal,
                $frete,
                $desconto,
                $total,
                'pendente'
            ]);
            
            $pedidoId = (int)$pdo->lastInsertId();
            
            // Criar itens
            foreach ($itens as $item) {
                $stmt = $pdo->prepare('INSERT INTO ecommerce_pedido_itens 
                    (pedido_id, product_id, codigo, nome, quantidade, preco_unitario, subtotal)
                    VALUES (?, ?, ?, ?, ?, ?, ?)');
                $stmt->execute([
                    $pedidoId,
                    $item['product_id'],
                    $item['codigo'],
                    $item['nome'],
                    $item['quantidade'],
                    $item['preco_unitario'],
                    $item['subtotal']
                ]);
            }
            
            $pdo->commit();
            
            return Response::json([
                'message' => 'Pedido criado com sucesso',
                'data' => [
                    'pedido_id' => $pedidoId,
                    'numero_pedido' => $numeroPedido,
                    'total' => $total
                ]
            ]);
        } catch (\Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            error_log("[Ecommerce] Erro ao criar pedido: " . $e->getMessage());
            return new Response(500, ['error' => ['code' => 'order_creation_failed', 'message' => 'Erro ao criar pedido']]);
        }
    }

    public function webhookPagamento(Request $req): Response {
        // Processar webhook de pagamento (Mercado Pago, PagBank, etc.)
        $body = $req->body;
        $provider = $req->header('x-payment-provider') ?? 'unknown';
        
        // Extrair ID do pedido do webhook
        $pedidoId = $body['pedido_id'] ?? $body['external_reference'] ?? null;
        $paymentStatus = $body['status'] ?? $body['payment_status'] ?? 'pending';
        $paymentId = $body['id'] ?? $body['payment_id'] ?? null;
        
        if (!$pedidoId) {
            error_log("[Ecommerce] Webhook sem pedido_id: " . json_encode($body));
            return new Response(422, ['error' => ['code' => 'missing_pedido_id', 'message' => 'pedido_id não encontrado no webhook']]);
        }
        
        // Usar serviço de integração para processar pagamento
        $integrationService = new \Modules\Ecommerce\Services\EcommerceIntegrationService();
        $sucesso = $integrationService->processarPagamento((int)$pedidoId, $paymentStatus, $paymentId);
        
        if ($sucesso) {
            return Response::json(['message' => 'Pagamento processado com sucesso']);
        } else {
            return new Response(500, ['error' => ['code' => 'payment_processing_failed', 'message' => 'Erro ao processar pagamento']]);
        }
    }
}

