<?php

declare(strict_types=1);

namespace App\Infrastructure\Api\RapidMail\Factories;

use App\Infrastructure\Api\RapidMail\Commands\CreateRecipientCommand;
use App\Infrastructure\Api\RapidMail\Commands\UpdateRecipientCommand;
use App\Infrastructure\Api\RapidMail\ReadModels\Recipient;
use App\Infrastructure\Api\RapidMail\RecipientListId;

final class RecipientCommandFactory
{
    public static function createFromArray(array $data, ?RecipientListId $recipientListId = null): CreateRecipientCommand
    {
        return new CreateRecipientCommand(
            email: $data['email'],
            firstname: $data['firstname'] ?? null,
            lastname: $data['lastname'] ?? null,
            title: $data['title'] ?? null,
            company: $data['company'] ?? null,
            zip: $data['zip'] ?? null,
            city: $data['city'] ?? null,
            street: $data['street'] ?? null,
            country: $data['country'] ?? null,
            phone: $data['phone'] ?? null,
            birthdate: $data['birthdate'] ?? null,
            gender: $data['gender'] ?? null,
            status: $data['status'] ?? null,
            recipientListId: $recipientListId,
            customFields: array_diff_key($data, array_flip([
                'email', 'firstname', 'lastname', 'title', 'company',
                'zip', 'city', 'street', 'country', 'phone', 'birthdate',
                'gender', 'status',
            ]))
        );
    }

    public static function updateFromRecipient(Recipient $recipient): UpdateRecipientCommand
    {
        return new UpdateRecipientCommand(
            id: $recipient->id,
            email: $recipient->email,
            firstname: $recipient->firstname,
            lastname: $recipient->lastname,
            title: $recipient->title,
            company: $recipient->company,
            zip: $recipient->zip,
            city: $recipient->city,
            street: $recipient->street,
            country: $recipient->country,
            phone: $recipient->phone,
            birthdate: $recipient->birthdate,
            gender: $recipient->gender,
            status: $recipient->status,
            recipientListId: $recipient->recipientListId,
            customFields: $recipient->customFields
        );
    }

    public static function updateFromRecipientWithChanges(Recipient $recipient, array $changes): UpdateRecipientCommand
    {
        $merged = array_merge([
            'email' => $recipient->email,
            'firstname' => $recipient->firstname,
            'lastname' => $recipient->lastname,
            'title' => $recipient->title,
            'company' => $recipient->company,
            'zip' => $recipient->zip,
            'city' => $recipient->city,
            'street' => $recipient->street,
            'country' => $recipient->country,
            'phone' => $recipient->phone,
            'birthdate' => $recipient->birthdate,
            'gender' => $recipient->gender,
            'status' => $recipient->status,
        ], $changes);

        return new UpdateRecipientCommand(
            id: $recipient->id,
            email: $merged['email'],
            firstname: $merged['firstname'],
            lastname: $merged['lastname'],
            title: $merged['title'],
            company: $merged['company'],
            zip: $merged['zip'],
            city: $merged['city'],
            street: $merged['street'],
            country: $merged['country'],
            phone: $merged['phone'],
            birthdate: $merged['birthdate'],
            gender: $merged['gender'],
            status: $merged['status'],
            recipientListId: $changes['recipientListId'] ?? $recipient->recipientListId,
            customFields: array_merge($recipient->customFields, $changes['customFields'] ?? [])
        );
    }
}
