<?php

namespace App\Modules\Email\Postmark;

use App\Core\Email\AbstractEmail;
use Illuminate\Support\Facades\Http;

/**
 * PRC-106 — Postmark transactional email provider.
 *
 * Uses Postmark REST API directly (POST /email). Settings:
 *   server_token   — Postmark Server API token (encrypted)
 */
class Postmark extends AbstractEmail
{
    protected string $apiUrl = 'https://api.postmarkapp.com/email';

    public function sendEmail(array $params)
    {
        $validation = $this->validateEmailParams($params);
        if (! $validation['valid']) {
            return ['success' => false, 'errors' => $validation['errors']];
        }

        $token = $this->getConfig('server_token');
        if (! $token) {
            return ['success' => false, 'error' => 'Postmark server_token missing'];
        }

        $fromEmail = $params['from'] ?? $this->getConfig('from_email');
        $fromName = $params['from_name'] ?? $this->getConfig('from_name');
        $fromFormatted = $fromName ? "{$fromName} <{$fromEmail}>" : $fromEmail;

        $body = [
            'From' => $fromFormatted,
            'To' => is_array($params['to']) ? implode(',', $params['to']) : $params['to'],
            'Subject' => $params['subject'],
            'HtmlBody' => $params['html_content'] ?? $params['content'] ?? '',
            'TextBody' => $params['text_content'] ?? $this->htmlToText($params['html_content'] ?? $params['content'] ?? ''),
            'MessageStream' => $this->getConfig('message_stream', 'outbound'),
        ];
        if (! empty($params['cc'])) {
            $body['Cc'] = is_array($params['cc']) ? implode(',', $params['cc']) : $params['cc'];
        }
        if (! empty($params['bcc'])) {
            $body['Bcc'] = is_array($params['bcc']) ? implode(',', $params['bcc']) : $params['bcc'];
        }
        if (! empty($params['attachments'])) {
            $body['Attachments'] = array_map(fn ($a) => [
                'Name' => $a['name'] ?? basename($a['path']),
                'Content' => base64_encode(file_get_contents($a['path'])),
                'ContentType' => $a['mime'] ?? 'application/octet-stream',
            ], $params['attachments']);
        }

        try {
            $resp = Http::withHeaders([
                'Accept' => 'application/json',
                'X-Postmark-Server-Token' => $token,
            ])->timeout(30)->post($this->apiUrl, $body);

            $data = $resp->json();

            // Postmark HTTP 200 dönüp gövdede per-mesaj hata verebilir
            // (ErrorCode != 0). Başarıyı hem HTTP hem gövde-statüsüyle gate et.
            $errorCode = is_array($data) ? ($data['ErrorCode'] ?? null) : null;
            if (! $resp->successful() || ($errorCode !== null && (int) $errorCode !== 0)) {
                return [
                    'success' => false,
                    'error' => 'Postmark error: '.($data['Message'] ?? ('HTTP '.$resp->status())),
                ];
            }

            $messageId = $data['MessageID'] ?? null;
            if (! $messageId) {
                // message_id yoksa uydurma; provider onaylamadıysa başarı sayma.
                return ['success' => false, 'error' => 'Postmark response missing MessageID'];
            }

            return [
                'success' => true,
                'message_id' => $messageId,
                'message' => $data['Message'] ?? 'Email sent',
            ];
        } catch (\Throwable $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function renderTemplate(array $params)
    {
        return ['success' => true, 'rendered' => $params['content'] ?? ''];
    }

    public function testConnection(array $params)
    {
        $token = $params['server_token'] ?? $this->getConfig('server_token');
        if (! $token) {
            return ['success' => false, 'message' => 'server_token required'];
        }
        $resp = Http::withHeaders(['X-Postmark-Server-Token' => $token, 'Accept' => 'application/json'])
            ->timeout(15)
            ->get('https://api.postmarkapp.com/server');

        return $resp->successful()
            ? ['success' => true, 'message' => 'Postmark connection OK']
            : ['success' => false, 'message' => 'Postmark HTTP '.$resp->status()];
    }

    /**
     * Email pipeline config anahtarlarını YALNIZ buradan okur
     * (EmailManager::getProviderConfig → ModuleConfig::resolved yalnız burada
     * declared key'leri resolve eder). adminFields() Email ailesinde ölü koddur;
     * Postmark'ın gerçek alanları burada tanımlı. validateConfig() /
     * getRequiredConfigFields() de aynı anahtarlarla hizalı olmalı.
     */
    public function getConfigFields(): array
    {
        return [
            'server_token' => [
                'type' => 'password',
                'label' => 'Postmark Server Token',
                'required' => true,
                'encrypted' => true,
                'description' => 'Postmark Server API token',
            ],
            'from_email' => [
                'type' => 'email',
                'label' => __('modules.email_config_from_email'),
                'required' => true,
                'description' => __('modules.email_config_from_email_desc'),
            ],
            'from_name' => [
                'type' => 'text',
                'label' => __('modules.email_config_from_name'),
                'required' => true,
                'description' => __('modules.email_config_from_name_desc'),
            ],
            'message_stream' => [
                'type' => 'text',
                'label' => 'Message Stream',
                'required' => false,
                'default' => 'outbound',
                'description' => 'Postmark message stream (default: outbound)',
            ],
            'test_mode' => [
                'type' => 'boolean',
                'label' => __('modules.email_config_test_mode'),
                'required' => false,
                'default' => true,
                'description' => 'Test modunda çalıştır',
            ],
        ];
    }

    public function getRequiredConfigFields(): array
    {
        return ['server_token', 'from_email', 'from_name'];
    }
}
