<?php

namespace App\Libraries;

use App\Models\SettingModel;
use Config\Services;
use Throwable;

class WhatsAppKitDelivery
{
    private $settings;

    public function __construct()
    {
        $this->settings = new SettingModel();
    }

    public function sendLogoLaunchKit(string $phone, string $name): bool
    {
        return $this->sendDocument($phone, $name, [
            "enabled_key" => "whatsapp_delivery_enabled",
            "template_key" => "whatsapp_cloud_template_name",
            "language_key" => "whatsapp_cloud_template_language",
            "document_url_key" => "logo_launch_kit_url",
            "filename" => "BrandSquare-Logo-Launch-Kit.pdf",
            "label" => "Logo Launch Kit",
        ]);
    }

    public function sendLogoRedesignScorecard(string $phone, string $name): bool
    {
        return $this->sendDocument($phone, $name, [
            "enabled_key" => "whatsapp_redesign_delivery_enabled",
            "template_key" => "whatsapp_redesign_template_name",
            "language_key" => "whatsapp_redesign_template_language",
            "document_url_key" => "logo_redesign_scorecard_url",
            "filename" => "BrandSquare-Logo-Redesign-Scorecard.pdf",
            "label" => "Logo Redesign Scorecard",
        ]);
    }

    private function sendDocument(
        string $phone,
        string $name,
        array $document
    ): bool {
        $settings = $this->settings->values();
        if (($settings[$document["enabled_key"]] ?? "0") !== "1") {
            return false;
        }

        $phoneNumberId = trim(
            (string) ($settings["whatsapp_cloud_phone_number_id"] ?? ""),
        );
        $graphVersion = trim(
            (string) ($settings["whatsapp_cloud_graph_version"] ?? ""),
        );
        $templateName = trim(
            (string) ($settings[$document["template_key"]] ?? ""),
        );
        $templateLanguage = trim(
            (string) ($settings[$document["language_key"]] ?? ""),
        );
        $documentUrl = trim(
            (string) ($settings[$document["document_url_key"]] ?? ""),
        );
        $recipient = $this->normalizeIndianPhone($phone);
        $accessToken = $this->accessToken(
            (string) ($settings["whatsapp_cloud_access_token"] ?? ""),
        );

        if (
            $phoneNumberId === "" ||
            !preg_match("/^v[0-9]+\.[0-9]+$/", $graphVersion) ||
            $templateName === "" ||
            $templateLanguage === "" ||
            $recipient === "" ||
            $accessToken === "" ||
            !$this->isPublicHttpsUrl($documentUrl)
        ) {
            log_message(
                "warning",
                "WhatsApp {document} delivery is enabled but its configuration is incomplete.",
                ["document" => $document["label"]],
            );
            return false;
        }

        $url =
            "https://graph.facebook.com/" .
            rawurlencode($graphVersion) .
            "/" .
            rawurlencode($phoneNumberId) .
            "/messages";
        $payload = [
            "messaging_product" => "whatsapp",
            "to" => $recipient,
            "type" => "template",
            "template" => [
                "name" => $templateName,
                "language" => ["code" => $templateLanguage],
                "components" => [
                    [
                        "type" => "header",
                        "parameters" => [
                            [
                                "type" => "document",
                                "document" => [
                                    "link" => $documentUrl,
                                    "filename" => $document["filename"],
                                ],
                            ],
                        ],
                    ],
                    [
                        "type" => "body",
                        "parameters" => [
                            [
                                "type" => "text",
                                "text" =>
                                    trim($name) !== "" ? trim($name) : "there",
                            ],
                        ],
                    ],
                ],
            ],
        ];

        try {
            $response = Services::curlrequest()->post($url, [
                "headers" => [
                    "Authorization" => "Bearer " . $accessToken,
                    "Content-Type" => "application/json",
                ],
                "json" => $payload,
                "http_errors" => false,
                "timeout" => 15,
                "connect_timeout" => 8,
            ]);
            $status = $response->getStatusCode();
            $body = json_decode((string) $response->getBody(), true);
            $messageId = $body["messages"][0]["id"] ?? "";

            if ($status >= 200 && $status < 300 && $messageId !== "") {
                log_message(
                    "info",
                    "WhatsApp {document} sent successfully. Message ID: {messageId}",
                    [
                        "document" => $document["label"],
                        "messageId" => $messageId,
                    ],
                );
                return true;
            }

            $errorCode = $body["error"]["code"] ?? "unknown";
            log_message(
                "error",
                "WhatsApp {document} delivery failed. HTTP {status}; API code {errorCode}.",
                [
                    "document" => $document["label"],
                    "status" => $status,
                    "errorCode" => $errorCode,
                ],
            );
        } catch (Throwable $exception) {
            log_message(
                "error",
                "WhatsApp {document} delivery exception: {message}",
                [
                    "document" => $document["label"],
                    "message" => $exception->getMessage(),
                ],
            );
        }

        return false;
    }

    private function accessToken(string $encrypted): string
    {
        if ($encrypted === "") {
            return "";
        }

        try {
            $decoded = base64_decode($encrypted, true);
            if ($decoded === false) {
                return "";
            }

            return (string) Services::encrypter()->decrypt($decoded);
        } catch (Throwable $exception) {
            log_message(
                "error",
                "Could not decrypt the WhatsApp Cloud access token.",
            );
            return "";
        }
    }

    private function isPublicHttpsUrl(string $url): bool
    {
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            return false;
        }

        return strtolower((string) parse_url($url, PHP_URL_SCHEME)) === "https";
    }

    private function normalizeIndianPhone(string $phone): string
    {
        $digits = preg_replace("/\D/", "", $phone);
        if (strlen($digits) === 10) {
            $digits = "91" . $digits;
        } elseif (strlen($digits) === 11 && substr($digits, 0, 1) === "0") {
            $digits = "91" . substr($digits, 1);
        }

        return strlen($digits) >= 8 && strlen($digits) <= 15 ? $digits : "";
    }
}
