<?php

namespace App\Controllers;

use App\Core\Request;
use App\Core\Response;
use App\Core\Flows\ConversationFlowEngine;
use App\Services\TTSService;
use App\Models\WhatsAppSession;
use App\Models\CompanySubscription;
use App\Models\CompanySubscriptionUsage;

class OTPController extends BaseController
{
    /**
     * Generate an image with the OTP code and return its public URL.
     */
    private function generateOtpImage(string $code): string
    {
        if (function_exists('imagecreate')) {
            // Base image
            $img = imagecreatetruecolor(400, 200);
            
            // Define high-contrast, beautiful color palettes [bg, text, line]
            $palettes = [
                ['bg' => [240, 248, 255], 'text' => [15, 23, 42], 'line' => [148, 163, 184]],   // Light Blue / Dark Navy
                ['bg' => [255, 250, 240], 'text' => [67, 20, 7], 'line' => [252, 211, 77]],     // Floral White / Dark Brown
                ['bg' => [240, 253, 244], 'text' => [6, 78, 59], 'line' => [110, 231, 183]],    // Mint Green / Dark Green
                ['bg' => [254, 242, 242], 'text' => [127, 29, 29], 'line' => [252, 165, 165]],  // Light Red / Dark Red
                ['bg' => [250, 245, 255], 'text' => [88, 28, 135], 'line' => [216, 180, 254]],  // Light Purple / Dark Purple
                ['bg' => [255, 247, 237], 'text' => [154, 52, 18], 'line' => [253, 186, 116]],  // Light Orange / Dark Orange
            ];
            
            $palette = $palettes[array_rand($palettes)];
            
            $bg = imagecolorallocate($img, $palette['bg'][0], $palette['bg'][1], $palette['bg'][2]);
            $textColor = imagecolorallocate($img, $palette['text'][0], $palette['text'][1], $palette['text'][2]);
            $lineColor = imagecolorallocate($img, $palette['line'][0], $palette['line'][1], $palette['line'][2]);
            
            imagefill($img, 0, 0, $bg);
            
            // Add noise lines to make it look like a CAPTCHA and prevent automated scraping
            for ($i = 0; $i < 15; $i++) {
                imageline($img, rand(0, 400), rand(0, 200), rand(0, 400), rand(0, 200), $lineColor);
            }
            
            // Add random noise dots
            for ($i = 0; $i < 200; $i++) {
                imagesetpixel($img, rand(0, 400), rand(0, 200), $lineColor);
            }
            
            // Get or download a beautiful modern font (Roboto Bold)
            $fontDir = __DIR__ . '/../../public/fonts';
            if (!is_dir($fontDir)) {
                mkdir($fontDir, 0755, true);
            }
            $fontPath = $fontDir . '/Roboto-Bold.ttf';
            
            if (!file_exists($fontPath)) {
                $options = [
                    'http' => [
                        'method' => 'GET',
                        'header' => 'User-Agent: PHP'
                    ]
                ];
                $context = stream_context_create($options);
                $fontData = @file_get_contents('https://github.com/google/fonts/raw/main/apache/roboto/Roboto-Bold.ttf', false, $context);
                if ($fontData) {
                    file_put_contents($fontPath, $fontData);
                }
            }
            
            $spacedCode = implode('   ', str_split($code));
            
            if (file_exists($fontPath) && function_exists('imagettftext')) {
                // Calculate exact text dimensions to center it perfectly
                $fontSize = 48; // Large smooth font
                $bbox = imagettfbbox($fontSize, 0, $fontPath, $spacedCode);
                $textWidth = abs($bbox[2] - $bbox[0]);
                $textHeight = abs($bbox[1] - $bbox[7]);
                
                // If code is too long, shrink font
                if ($textWidth > 360) {
                    $fontSize = 36;
                    $bbox = imagettfbbox($fontSize, 0, $fontPath, $spacedCode);
                    $textWidth = abs($bbox[2] - $bbox[0]);
                    $textHeight = abs($bbox[1] - $bbox[7]);
                }
                
                // Center calculations
                $x = (400 - $textWidth) / 2;
                $y = ((200 - $textHeight) / 2) + $textHeight; // Y is the baseline of the text
                
                // Draw beautifully smooth true type text
                imagettftext($img, $fontSize, 0, (int)$x, (int)$y, $textColor, $fontPath, $spacedCode);
            } else {
                // Fallback for missing TTF
                $tmp = imagecreatetruecolor(200, 40);
                $tmpBg = imagecolorallocate($tmp, $palette['bg'][0], $palette['bg'][1], $palette['bg'][2]);
                $tmpText = imagecolorallocate($tmp, $palette['text'][0], $palette['text'][1], $palette['text'][2]);
                imagefill($tmp, 0, 0, $tmpBg);
                
                imagestring($tmp, 5, 5, 12, $spacedCode, $tmpText);
                
                // Scale up dynamically
                imagecopyresampled($img, $tmp, 0, 60, 0, 0, 400, 80, 200, 40);
                imagedestroy($tmp);
            }
            
            ob_start();
            imagepng($img);
            $imageData = ob_get_clean();
            
            imagedestroy($img);
            
            return base64_encode($imageData);
        } else {
            // Fallback to placehold.co if PHP GD extension is missing
            $url = "https://placehold.co/400x200/e0f2fe/0f172a/png?text=" . $code . "&font=oswald";
            $content = file_get_contents($url);
            return base64_encode($content);
        }
    }

    /**
     * Send OTP verification code via WhatsApp (Text, Voice Note, or Image)
     * POST /api/otp/send
     */
    public function send(Request $request, Response $response): void
    {
        $companyId = $request->company_id;
        $body = $request->getBody();

        $phone = $body['phone'] ?? '';
        $type = $body['type'] ?? 'text'; // 'text', 'voice', or 'image'
        $sessionId = $body['session_id'] ?? null;
        $customCode = $body['code'] ?? null;

        if (empty($phone)) {
            $response->status(400)->json(['error' => 'Missing required parameter: phone']);
            return;
        }

        // Clean phone number (remove non-digits including +)
        $phone = preg_replace('/\D/', '', $phone);

        // 1. Resolve WhatsApp Session
        $session = null;
        if ($sessionId) {
            $session = WhatsAppSession::findSecure((int)$sessionId);
            if (!$session || (int)$session['company_id'] !== (int)$companyId) {
                $response->status(404)->json(['error' => 'WhatsApp session not found']);
                return;
            }
        } else {
            // Grab the first connected session of the company
            $sessions = WhatsAppSession::findAllByCompany($companyId);
            foreach ($sessions as $s) {
                if ($s['status'] === 'connected') {
                    $session = $s;
                    break;
                }
            }
            if (!$session && !empty($sessions)) {
                $session = $sessions[0]; // fallback to first session if none is connected
            }
        }

        if (!$session) {
            $response->status(400)->json(['error' => 'No active WhatsApp sessions configured for this company.']);
            return;
        }

        if ($session['status'] !== 'connected') {
            $response->status(400)->json(['error' => 'WhatsApp session is not connected. Connect the session first.']);
            return;
        }

        // 2. Check SaaS subscription quotas
        $useElevenLabs = false;
        if ($companyId !== 1) {
            $activeSub = CompanySubscription::findActiveByCompany($companyId);
            if (!$activeSub) {
                $response->status(402)->json(['error' => 'Active subscription plan required.']);
                return;
            }

            if (!CompanySubscriptionUsage::hasRemainingLimit($companyId, 'request')) {
                $response->status(403)->json(['error' => 'Monthly request quota exceeded. Please upgrade your plan.']);
                return;
            }

            if ($type === 'voice') {
                $features = json_decode($activeSub['features'] ?: '{}', true);
                $voiceFeatureEnabled = isset($features['voice']) ? (bool)$features['voice'] : false;
                $hasVoiceLimit = CompanySubscriptionUsage::hasRemainingLimit($companyId, 'voice');
                
                if ($voiceFeatureEnabled && $hasVoiceLimit) {
                    $useElevenLabs = true;
                }
            }
        } else {
            if ($type === 'voice') {
                $useElevenLabs = true;
            }
        }

        // 3. Generate verification code
        $code = $customCode ? trim($customCode) : (string)rand(1000, 9999);

        // 4. Send Message
        try {
            $usedElevenLabs = false;
            if ($type === 'voice') {
                // Spacing the digits to force slow Arabic pronunciation: e.g. "1 2 3 4"
                $spacedCode = implode(' ', str_split($code));
                $textToRead = "رمز التحقق الخاص بك هو: {$spacedCode}. أكرر، رمز التحقق هو: {$spacedCode}.";
                
                $audioBase64 = null;
                $mimeType = 'audio/mp3';

                if ($useElevenLabs) {
                    $rule = \App\Models\ChatbotRule::findActiveForRule($companyId, $session['id']);
                    $configuredElKey = ($rule && !empty($rule['elevenlabs_api_key'])) ? $rule['elevenlabs_api_key'] : null;
                    $elApiKey = \App\Services\GeminiService::getElevenLabsApiKey($configuredElKey);
                    
                    $configuredVoiceId = ($rule && !empty($rule['elevenlabs_voice_id'])) ? $rule['elevenlabs_voice_id'] : null;
                    $elVoiceId = \App\Services\GeminiService::getElevenLabsVoiceId($configuredVoiceId);

                    if (!empty($elApiKey)) {
                        $elVoiceId = !empty($elVoiceId) ? $elVoiceId : 'pNInz6obpgDQGcFmaJgB'; // Default to Adam
                        $audioData = \App\Services\GeminiService::generateAudioResponseWithElevenLabs($elApiKey, $textToRead, $elVoiceId);
                        if ($audioData) {
                            $audioBase64 = $audioData['audio'];
                            $mimeType = $audioData['mimeType'];
                            $usedElevenLabs = true;
                        }
                    }
                }

                if (!$audioBase64) {
                    // Fallback to Google Translate TTS
                    $audioBase64 = TTSService::textToSpeechArabic($textToRead);
                    $mimeType = 'audio/mp3';
                    $usedElevenLabs = false;
                }

                if (!$audioBase64) {
                    $response->status(500)->json(['error' => 'Failed to generate voice OTP audio.']);
                    return;
                }

                // Send voice note
                $success = ConversationFlowEngine::sendReply($session, $phone, '', null, $audioBase64, $mimeType);
                if (!$success) {
                    $response->status(500)->json(['error' => 'Failed to send voice OTP via gateway.']);
                    return;
                }
            } else if ($type === 'image') {
                // Generate OTP Image as Base64
                $imageBase64 = $this->generateOtpImage($code);
                $success = ConversationFlowEngine::sendReply($session, $phone, '', null, null, null, $imageBase64);
                if (!$success) {
                    $response->status(500)->json(['error' => 'Failed to send image OTP via gateway.']);
                    return;
                }
            } else {
                // Send text
                $customText = $body['message'] ?? null;
                if ($customText) {
                    $textMsg = str_replace('{code}', $code, $customText);
                } else {
                    $textMsg = "رمز التحقق الخاص بك لمتجر نابه هو: *{$code}* \n الرجاء عدم مشاركته مع أي شخص.";
                }
                $success = ConversationFlowEngine::sendReply($session, $phone, $textMsg);
                if (!$success) {
                    $response->status(500)->json(['error' => 'Failed to send text OTP via gateway.']);
                    return;
                }
            }

            // Increment usage stats
            if ($companyId !== 1) {
                CompanySubscriptionUsage::incrementUsage($companyId, 'request');
                if ($type === 'voice' && $usedElevenLabs) {
                    CompanySubscriptionUsage::incrementUsage($companyId, 'voice');
                }
            }

            $response->json([
                'status' => 'success',
                'message' => 'OTP sent successfully',
                'code' => $code,
                'type' => $type
            ]);

        } catch (\Exception $e) {
            error_log("[OTP Controller Error] " . $e->getMessage());
            $response->status(500)->json(['error' => 'Failed to send OTP message: ' . $e->getMessage()]);
        }
    }
}
