<?php
class MessageService {
    private $conn;

    public function __construct($db) {
        $this->conn = $db;
    }

    public function generateBirthdayPdf($userTemplatePath, $contactName, $outputPath, $options = []) {
        // Ensure directory exists
        $dir = dirname($outputPath);
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }

        // 1. Create Image with Name
        $ext = strtolower(pathinfo($userTemplatePath, PATHINFO_EXTENSION));
        if ($ext == 'png') {
            $im = @imagecreatefrompng($userTemplatePath);
        } else {
            $im = @imagecreatefromjpeg($userTemplatePath);
        }

        if (!$im) return false;

        $posX = $options['pos_x'] ?? 50; // Percentage
        $posY = $options['pos_y'] ?? 90; // Percentage
        $fontSize = $options['font_size'] ?? 20; // In Points for TTF, or 1-5 for GD
        $hexColor = $options['font_color'] ?? '#000000';

        // Parse Hex Color
        list($r, $g, $b) = sscanf($hexColor, "#%02x%02x%02x");
        $textColor = imagecolorallocate($im, $r, $g, $b);

        $text = $contactName;
        $imgWidth = imagesx($im);
        $imgHeight = imagesy($im);

        // Check for Fonts (Prioritize Hindi font for Devanagari names, fallback to Arial)
        $hindiFontPath = __DIR__ . '/../assets/fonts/NotoHindi.ttf';
        $arialFontPath = __DIR__ . '/../assets/fonts/arialbd.ttf';
        
        $fontPath = file_exists($hindiFontPath) ? $hindiFontPath : $arialFontPath;
        $useTTF = file_exists($fontPath);

        if ($useTTF) {
            // Calculate Box
            $bbox = imagettfbbox($fontSize, 0, $fontPath, $text);
            $textWidth = abs($bbox[4] - $bbox[0]);
            $textHeight = abs($bbox[5] - $bbox[1]);

            // Calculate Position
            // pos_x is percentage of center of text? Or Start?
            // Usually centering is preferred if pos_x=50.
            // Let's assume pos_x is the CENTER point of the text in % of image width
            $centerX = ($imgWidth * $posX) / 100;
            $x = $centerX - ($textWidth / 2);

            // pos_y is percentage of baseline?
            // Let's assume pos_y is percentage from top
            $y = ($imgHeight * $posY) / 100;

            imagettftext($im, $fontSize, 0, $x, $y, $textColor, $fontPath, $text);
        } else {
            // Fallback to GD
            // Font 5 is approx 15px width
            $font = 5;
            $fontWidth = imagefontwidth($font);
            $textWidth = $fontWidth * strlen($text);

            $centerX = ($imgWidth * $posX) / 100;
            $x = $centerX - ($textWidth / 2);
            $y = ($imgHeight * $posY) / 100;

            imagestring($im, $font, $x, $y, $text, $textColor);
            // Simulate Bold
            imagestring($im, $font, $x+1, $y, $text, $textColor);
        }

        $tempImgPath = str_replace('.pdf', '.jpg', $outputPath);
        imagejpeg($im, $tempImgPath, 90);
        imagedestroy($im);

        // 2. Wrap in PDF
        // Since FPDF might not be installed, using a simple fallback if not present?
        // I'll try to include a minimal PDF wrapper or just use the Image->PDF trick if FPDF is absent.
        // Assuming FPDF is available in libs/fpdf.php as per plan, but I didn't validly install it.
        // I will write a dummy PDF with the image embedded IF I can.
        // FOR NOW: I will just renaming the JPG to PDF is dirty.
        // I will create a VALID minimal PDF implementation here for just one image A4.

        $this->imageToPdf($tempImgPath, $outputPath);

        if(file_exists($tempImgPath)) unlink($tempImgPath);

        $exists = file_exists($outputPath);
        
        // Give the live server (cPanel/Cloudflare/Nginx) 2 seconds to flush the file to disk 
        // and make it publicly accessible before the WhatsApp API instantly tries to fetch it!
        if ($exists) {
            sleep(2); 
        }
        
        return $exists;
    }

    // Minimal Image to PDF converter (Native PHP, no big library)
    private function imageToPdf($img, $pdf) {
        // Get dimensions
        list($w, $h) = getimagesize($img);

        // A4 size in points (1 pt = 1/72 inch)
        // A4 = 595.28 x 841.89 points
        // We will just create a PDF with the image's dimensions to fit perfectly
        $pdfW = $w * 0.75; // px to pt approx
        $pdfH = $h * 0.75;

        // We'll trust the user to upload suitable size or we scale.
        // For simplicity, let's just make a PDF that wraps the JPEG stream.

        $content = file_get_contents($img);
        $stream = $content;
        $len = strlen($stream);

        // PDF Header
        $out = "%PDF-1.3\n";
        $out .= "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n";
        $out .= "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n";
        $out .= "3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 $pdfW $pdfH] /Contents 4 0 R /Resources << /XObject << /Im1 5 0 R >> >> >>\nendobj\n";
        $out .= "4 0 obj\n<< /Length 22 >>\nstream\nq $pdfW 0 0 $pdfH 0 0 cm /Im1 Do Q\nendstream\nendobj\n";
        $out .= "5 0 obj\n<< /Type /XObject /Subtype /Image /Width $w /Height $h /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length $len >>\nstream\n";
        $out .= $stream . "\nendstream\nendobj\n";

        $xref = "xref\n0 6\n0000000000 65535 f \n";
        $xref .= "0000000009 00000 n \n"; // 1
        $xref .= "0000000060 00000 n \n"; // 2
        $xref .= "0000000117 00000 n \n"; // 3
        $xref .= "0000000257 00000 n \n"; // 4
        $xref .= "0000000329 00000 n \n"; // 5

        $out .= $xref;
        $out .= "trailer\n<< /Size 6 /Root 1 0 R >>\nstartxref\n" . strlen($out) . "\n%%EOF";

        // Note: The offsets in xref need to be exact. The above is an approximation which might break.
        // Proper way: calculate offsets.
        // Given complexity, I will use a simplified approach:
        // Use a library-less PDF class or just a library if I could.
        // I will compute offsets dynamically.

        $objects = [];
        $objects[1] = "<< /Type /Catalog /Pages 2 0 R >>";
        $objects[2] = "<< /Type /Pages /Kids [3 0 R] /Count 1 >>";
        $objects[3] = "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 $pdfW $pdfH] /Contents 4 0 R /Resources << /XObject << /Im1 5 0 R >> >> >>";
        $objects[4] = "<< /Length 22 >>\nstream\nq $pdfW 0 0 $pdfH 0 0 cm /Im1 Do Q\nendstream";
        $objects[5] = "<< /Type /XObject /Subtype /Image /Width $w /Height $h /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length $len >>\nstream\n" . $stream . "\nendstream";

        $out = "%PDF-1.3\n";
        $offsets = [];

        foreach($objects as $id => $obj) {
            $offsets[$id] = strlen($out);
            $out .= "$id 0 obj\n$obj\nendobj\n";
        }

        $xrefStart = strlen($out);
        $out .= "xref\n0 " . (count($objects) + 1) . "\n0000000000 65535 f \n";
        foreach($offsets as $offset) {
            $out .= sprintf("%010d 00000 n \n", $offset);
        }

        $out .= "trailer\n<< /Size " . (count($objects) + 1) . " /Root 1 0 R >>\nstartxref\n$xrefStart\n%%EOF";

        file_put_contents($pdf, $out);
    }

    public function sendWhatsApp($apiData, $mobile, $pdfPath) {
        // Config: wa_url, wa_apikey
        // Target: wa_url (POST)
        // Payload: apikey, mobile, pdf, msg

        // Use the live server URL for the PDF path explicitly with HTTP
        $pdfUrl = "http://demo.atomsgroup.in/birthday_msg/" . $pdfPath;

        // Prepare Message
        $msg = $apiData['message'];

        // Ensure all parameters are built in the query string exactly as expected by Msg24
        // To prevent URI truncation limits caused by massively long URL-encoded Hindi text, 
        // we MUST place the 'msg' parameter at the absolute end of the query string!
        
        // Clean the WA URL to prevent issues if the user manually typed `?&pdf` or other query strings in their database configuration
        $waUrlRaw = $apiData['wa_url'];
        if (($pos = strpos($waUrlRaw, '?')) !== false) {
            $waUrlRaw = substr($waUrlRaw, 0, $pos);
        }
        
        $waUrl = $waUrlRaw . '?';
        $waUrl .= 'apikey=' . urlencode($apiData['wa_apikey']);
        $waUrl .= '&mobile=' . urlencode($mobile);
        $waUrl .= '&pdf=' . trim($pdfUrl); // DO NOT URL-ENCODE THIS - API requires plain text!
        $waUrl .= '&msg=' . urlencode($msg); // Keep massive strings at the end!

        // Sending as pure GET request
        return $this->curlRequest($waUrl, 'GET');
    }

    public function sendSMS($apiData, $mobile, $message) {
        // Keep SMS as GET for now unless we know otherwise, but updated curlRequest supports it.

        $params = [
            'user' => $apiData['sms_user'],
            'password' => $apiData['sms_password'],
            'senderid' => $apiData['sms_sender_id'],
            'channel' => 'Trans',
            'DCS' => '8',
            'flashsms' => '0',
            'number' => $mobile,
            'text' => $message,
            'route' => '08'
        ];

        // SMS usually uses GET
        $url = $apiData['sms_url'] . '?' . http_build_query($params);
        return $this->curlRequest($url, 'GET');
    }

    private function curlRequest($url, $method = 'GET', $data = []) {
        $ch = curl_init();

        if (strtoupper($method) === 'POST') {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
        }

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disabled for local dev/testing simplicity

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

        // Logging
        $logDir = __DIR__ . '/../logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0777, true);
        }

        $logEntry = "[" . date('Y-m-d H:i:s') . "] [$method] $url - Code: $httpCode\n";
        if (!empty($data)) {
            // Hide sensitive data like password/apikey in logs? For debugging we keep it, but be careful.
            $logEntry .= "Params: " . json_encode($data) . "\n";
        }
        if ($error) {
            $logEntry .= "Error: $error\n";
        }
        $logEntry .= "Response: " . substr($response, 0, 500) . "\n-------------------------\n";

        file_put_contents($logDir . '/api_requests.log', $logEntry, FILE_APPEND);

        if ($error) {
            return ['status' => 'failed', 'response' => $error];
        } else {
            return ['status' => 'success', 'http_code' => $httpCode, 'response' => $response];
        }
    }
}
?>
