<?php

namespace App\Services\EmailCampaign\Drivers;

use App\Models\EmailCampaign;
use App\Models\EmailCampaignRecipient;
use App\Models\Setting;
use Illuminate\Support\Facades\Log;
use MailchimpMarketing\ApiClient;

class MailchimpDriver extends AbstractEmailCampaignDriver
{
    protected function client(): ApiClient
    {
        $apiKey = (string) Setting::getValue('mailchimp_api_key', '');
        $serverPrefix = (string) Setting::getValue('mailchimp_server_prefix', '');
        if ($apiKey === '' || $serverPrefix === '') {
            throw new \RuntimeException('Mailchimp not configured');
        }
        $client = new ApiClient();
        $client->setConfig([
            'apiKey' => $apiKey,
            'server' => $serverPrefix,
        ]);
        return $client;
    }

    /**
     * For Mailchimp we don't fan out per-recipient: the first call ensures
     * the campaign is created + sent on Mailchimp side. Subsequent calls
     * for the same campaign are no-op success.
     */
    public function send(EmailCampaign $campaign, EmailCampaignRecipient $recipient): array
    {
        if ($campaign->remote_id) {
            return ['success' => true];
        }

        try {
            $client = $this->client();

            $listId = $campaign->list?->remote_id;
            if (! $listId) {
                return ['success' => false, 'error' => 'List has no Mailchimp remote_id (sync first)'];
            }

            $createResp = $client->campaigns->create([
                'type' => 'regular',
                'recipients' => ['list_id' => $listId],
                'settings' => [
                    'subject_line' => $campaign->subject ?: $campaign->name,
                    'title' => $campaign->name,
                    'from_name' => $campaign->from_name ?: 'Demo',
                    'reply_to' => $campaign->reply_to ?: $campaign->from_email,
                ],
            ]);

            $client->campaigns->setContent($createResp->id, [
                'html' => (string) $campaign->content_html,
            ]);

            $client->campaigns->send($createResp->id);

            $campaign->update(['remote_id' => $createResp->id]);

            return ['success' => true];
        } catch (\Throwable $e) {
            Log::warning('MailchimpDriver send failed', [
                'campaign_id' => $campaign->id,
                'error' => $e->getMessage(),
            ]);
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function sendTest(EmailCampaign $campaign, string $email): array
    {
        try {
            $client = $this->client();

            // For test, we need an existing campaign on Mailchimp. If not, create draft first.
            if (! $campaign->remote_id) {
                $listId = $campaign->list?->remote_id;
                if (! $listId) {
                    return ['success' => false, 'error' => 'List has no Mailchimp remote_id'];
                }
                $createResp = $client->campaigns->create([
                    'type' => 'regular',
                    'recipients' => ['list_id' => $listId],
                    'settings' => [
                        'subject_line' => '[TEST] '.($campaign->subject ?: $campaign->name),
                        'title' => $campaign->name,
                        'from_name' => $campaign->from_name ?: 'Demo',
                        'reply_to' => $campaign->reply_to ?: $campaign->from_email,
                    ],
                ]);
                $client->campaigns->setContent($createResp->id, [
                    'html' => (string) $campaign->content_html,
                ]);
                $campaign->update(['remote_id' => $createResp->id]);
            }

            $client->campaigns->sendTestEmail($campaign->remote_id, [
                'test_emails' => [$email],
                'send_type' => 'html',
            ]);

            return ['success' => true];
        } catch (\Throwable $e) {
            Log::warning('MailchimpDriver sendTest failed', [
                'campaign_id' => $campaign->id,
                'error' => $e->getMessage(),
            ]);
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public function supportsTracking(): bool
    {
        return true;
    }
}
