<?php

namespace Modules\Integracoes\WhatsApp\Services;

use PDO;
use Exception;

/**
 * Serviço para integração com WhatsApp Business API
 */
class WhatsAppAPIService {
    private PDO $pdo;
    private string $tenantId;
    private string $baseUrl = 'https://graph.facebook.com/v18.0';

    public function __construct(string $tenantId) {
        $this->tenantId = $tenantId;
        $this->pdo = \Gestoreasy\Core\Tenant\ConnectionManager::forTenant($tenantId);
    }

    /**
     * Obtém configuração
     */
    public function getConfig(): array {
        $stmt = $this->pdo->prepare('SELECT * FROM whatsapp_config WHERE tenant_id = ?');
        $stmt->execute([$this->tenantId]);
        $config = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$config) {
            return [
                'ativo' => false,
                'enviar_notificacoes' => true
            ];
        }

        // Não retornar token
        unset($config['access_token'], $config['app_secret']);

        return $config;
    }

    /**
     * Atualiza configuração
     */
    public function updateConfig(array $dados): void {
        $stmt = $this->pdo->prepare('SELECT id FROM whatsapp_config WHERE tenant_id = ?');
        $stmt->execute([$this->tenantId]);
        $exists = $stmt->fetch();

        $allowedFields = [
            'phone_number_id', 'access_token', 'business_account_id',
            'app_id', 'app_secret', 'webhook_verify_token', 'webhook_url',
            'enviar_notificacoes', 'templates_aprovados', 'ativo'
        ];

        if ($exists) {
            $updates = [];
            $params = [];
            foreach ($allowedFields as $field) {
                if (isset($dados[$field])) {
                    $updates[] = "{$field} = ?";
                    $params[] = $dados[$field];
                }
            }
            if (!empty($updates)) {
                $params[] = $this->tenantId;
                $sql = 'UPDATE whatsapp_config SET ' . implode(', ', $updates) . ' WHERE tenant_id = ?';
                $stmt = $this->pdo->prepare($sql);
                $stmt->execute($params);
            }
        } else {
            $fields = [];
            $values = [];
            $params = [];
            foreach ($allowedFields as $field) {
                if (isset($dados[$field])) {
                    $fields[] = $field;
                    $values[] = '?';
                    $params[] = $dados[$field];
                }
            }
            if (!empty($fields)) {
                $params[] = $this->tenantId;
                $sql = 'INSERT INTO whatsapp_config (tenant_id, ' . implode(', ', $fields) . ') VALUES (?, ' . implode(', ', $values) . ')';
                $stmt = $this->pdo->prepare($sql);
                $stmt->execute($params);
            }
        }
    }

    /**
     * Envia mensagem
     */
    public function enviarMensagem(string $numero, string $mensagem, ?int $templateId = null, ?array $variaveis = null): array {
        $config = $this->getConfig();
        
        if (!$config['ativo'] || empty($config['access_token'])) {
            throw new Exception('WhatsApp não está configurado ou ativo');
        }

        $phoneNumberId = $config['phone_number_id'];
        $numero = preg_replace('/[^0-9]/', '', $numero);

        if ($templateId) {
            // Enviar template
            $resultado = $this->enviarTemplate($phoneNumberId, $numero, $templateId, $variaveis);
        } else {
            // Enviar mensagem de texto
            $resultado = $this->enviarTexto($phoneNumberId, $numero, $mensagem);
        }

        // Salvar mensagem
        $mensagemId = $this->salvarMensagem([
            'tipo' => 'enviada',
            'direcao' => 'outbound',
            'numero_telefone' => $numero,
            'tipo_mensagem' => $templateId ? 'template' : 'text',
            'conteudo' => $mensagem,
            'template_id' => $templateId,
            'status' => 'enviada',
            'mensagem_id_whatsapp' => $resultado['messages'][0]['id'] ?? null
        ]);

        return [
            'mensagem_id' => $mensagemId,
            'whatsapp_id' => $resultado['messages'][0]['id'] ?? null,
            'status' => 'enviada'
        ];
    }

    /**
     * Envia mensagem de texto
     */
    private function enviarTexto(string $phoneNumberId, string $numero, string $mensagem): array {
        $url = "{$this->baseUrl}/{$phoneNumberId}/messages";
        $config = $this->getConfig();
        
        $data = [
            'messaging_product' => 'whatsapp',
            'to' => $numero,
            'type' => 'text',
            'text' => [
                'body' => $mensagem
            ]
        ];

        return $this->request($url, 'POST', $data, $config['access_token']);
    }

    /**
     * Envia template
     */
    private function enviarTemplate(string $phoneNumberId, string $numero, int $templateId, ?array $variaveis): array {
        // Buscar template
        $stmt = $this->pdo->prepare('SELECT * FROM whatsapp_templates WHERE id = ? AND tenant_id = ?');
        $stmt->execute([$templateId, $this->tenantId]);
        $template = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$template || !$template['aprovado']) {
            throw new Exception('Template não encontrado ou não aprovado');
        }

        $url = "{$this->baseUrl}/{$phoneNumberId}/messages";
        $config = $this->getConfig();
        
        $data = [
            'messaging_product' => 'whatsapp',
            'to' => $numero,
            'type' => 'template',
            'template' => [
                'name' => $template['template_id_whatsapp'],
                'language' => ['code' => 'pt_BR']
            ]
        ];

        if (!empty($variaveis)) {
            $data['template']['components'] = [
                [
                    'type' => 'body',
                    'parameters' => array_map(function($var) {
                        return ['type' => 'text', 'text' => $var];
                    }, $variaveis)
                ]
            ];
        }

        return $this->request($url, 'POST', $data, $config['access_token']);
    }

    /**
     * Faz requisição à API
     */
    private function request(string $url, string $method, array $data, string $token): array {
        $headers = [
            'Authorization: Bearer ' . $token,
            'Content-Type: application/json'
        ];

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_TIMEOUT => 30,
        ]);

        $response = curl_exec($ch);
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new Exception("Erro na requisição: {$error}");
        }

        if ($statusCode >= 400) {
            $errorData = json_decode($response, true);
            throw new Exception($errorData['error']['message'] ?? "Erro HTTP {$statusCode}");
        }

        return json_decode($response, true) ?? [];
    }

    /**
     * Salva mensagem
     */
    private function salvarMensagem(array $dados): int {
        $stmt = $this->pdo->prepare('
            INSERT INTO whatsapp_mensagens (
                tenant_id, mensagem_id_whatsapp, tipo, direcao,
                numero_telefone, nome_contato, tipo_mensagem,
                conteudo, template_id, status, cliente_id, pedido_id
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ');
        $stmt->execute([
            $this->tenantId,
            $dados['mensagem_id_whatsapp'] ?? null,
            $dados['tipo'],
            $dados['direcao'],
            $dados['numero_telefone'],
            $dados['nome_contato'] ?? null,
            $dados['tipo_mensagem'] ?? 'text',
            $dados['conteudo'],
            $dados['template_id'] ?? null,
            $dados['status'] ?? 'enviando',
            $dados['cliente_id'] ?? null,
            $dados['pedido_id'] ?? null
        ]);

        return (int)$this->pdo->lastInsertId();
    }

    /**
     * Lista mensagens
     */
    public function listMensagens(?string $numero = null, ?int $clienteId = null, int $limite = 50): array {
        $where = ['tenant_id = ?'];
        $params = [$this->tenantId];

        if ($numero) {
            $where[] = 'numero_telefone = ?';
            $params[] = $numero;
        }

        if ($clienteId) {
            $where[] = 'cliente_id = ?';
            $params[] = $clienteId;
        }

        $whereSql = implode(' AND ', $where);
        $sql = "
            SELECT * FROM whatsapp_mensagens
            WHERE {$whereSql}
            ORDER BY created_at DESC
            LIMIT ?
        ";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(array_merge($params, [$limite]));

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Lista templates
     */
    public function listTemplates(): array {
        $stmt = $this->pdo->prepare('
            SELECT * FROM whatsapp_templates
            WHERE tenant_id = ?
            ORDER BY nome ASC
        ');
        $stmt->execute([$this->tenantId]);

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Processa webhook do WhatsApp
     */
    public function processarWebhook(array $dados): void {
        $entry = $dados['entry'][0] ?? null;
        if (!$entry) {
            return;
        }

        $changes = $entry['changes'] ?? [];
        foreach ($changes as $change) {
            $value = $change['value'] ?? [];
            
            // Mensagens recebidas
            if (isset($value['messages'])) {
                foreach ($value['messages'] as $message) {
                    $this->processarMensagemRecebida($message);
                }
            }

            // Status de mensagens enviadas
            if (isset($value['statuses'])) {
                foreach ($value['statuses'] as $status) {
                    $this->atualizarStatusMensagem($status);
                }
            }
        }
    }

    /**
     * Processa mensagem recebida
     */
    private function processarMensagemRecebida(array $message): void {
        $numero = $message['from'] ?? '';
        $conteudo = $message['text']['body'] ?? '';
        $mensagemId = $message['id'] ?? '';

        // Buscar cliente por telefone
        $stmt = $this->pdo->prepare('
            SELECT id, nome FROM clients
            WHERE telefone LIKE ? OR celular LIKE ?
            LIMIT 1
        ');
        $stmt->execute(["%{$numero}%", "%{$numero}%"]);
        $cliente = $stmt->fetch(PDO::FETCH_ASSOC);

        // Salvar mensagem
        $this->salvarMensagem([
            'tipo' => 'recebida',
            'direcao' => 'inbound',
            'numero_telefone' => $numero,
            'tipo_mensagem' => 'text',
            'conteudo' => $conteudo,
            'status' => 'lida',
            'mensagem_id_whatsapp' => $mensagemId,
            'cliente_id' => $cliente['id'] ?? null,
            'nome_contato' => $cliente['nome'] ?? null
        ]);
    }

    /**
     * Atualiza status de mensagem
     */
    private function atualizarStatusMensagem(array $status): void {
        $mensagemId = $status['id'] ?? '';
        $statusWhatsapp = $status['status'] ?? '';

        $statusMap = [
            'sent' => 'enviada',
            'delivered' => 'entregue',
            'read' => 'lida',
            'failed' => 'erro'
        ];

        $statusLocal = $statusMap[$statusWhatsapp] ?? 'enviando';

        $stmt = $this->pdo->prepare('
            UPDATE whatsapp_mensagens
            SET status = ?,
                status_whatsapp = ?,
                updated_at = NOW()
            WHERE mensagem_id_whatsapp = ? AND tenant_id = ?
        ');
        $stmt->execute([$statusLocal, $statusWhatsapp, $mensagemId, $this->tenantId]);
    }
}

