<?php

namespace App\Services;

use App\Models\EmailConfiguration;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

/**
 * EmailConfigurationService
 *
 * Manages CRUD operations for email credentials with caching support.
 */
class EmailConfigurationService
{
    protected const CACHE_KEY = 'email_configuration_active';
    protected const CACHE_TTL = 3600;

    public function getConfiguration(): ?EmailConfiguration
    {
        return Cache::remember(
            self::CACHE_KEY,
            self::CACHE_TTL,
            fn () => EmailConfiguration::getActive()
        );
    }

    public function isConfigured(): bool
    {
        return Cache::remember(
            self::CACHE_KEY . '_exists',
            self::CACHE_TTL,
            fn () => EmailConfiguration::hasActiveConfiguration()
        );
    }

    public function saveConfiguration(array $data): EmailConfiguration
    {
        return \DB::transaction(function () use ($data) {
            EmailConfiguration::query()->update(['is_active' => false]);

            $configuration = EmailConfiguration::create(array_merge($data, ['is_active' => true]));

            $this->clearCache();

            Log::info('Email configuration saved', [
                'id'               => $configuration->id,
                'smtp_host'        => $configuration->smtp_host,
                'imap_configured'  => $configuration->hasImapConfigured(),
            ]);

            return $configuration;
        });
    }

    public function updateConfiguration(EmailConfiguration $configuration, array $data): EmailConfiguration
    {
        $configuration->update($data);

        $this->clearCache();

        Log::info('Email configuration updated', [
            'id'        => $configuration->id,
            'smtp_host' => $configuration->smtp_host,
        ]);

        return $configuration->fresh();
    }

    public function deleteConfiguration(EmailConfiguration $configuration): bool
    {
        $deleted = $configuration->delete();

        $this->clearCache();

        Log::info('Email configuration deleted', ['id' => $configuration->id]);

        return $deleted;
    }

    public function activateConfiguration(EmailConfiguration $configuration): void
    {
        $configuration->activate();

        $this->clearCache();

        Log::info('Email configuration activated', ['id' => $configuration->id]);
    }

    public function deactivateAll(): void
    {
        EmailConfiguration::query()->update(['is_active' => false]);

        $this->clearCache();

        Log::info('All email configurations deactivated');
    }

    public function getSmtpConfig(): ?array
    {
        $config = $this->getConfiguration();

        if (!$config || !$config->hasSmtpConfigured()) {
            return null;
        }

        return [
            'host'       => $config->smtp_host,
            'port'       => $config->smtp_port,
            'username'   => $config->smtp_username,
            'password'   => $config->smtp_password,
            'encryption' => $config->smtp_encryption,
            'from'       => [
                'address' => $config->from_address,
                'name'    => $config->from_name,
            ],
        ];
    }

    public function getImapConfig(): ?array
    {
        $config = $this->getConfiguration();

        if (!$config || !$config->hasImapConfigured()) {
            return null;
        }

        return [
            'host'       => $config->imap_host,
            'port'       => $config->imap_port,
            'username'   => $config->imap_username,
            'password'   => $config->imap_password,
            'encryption' => $config->imap_encryption,
        ];
    }

    public function getStatusSummary(): array
    {
        $config = $this->getConfiguration();

        if (!$config) {
            return [
                'configured'      => false,
                'smtp_configured' => false,
                'imap_configured' => false,
                'from_address'    => null,
                'from_name'       => null,
            ];
        }

        return [
            'configured'      => true,
            'id'              => $config->id,
            'smtp_configured' => $config->hasSmtpConfigured(),
            'imap_configured' => $config->hasImapConfigured(),
            'from_address'    => $config->from_address,
            'from_name'       => $config->from_name,
            'is_active'       => $config->is_active,
            'updated_at'      => $config->updated_at?->format('Y-m-d H:i:s'),
        ];
    }

    public function clearCache(): void
    {
        Cache::forget(self::CACHE_KEY);
        Cache::forget(self::CACHE_KEY . '_exists');
    }

    public function getEnvironmentConfig(): array
    {
        return [
            'smtp' => [
                'host'       => env('MAIL_SMTP_HOST'),
                'port'       => env('MAIL_SMTP_PORT', 587),
                'username'   => env('MAIL_SMTP_USERNAME'),
                'password'   => env('MAIL_SMTP_PASSWORD'),
                'encryption' => env('MAIL_SMTP_ENCRYPTION', 'tls'),
            ],
            'imap' => [
                'host'       => env('MAIL_IMAP_HOST'),
                'port'       => env('MAIL_IMAP_PORT', 993),
                'username'   => env('MAIL_IMAP_USERNAME'),
                'password'   => env('MAIL_IMAP_PASSWORD'),
                'encryption' => env('MAIL_IMAP_ENCRYPTION', 'ssl'),
            ],
            'from' => [
                'address' => env('MAIL_FROM_ADDRESS'),
                'name'    => env('MAIL_FROM_NAME'),
            ],
        ];
    }

    public function hasCredentials(string $type = 'smtp'): bool
    {
        $config = $this->getConfiguration();

        if (!$config) {
            return false;
        }

        if ($type === 'smtp') {
            return $config->hasSmtpConfigured()
                && !empty($config->smtp_username)
                && !empty($config->smtp_password);
        }

        if ($type === 'imap') {
            return $config->hasImapConfigured()
                && !empty($config->imap_username)
                && !empty($config->imap_password);
        }

        return false;
    }

    public function getAllConfigurations()
    {
        return EmailConfiguration::orderBy('created_at', 'desc')->get();
    }
}
