<?php

namespace PeytzMail\Tests;

use PeytzMail\PeytzMail;
use PeytzMail\Entity\Recipient;
use PeytzMail\Entity\TriggerMail;

class TriggerMailTest extends TestCase
{
    public function testWeGotTriggerMail()
    {
        $json = <<<JSON
{
    "trigger_mail": {
        "_id": "544621743fd580579c000150",
        "created_at": "2014-10-21T11:03:48+02:00",
        "reply_to": "no-reply@bonnier.dk",
        "from_email": "redaktion@illvid.dk",
        "from_name": "Illustreret Videnskab",
        "to_email": "annemarie.kolding@gmail.com",
        "to_name": null,
        "subject": "Nye login-oplysninger for: annemarie.kolding@gmail.com på Illustreret Videnskab",
        "state": "opened",
        "is_delayed_sending": false,
        "delayed_sending_at": null,
        "tag": "user_password_reset.illvid.dk",
        "trigger_mail_category_id": "user-password-reset-illvid-dk"
    }
}
JSON;
        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $triggerMail = $peytzMail->getTriggerMail('544621743fd580579c000150');

        $this->assertInstanceOf('PeytzMail\Entity\TriggerMail', $triggerMail);
        $this->assertSame('544621743fd580579c000150', $triggerMail->id);
        $this->assertSame('2014-10-21T11:03:48+02:00', $triggerMail->createdAt);
        $this->assertSame('no-reply@bonnier.dk', $triggerMail->replyTo);
        $this->assertSame('redaktion@illvid.dk', $triggerMail->fromEmail);
        $this->assertSame('Illustreret Videnskab', $triggerMail->fromName);
        $this->assertSame('annemarie.kolding@gmail.com', $triggerMail->toEmail);
        $this->assertNull($triggerMail->toName);
        $this->assertSame('Nye login-oplysninger for: annemarie.kolding@gmail.com på Illustreret Videnskab', $triggerMail->subject);
        $this->assertSame('opened', $triggerMail->state);
        $this->assertFalse($triggerMail->isDelayedSending);
        $this->assertNull($triggerMail->delayedSendingAt);
        $this->assertSame('user_password_reset.illvid.dk', $triggerMail->tag);
        $this->assertSame('user-password-reset-illvid-dk', $triggerMail->triggerMailCategoryId);
    }

    public function testCreateAndSendTriggerMail()
    {
        $recipient = new Recipient;
        $recipient->toEmail = 'customer@test.dk';
        $recipient->toName  = 'customer name';

        $recipients = array($recipient);

        $triggerMail = new TriggerMail;
        $triggerMail->subject   = 'subject';
        $triggerMail->fromName  = 'tieku.fi';
        $triggerMail->fromEmail = 'no-reply@tieku.fi';
        $triggerMail->layoutId  = 'tieku-fi';
        $triggerMail->tag       = 'userhub validation';

        $json = <<<JSON
{
    "trigger_mails": [
        {
            "_id": "54464a563fd580f04e000145",
            "to_email": "customer@test.dk",
            "to_name": "customer name",
            "state": "queued"
        }
    ]
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $triggeredMail = $peytzMail->createAndSendTriggerMail($triggerMail, $recipients);

        $this->assertTrue(is_array($triggeredMail));
        $this->assertCount(1, $triggeredMail);
        $this->assertInstanceOf('PeytzMail\Entity\TriggerMail', $triggeredMail[0]);
        $this->assertSame('54464a563fd580f04e000145', $triggeredMail[0]->id);
        $this->assertSame('customer@test.dk', $triggeredMail[0]->toEmail);
        $this->assertSame('customer name', $triggeredMail[0]->toName);
        $this->assertSame('queued', $triggeredMail[0]->state);
    }

    public function testNoRecipentProvided()
    {
        $this->expectException('PeytzMail\Exception\InvalidArgumentException');

        $triggerMail = new TriggerMail;
        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->createAndSendTriggerMail($triggerMail, array('foo', 'bar'));
    }

    public function testNoTriggerMailsFound()
    {
        $this->expectException('\\PeytzMail\\Exception\\NoResultException');
        $json = <<<JSON
{
    "current_page"  : 1,
    "total_records" : 0,
    "total_pages"   : 0,
    "next_page"     : null,
    "trigger_mails"   : []
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $peytzMail->findTriggerMails(array());
    }

    public function testOnlyOneSubscriberFound()
    {
        $criteria = array(
            'to_email' => 'foo@bar.org',
        );

        $json = <<<JSON
{
    "current_page"  : 1,
    "total_records" : 1,
    "total_pages"   : 1,
    "next_page"     : null,
    "trigger_mails"   : [{
        "id": "5fd3539361ee2b001854a27f",
            "created_at": "2020-12-11T12:10:11+01:00",
            "reply_to": "noreply@example-company.com",
            "from_email": "no-reply@example-company.com",
            "from_name": "The example company",
            "to_email": "foo@bar.org",
            "to_name": "New User 1",
            "subject": "Here's your triggermail!",
            "state": "opened",
            "general_state": "closed",
            "is_delayed_sending": false,
            "delayed_sending_at": null,
            "tag": "just-a-test-tag",
            "tags": [
                "test-test"
            ],
            "trigger_mail_category_id": "testing"
        }]
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $foundTriggerMails = $peytzMail->findTriggerMails($criteria);

        $this->assertTrue(is_array($foundTriggerMails));
        $this->assertCount(1, $foundTriggerMails);

        $foundTriggerMail = $foundTriggerMails[0];

        $this->assertInstanceOf('\\PeytzMail\\Entity\\TriggerMail', $foundTriggerMail);
        $this->assertSame('foo@bar.org', $foundTriggerMail->toEmail);
        $this->assertSame('New User 1', $foundTriggerMail->toName);
        $this->assertTrue(is_array($foundTriggerMail->tags));
        $this->assertSame($foundTriggerMail->triggerMailCategoryId, 'testing');
    }

    public function testManySubscribersFound()
    {
        $criteria = array(
            'tags' => 'test-test',
        );

        $json = <<<JSON
{
    "current_page"  : 1,
    "total_records" : 2,
    "total_pages"   : 1,
    "next_page"     : null,
    "trigger_mails"   : [
        {
            "id": "x",
                "created_at": "2020-12-11T12:10:11+01:00",
                "reply_to": "noreply@example-company.com",
                "from_email": "no-reply@example-company.com",
                "from_name": "The example company",
                "to_email": "foo@bar.org",
                "to_name": "New User 1",
                "subject": "Here's your triggermail!",
                "state": "opened",
                "general_state": "closed",
                "is_delayed_sending": false,
                "delayed_sending_at": null,
                "tag": "just-a-test-tag",
                "tags": [
                    "test-test"
                ],
                "trigger_mail_category_id": "testing"
            },
            {
            "id": "y",
                "created_at": "2019-12-11T12:10:11+01:00",
                "reply_to": "noreply@example-company.com",
                "from_email": "no-reply@example-company.com",
                "from_name": "The example company",
                "to_email": "footoo@bar.org",
                "to_name": "New User 2",
                "subject": "Here's also your triggermail!",
                "state": "opened",
                "general_state": "closed",
                "is_delayed_sending": false,
                "delayed_sending_at": null,
                "tag": "just-a-test-tag",
                "tags": [
                    "test-test"
                ],
                "trigger_mail_category_id": "testing"
            }
        ]
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $foundTriggerMails = $peytzMail->findTriggerMails($criteria);

        $this->assertTrue(is_array($foundTriggerMails));
        $this->assertCount(2, $foundTriggerMails);

        $foobar = $foundTriggerMails[0];
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TriggerMail', $foobar);
        $this->assertSame('x', $foobar->id);
        $this->assertSame('foo@bar.org', $foobar->toEmail);
        $this->assertSame('New User 1', $foobar->toName);

        $footoo = $foundTriggerMails[1];
        $this->assertInstanceOf('\\PeytzMail\\Entity\\TriggerMail', $footoo);
        $this->assertSame('y', $footoo->id);
        $this->assertSame('footoo@bar.org', $footoo->toEmail);
        $this->assertSame('New User 2', $footoo->toName);
    }
}
