<?php

namespace App\Libraries;

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

class LeadMailer
{
    private $settings;
    private $templates;

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

    public function sendLead(array $lead): bool
    {
        $settings = $this->settings->values();
        if (($settings["smtp_enabled"] ?? "0") !== "1") {
            return false;
        }

        $rendered = $this->templates->render(
            "lead_notification",
            $this->leadVariables($lead, $settings),
        );
        if (!$rendered || !$rendered["template"]["enabled"]) {
            return false;
        }

        return $this->send(
            $settings,
            $settings["notification_email"] ?? "",
            $rendered["subject"],
            $rendered["html"],
        );
    }

    public function sendCustomerConfirmation(array $lead): bool
    {
        $settings = $this->settings->values();
        if (($settings["smtp_enabled"] ?? "0") !== "1") {
            return false;
        }

        $key =
            ($lead["source"] ?? "") === "navigation enquiry"
                ? "enquiry_submitted"
                : "logo_brief_submitted";
        $rendered = $this->templates->render(
            $key,
            $this->leadVariables($lead, $settings),
        );
        if (!$rendered || !$rendered["template"]["enabled"]) {
            return false;
        }

        return $this->send(
            $settings,
            $lead["email"] ?? "",
            $rendered["subject"],
            $rendered["html"],
        );
    }

    public function sendQuotation(
        string $to,
        array $variables,
        string $attachmentPath
    ): bool {
        return $this->sendDocumentTemplate(
            "quotation_attached",
            $to,
            $variables,
            $attachmentPath,
        );
    }

    public function sendQuotationEmail(string $to, array $variables): bool
    {
        $settings = $this->settings->values();
        if (($settings["smtp_enabled"] ?? "0") !== "1") {
            return false;
        }

        $variables["from_email"] = $settings["smtp_from_email"] ?? "";
        $rendered = $this->templates->render("quotation_email", $variables);
        if (!$rendered || !$rendered["template"]["enabled"]) {
            return false;
        }

        return $this->send(
            $settings,
            $to,
            $rendered["subject"],
            $rendered["html"],
        );
    }

    public function sendInvoice(
        string $to,
        array $variables,
        string $attachmentPath
    ): bool {
        return $this->sendDocumentTemplate(
            "invoice_attached",
            $to,
            $variables,
            $attachmentPath,
        );
    }

    public function sendInvoiceEmail(string $to, array $variables): bool
    {
        $settings = $this->settings->values();
        if (($settings["smtp_enabled"] ?? "0") !== "1") {
            return false;
        }

        $variables["from_email"] = $settings["smtp_from_email"] ?? "";
        $rendered = $this->templates->render("invoice_email", $variables);
        if (!$rendered || !$rendered["template"]["enabled"]) {
            return false;
        }

        return $this->send(
            $settings,
            $to,
            $rendered["subject"],
            $rendered["html"],
        );
    }

    public function sendTest(array $settings): bool
    {
        return $this->send(
            $settings,
            $settings["notification_email"] ?? "",
            "BrandSquare SMTP test",
            "<h2>Your SMTP settings are working.</h2><p>This test email was sent from the BrandSquare admin panel.</p>",
        );
    }

    private function send(
        array $settings,
        string $to,
        string $subject,
        string $message,
        array $attachments = []
    ): bool {
        if (
            !$to ||
            empty($settings["smtp_host"]) ||
            empty($settings["smtp_from_email"])
        ) {
            return false;
        }

        try {
            $password = $this->decrypt($settings["smtp_password"] ?? "");
            $crypto = $settings["smtp_crypto"] ?? "tls";
            $config = [
                "protocol" => "smtp",
                "SMTPHost" => $settings["smtp_host"],
                "SMTPUser" => $settings["smtp_username"] ?? "",
                "SMTPPass" => $password,
                "SMTPPort" => (int) ($settings["smtp_port"] ?? 587),
                "SMTPTimeout" => 10,
                "SMTPCrypto" => $crypto === "none" ? "" : $crypto,
                "mailType" => "html",
                "charset" => "UTF-8",
                "CRLF" => "\r\n",
                "newline" => "\r\n",
            ];

            $email = Services::email($config, false);
            $email->setFrom(
                $settings["smtp_from_email"],
                $settings["smtp_from_name"] ?? "BrandSquare",
            );
            $email->setTo($to);
            $email->setSubject($subject);
            $email->setMessage($message);
            foreach ($attachments as $attachment) {
                $path = is_array($attachment)
                    ? $attachment["path"] ?? ""
                    : $attachment;
                if (is_file($path)) {
                    if (is_array($attachment)) {
                        $email->attach(
                            $path,
                            "attachment",
                            $attachment["name"] ?? basename($path),
                            $attachment["mime"] ?? "application/pdf",
                        );
                    } else {
                        $email->attach($path);
                    }
                }
            }

            return $email->send();
        } catch (Throwable $exception) {
            log_message("error", "Email delivery failed: {message}", [
                "message" => $exception->getMessage(),
            ]);
            return false;
        }
    }

    private function sendDocumentTemplate(
        string $key,
        string $to,
        array $variables,
        string $attachmentPath
    ): bool {
        $settings = $this->settings->values();
        if (
            ($settings["smtp_enabled"] ?? "0") !== "1" ||
            !is_file($attachmentPath)
        ) {
            return false;
        }

        $variables["attachment_name"] =
            $variables["attachment_name"] ?? basename($attachmentPath);
        $variables["from_email"] = $settings["smtp_from_email"] ?? "";
        $rendered = $this->templates->render($key, $variables);
        if (!$rendered || !$rendered["template"]["enabled"]) {
            return false;
        }

        return $this->send(
            $settings,
            $to,
            $rendered["subject"],
            $rendered["html"],
            [
                [
                    "path" => $attachmentPath,
                    "name" => $variables["attachment_name"],
                    "mime" => "application/pdf",
                ],
            ],
        );
    }

    private function leadVariables(array $lead, array $settings): array
    {
        return array_merge($lead, [
            "site_url" => base_url(),
            "admin_leads_url" => base_url("admin/leads"),
            "from_email" => $settings["smtp_from_email"] ?? "",
        ]);
    }

    private function decrypt(string $value): string
    {
        if ($value === "") {
            return "";
        }

        try {
            return Services::encrypter()->decrypt(base64_decode($value, true));
        } catch (Throwable $exception) {
            log_message("error", "Could not decrypt SMTP password.");
            return "";
        }
    }
}
