<?php
/**
 * app/plugins/members/plugin.php
 *
 * This houses all of the main plugin info and functionality.
 *
 * @package TP Members
 * @version 3.0
 * @author  Joey Kimsey <Joey@thetempusproject.com>
 * @link    https://TheTempusProject.com
 * @license https://opensource.org/licenses/MIT [MIT LICENSE]
 */
namespace TheTempusProject\Plugins;

use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Classes\Plugin;
use Stripe\StripeClient;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\Memberships;
use TheTempusProject\Models\MembershipProducts as Products;
use TheTempusProject\Canary\Bin\Canary as Debug;

class Members extends Plugin {
    public static $stripe;
    public static $memberships;
    private static $loaded = false;
    public $pluginName = 'TP Membership';
    public $configName = 'memberships';
    public $pluginAuthor = 'JoeyK';
    public $pluginWebsite = 'https://TheTempusProject.com';
    public $modelVersion = '1.0';
    public $pluginVersion = '3.0';
    public $pluginDescription = 'A simple plugin which adds a site wide membership system.';
    public $permissionMatrix = [
        'memberAccess' => [
            'pretty' => 'Access Member Areas',
            'default' => false,
        ],
        'controlMemberships' => [
            'pretty' => 'User can Access and Control user memberships.',
            'default' => false,
        ],
    ];
    public $admin_links = [
        [
            'text' => '<i class="fa fa-fw fa-arrow-down"></i> Memberships',
            'url' => [
                [
                    'text' => '<i class="fa fa-fw fa-barcode"></i> Products',
                    'url' => '{ROOT_URL}admin/products',
                ],
                [
                    'text' => '<i class="fa fa-fw fa-bag-shopping"></i> Subscriptions',
                    'url' => '{ROOT_URL}admin/records',
                ],
                [
                    'text' => '<i class="fa fa-fw fa-code"></i> Scripts',
                    'url' => '{ROOT_URL}admin/members',
                ],
            ],
        ],
    ];
    public $main_links = [
        [
            'text' => 'My Membership',
            'url' => '{ROOT_URL}member/index',
            'filter' => 'member',
        ],
        [
            'text' => 'Subscribe',
            'url' => '{ROOT_URL}member/join',
            'filter' => 'nonmember',
        ],
        [
            'text' => 'Upgrade',
            'url' => '{ROOT_URL}member/upgrade',
            'filter' => 'upgrade',
        ],
    ];
    public $resourceMatrix = [
        'groups' => [
            [
                'name' => 'Member',
                'permissions' => '{"adminAccess":false}',
            ]
        ],
    ];
    public $configMatrix = [
        'stripePublishable' => [
            'type' => 'text',
            'pretty' => 'Stripe Publishable key',
            'default' => 'pk_xxxxxxxxxxxxxxx',
        ],
        'stripeSecret' => [
            'type' => 'text',
            'pretty' => 'Stripe Secret key',
            'default' => 'sk_xxxxxxxxxxxxxxx',
        ],
    ];
    public static $webhookEvents = [
        'customer.subscription.created',
        'customer.subscription.updated',
        'customer.subscription.deleted',
        'customer.updated',
        'customer.deleted',
        'payment_method.automatically_updated',
        'invoice.payment_action_required',
        'invoice.payment_succeeded',
        'checkout.session.completed',
    ];
    public static $userLinks = [
        "url" => "{ROOT_URL}member/manage",
        "name" => "Subscriptions"
    ];

    public function __construct( $load = false ) {
        if ( ! self::$loaded && $load ) {
            if ( App::$isLoggedIn ) {
                App::$isMember = $this->groupHasMemberAccess( App::$activeGroup );
                if ( empty( App::$isMember ) ) {
                    App::$isMember = $this->userHasActiveMembership( App::$activeUser->ID );
                }
            }
            $this->filters[] = [
                'name' => 'member',
                'find' => '#{MEMBER}(.*?){/MEMBER}#is',
                'replace' => ( App::$isMember ? '$1' : '' ),
                'enabled' => true,
            ];
            $this->filters[] = [
                'name' => 'nonmember',
                'find' => '#{NONMEMBER}(.*?){/NONMEMBER}#is',
                'replace' => ( App::$isLoggedIn && App::$isMember == false ? '$1' : '' ),
                'enabled' => true,
            ];
            $this->filters[] = [
                'name' => 'upgrade',
                'find' => '#{UPGRADE}(.*?){/UPGRADE}#is',
                'replace' => ( App::$isLoggedIn && ( App::$isMember === 'monthly' ) ? '$1' : '' ),
                'enabled' => true,
            ];
        }

        parent::__construct( $load );

        if ( $this->checkEnabled() && App::$isLoggedIn ) {
            if ( ! self::$loaded && $load ) {
                App::$userCPlinks[] = (object) self::$userLinks;
                App::$topNavRightDropdown .= '<li><a href="{ROOT_URL}member/manage" class="dropdown-item"><i class="fa fa-fw fa-credit-card"></i> Subscriptions</a></li>';
            }
        }

        if ( ! self::$loaded && $load ) {
            self::$loaded = true;
        }

        $api_key = Config::getValue( 'memberships/stripeSecret' );
        if ( $api_key == 'sk_xxxxxxxxxxxxxxx' || empty($api_key) ) {
            self::$stripe = false;
        } else {
            self::$stripe = new StripeClient( $api_key );
        }
    }

    public function groupHasMemberAccess( $activeGroup ) {
        if ( $activeGroup->memberAccess == true ) {
            return true;
        }
        return false;
    }

    public function userHasActiveMembership( $user_id ) {
        $memberships = new Memberships;
        $membership = $memberships->findActiveByUserID( $user_id );
        if ( empty( $membership ) ) {
            return false;
        }

        $products = new Products;
        $product = $products->findByPriceID( $membership->subscription_price_id );
        if ( empty( $product ) ) {
            Debug::error('Active membership on non-existent product');
            return false;
        }
        if ( $product->stripe_price_monthly == $membership->subscription_price_id ) {
            return 'monthly';
        }
        return 'yearly';
    }

    public static function webhookSetup() {
        $root = Routes::getAddress();
        $response = self::$stripe->webhookEndpoints->create([
            'enabled_events' => self::$webhookEvents,
            'url' => $root . 'api/stripe/webhook',
        ]);
        return $response;
    }

    public static function webhookList() {
        $response = self::$stripe->webhookEndpoints->all(['limit' => 25]);
        return $response;
    }
    
    public static function webhookRemove( $id ) {
        $response = self::$stripe->webhookEndpoints->delete( $id, []);
        return $response;
    }

    public static function orphanAbandon( $id ) {
        $response = self::$stripe->prices->update(
            $id,
            ['lookup_key' => ""]
        );
        return $response;
    }

    public static function findOrphans() {
        $orphans = [];
        // any prices with keys not represented in our local db will show as an orphan

        $result = self::$stripe->prices->search([
            'query' => 'lookup_key:"membership-monthly"',
        ]);

        $products = new Products;
        if ( ! empty( $result->data ) ) {
            $product = $products->findByPriceID( $result->data[0]->id );
            
            if ( empty( $product ) ) {
                $data = $result->data[0];
                
                $child = new \stdClass;
                $child->price_id = $data->id;
                $child->product = $data->product;
                $child->lookup_key = $data->lookup_key;
                $child->amount = $data->unit_amount;
                $orphans[] = $child;
            }
        }

        $result = self::$stripe->prices->search([
            'query' => 'lookup_key:"membership-yearly"',
        ]);
        if ( ! empty( $result->data ) ) {
            $product = $products->findByPriceID( $result->data[0]->id );
            
            if ( empty( $product ) ) {
                $data = $result->data[0];
                
                $child = new \stdClass;
                $child->price_id = $data->id;
                $child->product = $data->product;
                $child->lookup_key = $data->lookup_key;
                $child->amount = $data->unit_amount;
                $orphans[] = $child;
            }
        }

        return $orphans;
    }
}
