<?php

namespace App\Controllers;

use App\Core\Request;
use App\Core\Response;
use App\Core\Security;
use App\Models\SallaMerchant;
use App\Models\WhatsAppSession;

class SallaController extends BaseController
{
    /**
     * Redirect user to Salla OAuth login page.
     * Accessible via GET /api/integrations/salla/auth?token=JWT_TOKEN
     */
    public function auth(Request $request, Response $response)
    {
        $token = $_GET['token'] ?? '';
        if (empty($token)) {
            $response->status(400)->html("<h3>Error: Token is required</h3>");
            return;
        }

        $payload = Security::verifyJWT($token);
        if (!$payload) {
            $response->status(401)->html("<h3>Error: Invalid token</h3>");
            return;
        }

        $companyId = $payload['company_id'];
        $clientId = getenv('SALLA_CLIENT_ID') ?: '69ea789c-f611-4ea7-a3ee-7ead41420225';
        $redirectUri = getenv('APP_URL') . '/api/integrations/salla/callback';

        // Build state: company_id + random token (min 8 chars required by Salla)
        $randomToken = bin2hex(random_bytes(8)); // 16-char hex
        $state = $companyId . '_' . $randomToken;

        $authUrl = "https://accounts.salla.sa/oauth2/auth?" . http_build_query([
            'client_id' => $clientId,
            'redirect_uri' => $redirectUri,
            'response_type' => 'code',
            'state' => $state
        ]);

        header("Location: " . $authUrl);
        exit;
    }

    /**
     * Handle Salla OAuth callback.
     * Accessible via GET /api/integrations/salla/callback?code=CODE&state=COMPANY_ID
     */
    public function callback(Request $request, Response $response)
    {
        // Handle Salla returning an error redirect (e.g. invalid_scope, access_denied)
        if (!empty($_GET['error'])) {
            $errorCode = $_GET['error'] ?? 'unknown_error';
            $errorDesc = $_GET['error_description'] ?? 'An unknown error occurred during Salla authorization.';
            error_log("[Salla OAuth Error] $errorCode: $errorDesc");
            $appUrl = rtrim(getenv('APP_URL') ?: 'https://nabeh.intaleqapp.com', '/');
            header("Location: {$appUrl}/?salla_connect=error&reason=" . urlencode($errorDesc));
            exit;
        }

        $code = $_GET['code'] ?? '';
        $rawState = $_GET['state'] ?? '';

        // Extract company_id from state (format: "companyId_randomToken")
        $stateParts = explode('_', $rawState, 2);
        $companyId = $stateParts[0] ?? '';

        if (empty($code) || empty($companyId)) {
            $response->status(400)->html("<h3>Error: Missing authorization code or state (company_id).</h3>");
            return;
        }

        $clientId = getenv('SALLA_CLIENT_ID') ?: '69ea789c-f611-4ea7-a3ee-7ead41420225';
        $clientSecret = getenv('SALLA_CLIENT_SECRET') ?: '';
        $redirectUri = getenv('APP_URL') . '/api/integrations/salla/callback';

        // 1. Swap authorization code for token
        $ch = curl_init('https://accounts.salla.sa/oauth2/token');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'grant_type' => 'authorization_code',
            'code' => $code,
            'redirect_uri' => $redirectUri
        ]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded'
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);
        
        $res = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            error_log("Salla Token Error: HTTP $httpCode - Response: $res");
            $response->status(500)->html("<h3>Failed to exchange code for Salla token. Status code: $httpCode</h3>");
            return;
        }

        $tokenData = json_decode($res, true);
        if (empty($tokenData['access_token'])) {
            $response->status(500)->html("<h3>Failed to parse Salla token response.</h3>");
            return;
        }

        $accessToken = $tokenData['access_token'];
        $refreshToken = $tokenData['refresh_token'];
        $expiresIn = $tokenData['expires_in'] ?? 2592000;
        $expiresAt = date('Y-m-d H:i:s', time() + $expiresIn);

        // 2. Fetch merchant/user info
        $chInfo = curl_init('https://accounts.salla.sa/oauth2/user/info');
        curl_setopt($chInfo, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($chInfo, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $accessToken
        ]);
        curl_setopt($chInfo, CURLOPT_TIMEOUT, 10);
        
        $resInfo = curl_exec($chInfo);
        $infoHttpCode = curl_getinfo($chInfo, CURLINFO_HTTP_CODE);
        curl_close($chInfo);

        $storeName = 'Salla Store';
        $merchantId = '';
        if ($infoHttpCode === 200) {
            $infoData = json_decode($resInfo, true);
            $merchantId = $infoData['merchant']['id'] ?? $infoData['id'] ?? '';
            $storeName = $infoData['merchant']['name'] ?? 'Salla Store';
        }

        if (empty($merchantId)) {
            error_log("Salla Info Fetch Error: HTTP $infoHttpCode - Response: $resInfo");
            $response->status(500)->html("<h3>Failed to fetch merchant profile from Salla.</h3>");
            return;
        }

        // 3. Save or update Salla merchant settings in DB
        SallaMerchant::saveSecure([
            'company_id' => (int)$companyId,
            'merchant_id' => (string)$merchantId,
            'store_name' => $storeName,
            'access_token' => $accessToken,
            'refresh_token' => $refreshToken,
            'expires_at' => $expiresAt
        ]);

        // Redirect back to frontend
        header("Location: " . getenv('APP_URL') . "/?salla_connect=success");
        exit;
    }

    /**
     * Get Salla connection status for current company.
     * Protected by AuthMiddleware.
     * Accessible via GET /api/integrations/salla/status
     */
    public function status(Request $request, Response $response)
    {
        $merchant = SallaMerchant::findByCompany($request->company_id);
        if ($merchant) {
            $response->json([
                'status' => 'success',
                'connected' => true,
                'store_name' => $merchant['store_name'],
                'merchant_id' => $merchant['merchant_id'],
                'expires_at' => $merchant['expires_at']
            ]);
        } else {
            $response->json([
                'status' => 'success',
                'connected' => false
            ]);
        }
    }

    /**
     * Disconnect Salla integration.
     * Protected by AuthMiddleware.
     * Accessible via POST /api/integrations/salla/disconnect
     */
    public function disconnect(Request $request, Response $response)
    {
        SallaMerchant::deleteByCompany($request->company_id);
        $response->json([
            'status' => 'success',
            'message' => 'Salla integration disconnected successfully'
        ]);
    }

    /**
     * Handle incoming Webhook from Salla.
     * Accessible via POST /api/webhooks/salla
     */
    public function webhook(Request $request, Response $response)
    {
        // 1. Get raw input and signature
        $rawPayload = file_get_contents('php://input');
        $signature = $request->getHeader('x-salla-signature') ?: '';

        // 2. Verify signature
        $secret = getenv('SALLA_WEBHOOK_SECRET') ?: '406550c38b782a50e9a3e0687f564107f8a60135b072b1f819470dda5333a65d';
        $calculated = hash_hmac('sha256', $rawPayload, $secret);

        if (!hash_equals($calculated, $signature)) {
            error_log("[Salla Webhook Error] Invalid signature. Received: $signature, Calculated: $calculated");
            $response->status(401)->json(['error' => 'Invalid signature']);
            return;
        }

        // 3. Parse JSON payload
        $payload = json_decode($rawPayload, true);
        if (!$payload) {
            $response->status(400)->json(['error' => 'Invalid JSON']);
            return;
        }

        $event = $payload['event'] ?? '';
        $merchantId = $payload['merchant'] ?? '';

        if (empty($event) || empty($merchantId)) {
            $response->status(400)->json(['error' => 'Missing event or merchant information']);
            return;
        }

        // 4. Find the merchant config to get company_id
        $merchant = SallaMerchant::findByMerchantId((string)$merchantId);
        if (!$merchant) {
            error_log("[Salla Webhook Warning] Webhook received for unlinked merchant ID: " . $merchantId);
            $response->status(404)->json(['error' => 'Store is not linked to any company in Nabeh']);
            return;
        }

        $companyId = (int)$merchant['company_id'];
        $orderData = $payload['data'] ?? [];

        // 5. Process events
        if ($event === 'order.created' || $event === 'order.status.updated') {
            $this->handleOrderWebhook($companyId, $event, $orderData);
        }

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

    /**
     * Process order webhook events and send automated WhatsApp message
     */
    private function handleOrderWebhook(int $companyId, string $event, array $orderData)
    {
        $orderId = $orderData['id'] ?? $orderData['reference_id'] ?? '';
        $customerName = $orderData['customer']['name'] ?? 'عميلنا العزيز';
        $customerPhone = $orderData['customer']['mobile'] ?? $orderData['customer']['phone'] ?? '';
        $statusName = $orderData['status']['name'] ?? '';

        if (empty($customerPhone) || empty($orderId)) {
            return;
        }

        // Format phone: remove leading zero or +, ensure only digits
        $customerPhone = preg_replace('/\D/', '', $customerPhone);
        if (substr($customerPhone, 0, 2) === '00') {
            $customerPhone = substr($customerPhone, 2);
        }
        // Normalize Saudi numbers starting with 05
        if (strlen($customerPhone) === 9 && $customerPhone[0] === '5') {
            $customerPhone = '966' . $customerPhone;
        } elseif (strlen($customerPhone) === 10 && substr($customerPhone, 0, 2) === '05') {
            $customerPhone = '966' . substr($customerPhone, 1);
        }

        // Construct message based on event
        $message = '';
        if ($event === 'order.created') {
            $message = "مرحباً {$customerName}،\nتم استلام طلبك رقم ({$orderId}) بنجاح! شكرًا لتسوقك معنا. سنقوم بتحديثك فور تغيير حالة الطلب.";
        } elseif ($event === 'order.status.updated') {
            $message = "مرحباً {$customerName}،\nتم تحديث حالة طلبك رقم ({$orderId}) إلى: *{$statusName}*.";
            
            // Check for shipping details
            $courier = $orderData['shipment']['courier_name'] ?? '';
            $tracking = $orderData['shipment']['tracking_link'] ?? '';
            if (!empty($courier) && !empty($tracking)) {
                $message .= "\n🚚 الشحن عبر: {$courier}\nرابط التتبع: {$tracking}";
            }
        }

        if (empty($message)) {
            return;
        }

        // Send WhatsApp Message via active session
        $session = WhatsAppSession::findByCompany($companyId);
        if (!$session || $session['status'] !== 'connected') {
            error_log("[Salla Webhook Warning] Cannot send auto-notification: No active connected WhatsApp session for company: " . $companyId);
            return;
        }

        $this->sendWhatsAppNotification($session['session_key'], $customerPhone, $message);
    }

    /**
     * Send a WhatsApp message through the gateway
     */
    private function sendWhatsAppNotification(string $sessionKey, string $phone, string $message)
    {
        $gatewayUrl = rtrim(getenv('WHATSAPP_GATEWAY_URL') ?: 'http://localhost:3722', '/');
        if (substr($gatewayUrl, -4) === '/api') {
            $sendUrl = $gatewayUrl . '/messages/send';
        } else {
            $sendUrl = $gatewayUrl . '/api/messages/send';
        }

        $payload = json_encode([
            'session_key' => $sessionKey,
            'phone' => $phone,
            'message' => $message
        ]);

        $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);

        if ($httpCode !== 200) {
            error_log("[Salla Webhook Gateway Error] Failed to send WhatsApp notification. Gateway response: " . $response);
        }
    }
}
