<?php

namespace App\Services;

use App\Models\Account\Account;
use App\Models\Account\Plan;
use App\Models\User\User;
use RuntimeException;
use Str;
use Stripe;

/**
 * Provides Account business logic (creation, update, etc)
 */
class AccountService
{
    /**
     * createAccount
     *
     * @param  User $user
     * @return Account
     */
    public function createAccount(User $user)
    {
        $plan = $this->getFreePlan();
        if (!$plan) {
            throw new RuntimeException("Free plan not available!");
        }
        $account = new Account();
        $account->uid = Str::random(config('app.uid_length'));
        $account->name = $user->name;
        $account->owner()->associate($user);
        $account->settings = [];
        $account->plan()->associate($plan);

        $this->generateUniqueSlug($account);

        $account->save();
        return $account;
    }

    public function updateContacts(Account $account, array $contacts)
    {
        $settings = $account->settings;
        $settings['contactInfo'] = $contacts;
        $account->settings = $settings;
        $account->save();
    }

    public function createSubscription(Account $account, $data)
    {
        try {
            Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));

            if (is_null($account->stripe_id)) {
                $stripeCustomer = $account->createAsStripeCustomer([
                    'name' => $account->name,
                    'email' => $account->owner->email
                ]);
            }

            Stripe\Customer::createSource(
                $account->stripe_id,
                ['source' => $data['id']]
            );

            $account->newSubscription('Pro', 'price_1HcpEiEZt5x4LKJOjGmUSctM')
                ->create($data['card']['id'], ['email' => $account->owner->email]);

            $proPlan = Plan::find(2);
            $account->plan()->associate($proPlan);
            $account->save();
            return true;
        } catch (\Exception $e) {
            throw $e;
            return false;
        }
    }

    public function updateName(Account $account, string $name)
    {
        $account->name = $name;
        $account->save();
    }

    protected function getFreePlan()
    {
        return Plan::where('type', Plan::TYPE_FREE)
            ->where('state', Plan::STATE_ACTIVE)
            ->first();
    }

    /**
     * generateUniqueSlug
     *
     * @param  App\Models\Account\Account $account
     * @return void
     */
    protected function generateUniqueSlug(Account $account)
    {
        $baseSlug = Str::slug($account->name);
        $suffix = '';
        while(Account::where('slug', $baseSlug . $suffix)->count()) {
            $suffix = '-' . Str::random(4);
        }
        $account->slug =  $baseSlug . $suffix;
    }
}
