<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Support\Facades\Crypt;

/**
 * EmailConfiguration Model
 * 
 * Stores SMTP and IMAP credentials for email configuration.
 * Sensitive fields are automatically encrypted/decrypted using Laravel's encryption.
 * 
 * Security Features:
 * - Usernames and passwords are encrypted at rest
 * - Passwords are masked when converted to array/JSON
 * - Only one active configuration is allowed
 * 
 * @property int $id
 * @property string $smtp_host
 * @property int $smtp_port
 * @property string|null $smtp_username
 * @property string|null $smtp_password
 * @property string $smtp_encryption
 * @property string|null $imap_host
 * @property int|null $imap_port
 * @property string|null $imap_username
 * @property string|null $imap_password
 * @property string $imap_encryption
 * @property string|null $from_address
 * @property string|null $from_name
 * @property bool $is_active
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 */
class EmailConfiguration extends Model
{
    use HasFactory;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'email_configurations';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'smtp_host',
        'smtp_port',
        'smtp_username',
        'smtp_password',
        'smtp_encryption',
        'imap_host',
        'imap_port',
        'imap_username',
        'imap_password',
        'imap_encryption',
        'from_address',
        'from_name',
        'is_active',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'smtp_port' => 'integer',
        'imap_port' => 'integer',
        'is_active' => 'boolean',
        'smtp_username' => 'encrypted',
        'smtp_password' => 'encrypted',
        'imap_username' => 'encrypted',
        'imap_password' => 'encrypted',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    /**
     * The attributes that should be hidden for serialization.
     * Passwords are never exposed in API responses or logs.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'smtp_password',
        'imap_password',
    ];

    /**
     * Validation rules for email configuration.
     *
     * @var array<string, string>
     */
    public static array $validationRules = [
        'smtp_host' => 'required|string|max:191',
        'smtp_port' => 'required|integer|min:1|max:65535',
        'smtp_username' => 'nullable|string|max:191',
        'smtp_password' => 'nullable|string|max:191',
        'smtp_encryption' => 'required|in:tls,ssl,none',
        'imap_host' => 'nullable|string|max:191',
        'imap_port' => 'nullable|integer|min:1|max:65535',
        'imap_username' => 'nullable|string|max:191',
        'imap_password' => 'nullable|string|max:191',
        'imap_encryption' => 'nullable|in:tls,ssl,none',
        'from_address' => 'nullable|email|max:191',
        'from_name' => 'nullable|string|max:191',
        'is_active' => 'boolean',
    ];

    /**
     * Get the active email configuration.
     *
     * @return self|null
     */
    public static function getActive(): ?self
    {
        return static::where('is_active', true)->first();
    }

    /**
     * Check if there is an active configuration.
     *
     * @return bool
     */
    public static function hasActiveConfiguration(): bool
    {
        return static::where('is_active', true)->exists();
    }

    /**
     * Activate this configuration and deactivate others.
     *
     * @return void
     */
    public function activate(): void
    {
        // Deactivate all other configurations
        static::where('id', '!=', $this->id)->update(['is_active' => false]);

        // Activate this one
        $this->update(['is_active' => true]);
    }

    /**
     * Deactivate this configuration.
     *
     * @return void
     */
    public function deactivate(): void
    {
        $this->update(['is_active' => false]);
    }

    /**
     * Check if SMTP is configured.
     *
     * @return bool
     */
    public function hasSmtpConfigured(): bool
    {
        return !empty($this->smtp_host) && !empty($this->smtp_port);
    }

    /**
     * Check if IMAP is configured.
     *
     * @return bool
     */
    public function hasImapConfigured(): bool
    {
        return !empty($this->imap_host) && !empty($this->imap_port);
    }

    /**
     * Get masked password for display (shows only asterisks).
     *
     * @return string
     */
    public function getMaskedSmtpPasswordAttribute(): string
    {
        return $this->smtp_password ? '••••••••' : '';
    }

    /**
     * Get masked IMAP password for display.
     *
     * @return string
     */
    public function getMaskedImapPasswordAttribute(): string
    {
        return $this->imap_password ? '••••••••' : '';
    }

    /**
     * Get the SMTP connection string for display.
     *
     * @return string
     */
    public function getSmtpConnectionStringAttribute(): string
    {
        $encryption = $this->smtp_encryption !== 'none' ? " ({$this->smtp_encryption})" : '';
        return "{$this->smtp_host}:{$this->smtp_port}{$encryption}";
    }

    /**
     * Get the IMAP connection string for display.
     *
     * @return string
     */
    public function getImapConnectionStringAttribute(): string
    {
        if (!$this->hasImapConfigured()) {
            return 'Not configured';
        }
        $encryption = $this->imap_encryption !== 'none' ? " ({$this->imap_encryption})" : '';
        return "{$this->imap_host}:{$this->imap_port}{$encryption}";
    }

    /**
     * Get configuration status summary.
     *
     * @return array
     */
    public function getStatusSummary(): array
    {
        return [
            'id' => $this->id,
            'smtp' => [
                'configured' => $this->hasSmtpConfigured(),
                'host' => $this->smtp_host,
                'port' => $this->smtp_port,
                'encryption' => $this->smtp_encryption,
                'has_credentials' => !empty($this->smtp_username),
            ],
            'imap' => [
                'configured' => $this->hasImapConfigured(),
                'host' => $this->imap_host,
                'port' => $this->imap_port,
                'encryption' => $this->imap_encryption,
                'has_credentials' => !empty($this->imap_username),
            ],
            'from' => [
                'address' => $this->from_address,
                'name' => $this->from_name,
            ],
            'is_active' => $this->is_active,
            'created_at' => $this->created_at?->format('Y-m-d H:i:s'),
            'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'),
        ];
    }

    /**
     * Get the logs for this configuration.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function logs()
    {
        return $this->hasMany(EmailLog::class, 'configuration_id');
    }
}
