<?php
/**
 * NEXUS IT - Email Service
 * Envío de correos via SMTP
 */
class EmailService {

    private static function getConfig(): array {
        $db = getDB();
        $stmt = $db->query("SELECT clave, valor FROM configuracion WHERE grupo = 'email'");
        $config = [];
        foreach ($stmt->fetchAll() as $row) {
            $config[$row['clave']] = $row['valor'];
        }
        return $config;
    }

    /**
     * Enviar email
     */
    public static function enviar(string $to, string $subject, string $htmlBody, bool $debug = false): array|bool {
        $config = self::getConfig();
        $host = $config['smtp_host'] ?? '';
        $port = (int)($config['smtp_port'] ?? 587);
        $user = $config['smtp_user'] ?? '';
        $pass = $config['smtp_password'] ?? '';
        $fromName = $config['smtp_from_name'] ?? 'Nexus IT';
        $fromEmail = $config['smtp_from_email'] ?? $user ?? 'nexus@evolucionamos.com';
        if (empty($fromEmail)) $fromEmail = 'nexus@evolucionamos.com';

        if (empty($host)) {
            if ($debug) return ['ok' => false, 'error' => 'SMTP host no configurado', 'config' => ['host' => $host, 'port' => $port, 'user' => $user, 'pass' => $pass ? '***SET***' : '***EMPTY***']];
            return false;
        }

        // localhost or local server: can work without auth
        if ($host === 'localhost' || $host === '127.0.0.1') {
            $result = self::enviarLocal($fromEmail, $fromName, $to, $subject, $htmlBody, $debug);
            return $result;
        }

        if (empty($user) || empty($pass)) {
            if ($debug) return ['ok' => false, 'error' => 'Usuario o contraseña SMTP vacíos', 'config' => ['host' => $host, 'port' => $port, 'user' => $user, 'pass' => $pass ? '***SET***' : '***EMPTY***']];
            return false;
        }

        return self::enviarSMTP($host, $port, $user, $pass, $fromEmail, $fromName, $to, $subject, $htmlBody, $debug);
    }

    /**
     * Send via local server using PHP mail()
     */
    private static function enviarLocal(string $from, string $fromName, string $to, string $subject, string $body, bool $debug = false): array|bool {
        $log = [];
        $log[] = "Using PHP mail() via localhost...";

        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "Content-type: text/html; charset=utf-8\r\n";
        $headers .= "From: {$fromName} <{$from}>\r\n";
        $headers .= "Reply-To: {$from}\r\n";
        $headers .= "X-Mailer: NexusIT/1.0\r\n";

        $subjectEncoded = "=?UTF-8?B?" . base64_encode($subject) . "?=";
        $result = @mail($to, $subjectEncoded, $body, $headers);

        if ($result) {
            $log[] = "SUCCESS: mail() returned true. Email queued for delivery.";
            $log[] = "Note: mail() reports queued, not delivered. Check inbox and spam.";
        } else {
            $error = error_get_last();
            $log[] = "FAIL: mail() returned false.";
            if ($error) $log[] = "PHP Error: " . ($error['message'] ?? 'unknown');
        }

        if ($debug) return ['ok' => $result, 'log' => $log, 'method' => 'php_mail'];
        return $result;
    }

    /**
     * SMTP via fsockopen with detailed logging
     */
    private static function enviarSMTP(string $host, int $port, string $user, string $pass, string $from, string $fromName, string $to, string $subject, string $body, bool $debug = false): array|bool {
        $log = [];
        try {
            // Connect
            $tls = ($port === 465) ? 'ssl://' : '';
            $log[] = "Connecting to {$tls}{$host}:{$port}...";
            $sock = @fsockopen($tls . $host, $port, $errno, $errstr, 15);
            if (!$sock) {
                $log[] = "FAIL: Could not connect: $errstr ($errno)";
                if ($debug) return ['ok' => false, 'error' => "No se pudo conectar a {$host}:{$port} — $errstr", 'log' => $log];
                return false;
            }

            $resp = self::readResp($sock);
            $log[] = "SERVER: $resp";

            // EHLO
            $resp = self::smtpCmd($sock, "EHLO nexusit.local", $log);

            // STARTTLS for port 587
            if ($port === 587) {
                $resp = self::smtpCmd($sock, "STARTTLS", $log);
                if (strpos($resp, '220') === false) {
                    $log[] = "FAIL: STARTTLS rejected";
                    if ($debug) return ['ok' => false, 'error' => 'STARTTLS rechazado por el servidor', 'log' => $log];
                    fclose($sock);
                    return false;
                }
                // Try multiple TLS methods
                $cryptoMethods = STREAM_CRYPTO_METHOD_TLS_CLIENT;
                if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
                    $cryptoMethods = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
                }
                $crypto = @stream_socket_enable_crypto($sock, true, $cryptoMethods);
                if (!$crypto) {
                    // Retry with any TLS
                    $crypto = @stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
                }
                if (!$crypto) {
                    $log[] = "FAIL: TLS handshake failed. Tu hosting puede estar bloqueando conexiones SMTP externas en puerto 587. Intenta puerto 465.";
                    if ($debug) return ['ok' => false, 'error' => 'Error en handshake TLS. Intenta cambiar el puerto a 465 en la configuración.', 'log' => $log];
                    fclose($sock);
                    return false;
                }
                $log[] = "TLS: OK";
                $resp = self::smtpCmd($sock, "EHLO nexusit.local", $log);
            }

            // AUTH LOGIN
            $resp = self::smtpCmd($sock, "AUTH LOGIN", $log);
            if (strpos($resp, '334') === false) {
                $log[] = "FAIL: AUTH LOGIN not accepted";
                if ($debug) return ['ok' => false, 'error' => 'El servidor no acepta AUTH LOGIN', 'log' => $log];
                fclose($sock);
                return false;
            }
            $resp = self::smtpCmd($sock, base64_encode($user), $log, 'USER: ***');
            $resp = self::smtpCmd($sock, base64_encode($pass), $log, 'PASS: ***');

            if (strpos($resp, '235') === false && strpos($resp, '2') !== 0) {
                $log[] = "FAIL: Authentication failed";
                if ($debug) return ['ok' => false, 'error' => 'Autenticación fallida. Verifica usuario y contraseña SMTP.', 'log' => $log];
                fclose($sock);
                return false;
            }
            $log[] = "AUTH: OK";

            // MAIL FROM / RCPT TO
            $resp = self::smtpCmd($sock, "MAIL FROM:<{$from}>", $log);
            $resp = self::smtpCmd($sock, "RCPT TO:<{$to}>", $log);
            if (strpos($resp, '250') === false) {
                $log[] = "FAIL: Recipient rejected";
                if ($debug) return ['ok' => false, 'error' => "Destinatario rechazado: $to", 'log' => $log];
                fclose($sock);
                return false;
            }

            // DATA
            $resp = self::smtpCmd($sock, "DATA", $log);

            $message = "From: {$fromName} <{$from}>\r\n";
            $message .= "To: {$to}\r\n";
            $message .= "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=\r\n";
            $message .= "MIME-Version: 1.0\r\n";
            $message .= "Content-Type: text/html; charset=utf-8\r\n";
            $message .= "Content-Transfer-Encoding: base64\r\n";
            $message .= "Date: " . date('r') . "\r\n";
            $message .= "Message-ID: <" . md5(uniqid()) . "@nexusit.local>\r\n";
            $message .= "\r\n";
            $message .= chunk_split(base64_encode($body));
            $message .= "\r\n.\r\n";

            fwrite($sock, $message);
            $resp = self::readResp($sock);
            $log[] = "DATA RESP: $resp";

            self::smtpCmd($sock, "QUIT", $log);
            fclose($sock);

            $ok = (strpos($resp, '250') !== false);
            $log[] = $ok ? "SUCCESS: Email sent" : "FAIL: Server did not confirm delivery";

            if ($debug) return ['ok' => $ok, 'log' => $log];
            return $ok;

        } catch (\Exception $e) {
            $log[] = "EXCEPTION: " . $e->getMessage();
            error_log("EmailService error: " . $e->getMessage());
            if ($debug) return ['ok' => false, 'error' => $e->getMessage(), 'log' => $log];
            return false;
        }
    }

    private static function smtpCmd($sock, string $cmd, array &$log, string $logAs = ''): string {
        fwrite($sock, $cmd . "\r\n");
        $resp = self::readResp($sock);
        $log[] = ">> " . ($logAs ?: $cmd);
        $log[] = "<< " . $resp;
        return $resp;
    }

    private static function readResp($sock): string {
        $resp = '';
        stream_set_timeout($sock, 10);
        while ($line = fgets($sock, 515)) {
            $resp .= $line;
            if (isset($line[3]) && $line[3] === ' ') break;
        }
        return trim($resp);
    }

    /**
     * TEST: Enviar email de prueba con debug completo
     */
    public static function test(string $to): array {
        $html = self::template('Correo de Prueba', '<p>Este es un correo de prueba desde <strong>Nexus IT</strong>.</p><p>Si recibes este email, la configuración SMTP está funcionando correctamente. ✅</p>', '', '');
        return self::enviar($to, 'Nexus IT — Prueba de Email', $html, true);
    }

    /**
     * Template HTML
     */
    public static function template(string $titulo, string $contenido, string $actionUrl = '', string $actionText = ''): string {
        $btn = $actionUrl ? "<a href=\"{$actionUrl}\" style=\"display:inline-block;padding:12px 28px;background:#6366f1;color:#fff;text-decoration:none;border-radius:8px;font-weight:600;margin-top:16px\">{$actionText}</a>" : '';
        return <<<HTML
<!DOCTYPE html>
<html><head><meta charset="utf-8"></head>
<body style="margin:0;padding:0;background:#0f172a;font-family:system-ui,-apple-system,sans-serif">
<div style="max-width:560px;margin:0 auto;padding:40px 20px">
<div style="background:#1e293b;border-radius:16px;padding:32px;border:1px solid #334155">
<div style="text-align:center;margin-bottom:24px">
<span style="background:#6366f1;color:#fff;padding:8px 16px;border-radius:8px;font-weight:700;font-size:18px">N</span>
<span style="color:#e2e8f0;font-size:20px;font-weight:600;margin-left:8px">Nexus IT</span>
</div>
<h2 style="color:#e2e8f0;font-size:20px;margin:0 0 16px">{$titulo}</h2>
<div style="color:#94a3b8;font-size:14px;line-height:1.7">{$contenido}</div>
{$btn}
</div>
<p style="text-align:center;color:#64748b;font-size:12px;margin-top:16px">Este correo fue enviado automáticamente por Nexus IT</p>
</div>
</body></html>
HTML;
    }

    // ---- Convenience methods ----
    /**
     * Render email from DB template with variable replacement
     */
    public static function renderPlantilla(string $codigo, array $variables, string $actionUrl = '', string $actionText = 'Ver Ticket'): ?array {
        try {
            $db = getDB();
            $stmt = $db->prepare("SELECT asunto, contenido, activo FROM email_plantillas WHERE codigo = ?");
            $stmt->execute([$codigo]);
            $tpl = $stmt->fetch();
            if (!$tpl || !$tpl['activo']) return null;
            
            $asunto = $tpl['asunto'];
            $contenido = $tpl['contenido'];
            
            // Add default variables
            $variables['nombre_empresa'] = $variables['nombre_empresa'] ?? 'Nexus IT';
            
            foreach ($variables as $k => $v) {
                $asunto = str_replace("{{{$k}}}", (string)($v ?? ''), $asunto);
                $contenido = str_replace("{{{$k}}}", (string)($v ?? ''), $contenido);
            }
            
            // Clean any unreplaced variables
            $contenido = preg_replace('/\{\{[a-z_]+\}\}/', '', $contenido);
            $asunto = preg_replace('/\{\{[a-z_]+\}\}/', '', $asunto);
            
            // Si la plantilla ya es un HTML completo, usarla directamente sin envolverla
            $isFullHtml = (stripos(trim($contenido), '<!DOCTYPE') !== false || stripos(trim($contenido), '<html') !== false);
            
            if ($isFullHtml) {
                $html = $contenido;
            } else {
                $html = self::template($asunto, $contenido, $actionUrl, $actionText);
            }
            
            return ['asunto' => $asunto, 'html' => $html];
        } catch (\Exception $e) {
            error_log("renderPlantilla error ($codigo): " . $e->getMessage());
            return null;
        }
    }

    /**
     * Build SLA-related variables for templates
     */
    public static function buildSLAVariables(string $prioridad): array {
        $vars = ['sla_horas' => '24', 'sla_texto' => '24 horas hábiles', 'horario_atencion' => '', 'sla_mensaje' => ''];
        try {
            $db = getDB();
            if (class_exists('SLACalculator')) {
                $horas = SLACalculator::getHorasSLA($prioridad);
                $vars['sla_horas'] = (string)$horas;
                $vars['sla_texto'] = SLACalculator::textoSLA($horas);
            }
            $conf = $db->prepare("SELECT clave, valor FROM configuracion WHERE grupo = 'sla'");
            $conf->execute();
            $rows = $conf->fetchAll(\PDO::FETCH_KEY_PAIR);
            
            $diasMap = ['1'=>'Lun','2'=>'Mar','3'=>'Mié','4'=>'Jue','5'=>'Vie','6'=>'Sáb','7'=>'Dom'];
            $diasNombres = [];
            foreach (explode(',', $rows['dias_laborales'] ?? '1,2,3,4,5') as $d) {
                $diasNombres[] = $diasMap[trim($d)] ?? $d;
            }
            $vars['horario_atencion'] = implode(', ', $diasNombres) . ' de ' . ($rows['horario_inicio'] ?? '08:00') . ' a ' . ($rows['horario_fin'] ?? '18:00');
            $vars['sla_mensaje'] = $rows['sla_mensaje'] ?? '';
        } catch (\Exception $e) {}
        return $vars;
    }

    public static function notificarNuevoTicket(array $ticket, string $email, string $nombreUsuario = ''): void {
        $prioridad = $ticket['prioridad'] ?? 'media';
        $slaVars = self::buildSLAVariables($prioridad);
        
        $variables = array_merge($slaVars, [
            'numero_ticket' => $ticket['numero_ticket'] ?? '',
            'titulo' => $ticket['titulo'] ?? '',
            'descripcion' => $ticket['descripcion'] ?? '',
            'prioridad' => ucfirst($prioridad),
            'estado' => 'Abierto',
            'nombre_usuario' => $nombreUsuario,
            'email_usuario' => $email,
            'categoria' => $ticket['categoria_nombre'] ?? '',
            'subcategoria' => $ticket['subcategoria_nombre'] ?? '',
            'fecha_creacion' => date('d/m/Y H:i'),
            'url_ticket' => "https://ana.evolucionamos.com/app/portal/ticket-detalle.html?id={$ticket['id']}",
        ]);
        
        $rendered = self::renderPlantilla('ticket_creado', $variables, $variables['url_ticket'], 'Ver Mi Ticket');
        if ($rendered) {
            self::enviar($email, $rendered['asunto'], $rendered['html']);
        } else {
            // Fallback hardcoded
            $html = self::template("Ticket Recibido: {$ticket['numero_ticket']}",
                "<p>Hola {$nombreUsuario},</p><p>Tu ticket <strong>{$ticket['numero_ticket']}</strong> — {$ticket['titulo']} ha sido creado. Prioridad: {$prioridad}. Tiempo de atención: {$slaVars['sla_texto']}.</p>",
                $variables['url_ticket'], 'Ver Mi Ticket');
            self::enviar($email, "Nexus IT - Ticket {$ticket['numero_ticket']} recibido", $html);
        }
    }

    public static function notificarCambioEstado(array $ticket, string $email, string $nuevoEstado): void {
        $url = "https://ana.evolucionamos.com/app/portal/ticket-detalle.html?id={$ticket['id']}";
        $estadoLabel = ucfirst(str_replace('_', ' ', $nuevoEstado));
        
        // Use cerrado template for resolved/closed
        $codigo = in_array($nuevoEstado, ['resuelto','cerrado']) ? 'ticket_cerrado' : 'ticket_actualizado';
        $rendered = self::renderPlantilla($codigo, [
            'numero_ticket' => $ticket['numero_ticket'] ?? '',
            'titulo' => $ticket['titulo'] ?? '',
            'estado' => $estadoLabel,
            'nombre_usuario' => $ticket['sol_nombre'] ?? '',
            'cambios_detalle' => "• Estado: {$estadoLabel}",
            'fecha_actualizacion' => date('d/m/Y H:i'),
            'fecha_cierre' => date('d/m/Y H:i'),
            'url_ticket' => $url,
        ], $url, 'Ver Ticket');
        
        if ($rendered) {
            self::enviar($email, $rendered['asunto'], $rendered['html']);
        } else {
            $html = self::template("Ticket {$ticket['numero_ticket']} - Estado Actualizado", "<p>El ticket <strong>{$ticket['titulo']}</strong> cambió de estado a: <strong>{$estadoLabel}</strong></p>", $url, "Ver Ticket");
            self::enviar($email, "Nexus IT - Ticket {$ticket['numero_ticket']} actualizado", $html);
        }
    }

    public static function notificarAsignacion(array $ticket, string $emailTecnico, string $nombreTecnico): void {
        $url = "https://ana.evolucionamos.com/app/admin/ticket-detalle.html?id={$ticket['id']}";
        $rendered = self::renderPlantilla('ticket_asignado', [
            'numero_ticket' => $ticket['numero_ticket'] ?? '',
            'titulo' => $ticket['titulo'] ?? '',
            'descripcion' => $ticket['descripcion'] ?? '',
            'prioridad' => ucfirst($ticket['prioridad'] ?? 'media'),
            'estado' => ucfirst($ticket['estado'] ?? 'abierto'),
            'nombre_tecnico' => $nombreTecnico,
            'nombre_usuario' => $ticket['sol_nombre'] ?? '',
            'url_ticket' => $url,
        ], $url, 'Ver Ticket');
        
        if ($rendered) {
            self::enviar($emailTecnico, $rendered['asunto'], $rendered['html']);
        } else {
            $html = self::template("Ticket Asignado: {$ticket['numero_ticket']}", "<p>Hola {$nombreTecnico},</p><p>Se te ha asignado el ticket <strong>{$ticket['titulo']}</strong>.</p><p><strong>Prioridad:</strong> {$ticket['prioridad']}</p>", $url, "Ver Ticket");
            self::enviar($emailTecnico, "Nexus IT - Ticket asignado {$ticket['numero_ticket']}", $html);
        }
    }

    public static function notificarComentario(array $ticket, string $email, string $autorNombre, string $comentarioTexto = '', string $nombreDestinatario = ''): void {
        $url = "https://ana.evolucionamos.com/app/portal/ticket-detalle.html?id={$ticket['id']}";
        $rendered = self::renderPlantilla('ticket_comentario', [
            'numero_ticket' => $ticket['numero_ticket'] ?? '',
            'titulo' => $ticket['titulo'] ?? '',
            'nombre_destinatario' => $nombreDestinatario,
            'nombre_autor' => $autorNombre,
            'comentario' => htmlspecialchars($comentarioTexto),
            'fecha_comentario' => date('d/m/Y H:i'),
            'url_ticket' => $url,
        ], $url, 'Ver Conversación');
        
        if ($rendered) {
            self::enviar($email, $rendered['asunto'], $rendered['html']);
        } else {
            $html = self::template("Nuevo comentario en {$ticket['numero_ticket']}", "<p><strong>{$autorNombre}</strong> ha agregado un comentario al ticket <strong>{$ticket['titulo']}</strong>.</p>", $url, "Ver Conversación");
            self::enviar($email, "Nexus IT - Comentario en {$ticket['numero_ticket']}", $html);
        }
    }
}