<?php

namespace App\Services;

use App\Developer;
use App\Http\Controllers\Traits\ValidationTrait;
use App\Http\Requests\Api\SubscriptionStoreRequest;
use App\ResidentialComplex;
use App\SubscriptionDeveloper;
use App\SubscriptionRc;
use App\SubscriptionSite;
use Illuminate\Http\Request;
use Newsletter;

class SubscriptionService
{
    use ValidationTrait;
    const NS_RESIDENTIAL_COMPLEX = 'rc';
    const NS_DEVELOPER = 'developer';
    const NS_MAIN = 'main';

    /**
     * @param Request $request
     * @throws \Exception
     */
    public function subscribe(Request $request)
    {
        $data = $request->all();

        $isEmail = false;
        if (!empty($data['email']) && strpos($data['email'], '@')) {
            $isEmail = true;
        }
        if ($data['type'] == SubscriptionStoreRequest::DEVELOPER) {
            if (!$developer = Developer::query()->find($data['value'])) {
                throw new \Exception('developer content was not found');
            };
            $this->storeDeveloperSubscription($data, $developer, $isEmail);
        } elseif ($data['type'] == SubscriptionStoreRequest::RC) {
            if (!$rc = ResidentialComplex::query()->find($data['value'])) {
                throw new \Exception('residential complex content was not found');
            }

            $this->storeResidentialComplexSubscription($data, $rc, $isEmail);
        } else {
            $this->storeSiteSubscription($data, $isEmail);
        }
    }

    /**
     * @param $data
     * @param bool $isEmail
     */
    public function storeSiteSubscription($data, $isEmail = true)
    {
        $subscriptionSite = SubscriptionSite::query()->where('email', $data['email'])->first();
        if ($subscriptionSite) {
            $subscriptionSite->update(['is_subscribed' => true]);
        } else {
            SubscriptionSite::query()->create([
                'email' => $data['email'],
                'is_subscribed' => true
            ]);
        }

        if ($isEmail) {
            $this->subscribeToList($data['email'], self::NS_MAIN);
        }
    }

    /**
     * @param $data
     * @param $rc
     * @param bool $isEmail
     */
    public function storeResidentialComplexSubscription($data, $rc, $isEmail = true)
    {
        $subscriptionRC = SubscriptionRc::query()->where('email', $data['email'])->where('residential_complex_id',
            $data['value'])->first();
        if ($subscriptionRC) {
            $subscriptionRC->update(['is_subscribed' => true]);
        } else {
            SubscriptionRc::query()->create([
                'email' => $data['email'],
                'residential_complex_id' => $data['value'],
                'is_subscribed' => true
            ]);
        }

        if ($isEmail) {
            $this->subscribeToList($data['email'], self::NS_RESIDENTIAL_COMPLEX, $rc->name);
        }
    }

    /**
     * @param $data
     * @param $developer
     * @param bool $isEmail
     */
    public function storeDeveloperSubscription($data, $developer, $isEmail = true)
    {
        $subscriptionDeveloper = SubscriptionDeveloper::query()->where('email', $data['email'])->where('developer_id',
            $data['value'])->first();
        if ($subscriptionDeveloper) {
            $subscriptionDeveloper->update(['is_subscribed' => true]);
        } else {
            SubscriptionDeveloper::query()->create([
                'email' => $data['email'],
                'developer_id' => $data['value'],
                'is_subscribed' => true
            ]);
        }

        if ($isEmail) {
            $this->subscribeToList($data['email'], self::NS_DEVELOPER, $developer->name);
        }
    }

    /**
     * @param string $email
     * @param string $listKey
     * @param array $tag
     */
    public function subscribeToList(string $email, string $listKey = '', string $tag = '')
    {
        if (!empty($listKey) && empty($tag)) {
            if (!Newsletter::hasMember($email, $listKey)) {
                Newsletter::subscribe($email);
            } elseif (Newsletter::hasMember($email, $listKey) && !Newsletter::isSubscribed($email, $listKey)) {
                Newsletter::subscribeOrUpdate($email);
            }
        }
        if (!empty($listKey) && !empty($tag)) {
            if (Newsletter::hasMember($email, $listKey) && Newsletter::isSubscribed($email, $listKey)) {
                Newsletter::addTags([$tag], $email, $listKey);
            } elseif (Newsletter::hasMember($email, $listKey) && !Newsletter::isSubscribed($email, $listKey)) {
                Newsletter::subscribeOrUpdate($email, [], $listKey);
            } else {
                Newsletter::subscribe($email, [], $listKey);
                Newsletter::addTags([$tag], $email, $listKey);
            }
        }
    }
}
