<?php

namespace App\Controllers;

use App\Core\Request;
use App\Core\Response;
use App\Models\Campaign;

class CampaignController extends BaseController
{
    /**
     * List all campaigns for the company
     */
    public function index(Request $request, Response $response)
    {
        $campaignModel = new Campaign();
        $campaigns = $campaignModel->findAllByCompany($request->company_id);
        
        // Count sent messages per campaign from database
        foreach ($campaigns as &$cmp) {
            $counts = \App\Core\Database::selectOne(
                "SELECT COUNT(*) as total FROM messages_log WHERE campaign_id = ? AND status = 'sent'",
                [$cmp['id']]
            );
            $cmp['sent_count'] = $counts['total'] ?? 0;
        }

        $response->json([
            'status' => 'success',
            'data' => $campaigns
        ]);
    }

    /**
     * Create a new broadcast campaign and launch it
     */
    public function store(Request $request, Response $response)
    {
        $errors = $this->validate($request, [
            'name' => 'required',
            'group_id' => 'required',
            'session_id' => 'required',
            'template_id' => 'required'
        ]);

        if (!empty($errors)) {
            $response->status(400)->json(['status' => 'error', 'errors' => $errors]);
            return;
        }

        $body = $request->getBody();
        $campaignModel = new Campaign();

        $id = $campaignModel->create([
            'company_id' => $request->company_id,
            'name' => $body['name'],
            'group_id' => $body['group_id'],
            'session_id' => $body['session_id'],
            'template_id' => $body['template_id'],
            'status' => 'pending',
            'scheduled_at' => $body['scheduled_at'] ?? null
        ]);

        // Launch campaign in background using PHP fastcgi_finish_request
        if (function_exists('fastcgi_finish_request')) {
            $response->status(201);
            $response->setHeader('Content-Type', 'application/json; charset=utf-8');
            $allowedOrigin = getenv('ALLOWED_ORIGIN') ?: '*';
            $response->setHeader('Access-Control-Allow-Origin', $allowedOrigin);
            $response->setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
            $response->setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
            $response->sendHeaders();
            http_response_code(201);
            echo json_encode([
                'status' => 'success',
                'message' => 'Campaign started in background',
                'id' => $id
            ], JSON_UNESCAPED_UNICODE);
            fastcgi_finish_request();
            
            $this->dispatchCampaign($id, $request->company_id);
            exit;
        } else {
            // Fallback for environment without PHP-FPM
            $this->dispatchCampaign($id, $request->company_id);
            $response->status(201)->json([
                'status' => 'success',
                'message' => 'Campaign completed successfully (synchronous fallback)',
                'id' => $id
            ]);
        }
    }

    /**
     * Dispatch campaign messages in sequence with rate limiting
     */
    private function dispatchCampaign(int $campaignId, int $companyId)
    {
        set_time_limit(0);
        ignore_user_abort(true);

        $campaign = \App\Core\Database::selectOne(
            "SELECT * FROM campaigns WHERE id = ? AND company_id = ? LIMIT 1",
            [$campaignId, $companyId]
        );

        if (!$campaign) return;

        // Set status to running
        \App\Core\Database::execute(
            "UPDATE campaigns SET status = 'running' WHERE id = ?",
            [$campaignId]
        );

        // Fetch template
        $template = \App\Models\Template::findByIdAndCompany($campaign['template_id'], $companyId);
        if (!$template) {
            \App\Core\Database::execute(
                "UPDATE campaigns SET status = 'failed' WHERE id = ?",
                [$campaignId]
            );
            return;
        }

        // Fetch whatsapp session
        $session = \App\Core\Database::selectOne(
            "SELECT * FROM whatsapp_sessions WHERE id = ? AND company_id = ? LIMIT 1",
            [$campaign['session_id'], $companyId]
        );
        if (!$session || $session['status'] !== 'connected') {
            \App\Core\Database::execute(
                "UPDATE campaigns SET status = 'failed' WHERE id = ?",
                [$campaignId]
            );
            return;
        }

        // Get contacts in group
        $contacts = \App\Models\ContactGroup::getRawContacts($campaign['group_id']);
        if (empty($contacts)) {
            \App\Core\Database::execute(
                "UPDATE campaigns SET status = 'completed' WHERE id = ?",
                [$campaignId]
            );
            return;
        }

        $gatewayUrl = rtrim(getenv('WHATSAPP_GATEWAY_URL') ?: 'http://localhost:3722', '/');
        if (substr($gatewayUrl, -4) === '/api') {
            $sendUrl = $gatewayUrl . '/messages/send';
        } else {
            $sendUrl = $gatewayUrl . '/api/messages/send';
        }

        foreach ($contacts as $rawContact) {
            // Decrypt contact data
            $contact = \App\Models\Contact::findByPhone($companyId, \App\Core\Security::decrypt($rawContact['phone']));
            if (!$contact) continue;

            // Replace template variables
            $messageBody = str_replace('{{name}}', $contact['name'], $template['body']);

            // Send via cURL to Node.js Gateway
            $payload = json_encode([
                'session_key' => $session['session_key'],
                'phone' => $contact['phone'],
                'message' => $messageBody,
                'media_url' => $template['media_url']
            ]);

            $ch = curl_init($sendUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'X-Webhook-Secret: ' . getenv('WEBHOOK_SECRET')
            ]);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            $status = 'failed';
            $errorMsg = null;

            if ($httpCode === 200) {
                $status = 'sent';
            } else {
                $resData = json_decode($response, true);
                $errorMsg = $resData['error'] ?? 'HTTP Code ' . $httpCode;
            }

            // Log message securely
            \App\Models\MessageLog::logMessage([
                'company_id' => $companyId,
                'session_id' => $session['id'],
                'campaign_id' => $campaignId,
                'contact_phone' => $contact['phone'],
                'direction' => 'outbound',
                'message_type' => $template['type'],
                'message_body' => $messageBody,
                'media_url' => $template['media_url'],
                'status' => $status,
                'error_message' => $errorMsg
            ]);

            // Wait 2 seconds between messages
            sleep(2);
        }

        // Set status to completed
        \App\Core\Database::execute(
            "UPDATE campaigns SET status = 'completed' WHERE id = ?",
            [$campaignId]
        );
    }
}
