<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Crypt;

class SenderAccount extends Model
{
    protected $table = 'sender_accounts';

    protected $fillable = [
        'email_address',
        'email_name',
        'smtp_host',
        'smtp_port',
        'smtp_encryption',
        'smtp_username',
        'smtp_password',
        'reply_to',
        'verify_email',
        'note',
        'is_active',
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'smtp_port' => 'integer',
    ];

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function getDecryptedPassword(): string
    {
        if (empty($this->smtp_password)) {
            return '';
        }

        try {
            return Crypt::decryptString($this->smtp_password);
        } catch (\Exception $e) {
            return $this->smtp_password;
        }
    }

    public function sanitizeName(): string
    {
        $name = $this->email_name ?? '';

        if (filter_var($name, FILTER_VALIDATE_EMAIL)) {
            return 'Glastree';
        }

        $name = preg_replace('/[^\p{L}\p{N}\s]/u', '', $name);
        $name = trim($name);

        return empty($name) ? 'Glastree' : $name;
    }

    public function getReplyTo(): ?string
    {
        if ($this->reply_to) {
            return $this->reply_to;
        }

        if ($this->verify_email) {
            return $this->verify_email;
        }

        return null;
    }

    public function buildDsn(): string
    {
        $password = $this->getDecryptedPassword();
        $username = $this->smtp_username ?? $this->email_address;
        $encryption = $this->smtp_encryption ?? 'tls';
        $scheme = ($encryption === 'ssl') ? 'smtps' : 'smtp';

        return sprintf(
            '%s://%s:%s@%s:%d?encryption=%s',
            $scheme,
            rawurlencode($username),
            rawurlencode($password),
            $this->smtp_host ?? 'smtp.gmail.com',
            $this->smtp_port ?? 587,
            $encryption
        );
    }

    public function buildSymfonyEmail(string $to, string $subject, string $body): \Symfony\Component\Mime\Email
    {
        $fromName = $this->sanitizeName();
        $fromAddress = \Symfony\Component\Mime\Address::create($this->email_address, $fromName);

        $email = (new \Symfony\Component\Mime\Email())
            ->from($fromAddress)
            ->to($to)
            ->subject($subject)
            ->text($body);

        $replyTo = $this->getReplyTo();
        if ($replyTo) {
            $email->replyTo($replyTo);
        }

        return $email;
    }

    public function sendEmail(string $to, string $subject, string $body, array $attachmentPaths = []): void
    {
        $email = $this->buildSymfonyEmail($to, $subject, $body);

        foreach ($attachmentPaths as $path) {
            $email->attachFromPath($path);
        }

        $transport = \Symfony\Component\Mailer\Transport::fromDsn($this->buildDsn());
        $mailer = new \Symfony\Component\Mailer\Mailer($transport);
        $mailer->send($email);
    }

    public function sendReport(string $subject, string $body): bool
    {
        if (empty($this->verify_email)) {
            return false;
        }

        try {
            $this->sendEmail($this->verify_email, $subject, $body);
            return true;
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Sender report email failed', [
                'sender' => $this->email_address,
                'error' => $e->getMessage(),
            ]);
            return false;
        }
    }
}
