<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use App\Core\Http\ToggleableRepositoryTrait;
use PDO;

final class EmailMailboxRepository
{
    use ToggleableRepositoryTrait;
    public function __construct(
        private readonly PDO $pdo,
        private readonly IntegrationSecretCipher $cipher
    ) {
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function listAll(): array
    {
        $statement = $this->pdo->prepare(
            'SELECT id, name, smtp_host, smtp_port, smtp_encryption, smtp_username,
                    sender_email, sender_name, is_default, is_active, created_at, updated_at
             FROM email_mailboxes
             ORDER BY is_default DESC, created_at DESC'
        );
        $statement->execute();
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        return is_array($rows) ? $rows : [];
    }

    /**
     * @return array<string, mixed>|null
     */
    public function findById(int $id): ?array
    {
        $statement = $this->pdo->prepare('SELECT * FROM email_mailboxes WHERE id = :id LIMIT 1');
        $statement->execute(['id' => $id]);
        $row = $statement->fetch(PDO::FETCH_ASSOC);

        if (!is_array($row)) {
            return null;
        }

        if (isset($row['smtp_password_encrypted']) && $row['smtp_password_encrypted'] !== '') {
            $row['smtp_password_decrypted'] = $this->cipher->decrypt($row['smtp_password_encrypted']);
        }

        return $row;
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function listActive(): array
    {
        $statement = $this->pdo->prepare(
            'SELECT id, name, sender_email, sender_name, is_default
             FROM email_mailboxes
             WHERE is_active = 1
             ORDER BY is_default DESC, name ASC'
        );
        $statement->execute();
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        return is_array($rows) ? $rows : [];
    }

    /**
     * @param array<string, mixed> $data
     */
    public function save(array $data): void
    {
        $id = isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : null;

        $encryption = in_array((string) ($data['smtp_encryption'] ?? ''), ['tls', 'ssl', 'none'], true)
            ? (string) $data['smtp_encryption']
            : 'tls';

        $isDefault = isset($data['is_default']) ? 1 : 0;

        if ($isDefault === 1) {
            $this->pdo->prepare('UPDATE email_mailboxes SET is_default = 0 WHERE is_default = 1')->execute();
        }

        $headerHtml = isset($data['header_html']) && trim((string) $data['header_html']) !== '' ? trim((string) $data['header_html']) : null;
        $footerHtml = isset($data['footer_html']) && trim((string) $data['footer_html']) !== '' ? trim((string) $data['footer_html']) : null;

        $params = [
            'name' => trim((string) ($data['name'] ?? '')),
            'smtp_host' => trim((string) ($data['smtp_host'] ?? '')),
            'smtp_port' => (int) ($data['smtp_port'] ?? 587),
            'smtp_encryption' => $encryption,
            'smtp_username' => trim((string) ($data['smtp_username'] ?? '')),
            'sender_email' => trim((string) ($data['sender_email'] ?? '')),
            'sender_name' => trim((string) ($data['sender_name'] ?? '')) ?: null,
            'header_html' => $headerHtml,
            'footer_html' => $footerHtml,
            'is_default' => $isDefault,
            'is_active' => isset($data['is_active']) ? 1 : 0,
        ];

        $password = (string) ($data['smtp_password'] ?? '');
        if ($password !== '') {
            $params['smtp_password_encrypted'] = $this->cipher->encrypt($password);
        }

        if ($id !== null) {
            $setClauses = [
                'name = :name',
                'smtp_host = :smtp_host',
                'smtp_port = :smtp_port',
                'smtp_encryption = :smtp_encryption',
                'smtp_username = :smtp_username',
                'sender_email = :sender_email',
                'sender_name = :sender_name',
                'header_html = :header_html',
                'footer_html = :footer_html',
                'is_default = :is_default',
                'is_active = :is_active',
            ];

            if (isset($params['smtp_password_encrypted'])) {
                $setClauses[] = 'smtp_password_encrypted = :smtp_password_encrypted';
            }

            $params['id'] = $id;
            $statement = $this->pdo->prepare(
                'UPDATE email_mailboxes SET ' . implode(', ', $setClauses) . ' WHERE id = :id'
            );
        } else {
            if (!isset($params['smtp_password_encrypted'])) {
                $params['smtp_password_encrypted'] = '';
            }

            $statement = $this->pdo->prepare(
                'INSERT INTO email_mailboxes (name, smtp_host, smtp_port, smtp_encryption, smtp_username, smtp_password_encrypted, sender_email, sender_name, header_html, footer_html, is_default, is_active)
                 VALUES (:name, :smtp_host, :smtp_port, :smtp_encryption, :smtp_username, :smtp_password_encrypted, :sender_email, :sender_name, :header_html, :footer_html, :is_default, :is_active)'
            );
        }

        $statement->execute($params);
    }

    public function delete(int $id): void
    {
        $statement = $this->pdo->prepare('DELETE FROM email_mailboxes WHERE id = :id');
        $statement->execute(['id' => $id]);
    }

    public function toggleStatus(int $id): void
    {
        $this->toggleActive('email_mailboxes', $id);
    }
}
