<?php

namespace App\Helpers\FirstParty\Purchase;

use App\Helpers\FirstParty\Stripe\StripeHelper;
use App\Models\Plan;
use App\Models\UserPlan;
use Laravel\Cashier\Events\WebhookReceived;

class SubscriptionHelper
{
    public static function handleWebhookEvents(WebhookReceived $event)
    {
        switch (StripeHelper::getEventType($event)) {
            case 'customer.subscription.created':
            case 'customer.subscription.updated':
                self::handleSubscriptionUpsert($event);
                break;

            case 'customer.subscription.deleted':
                self::handleSubscriptionDelete($event);
                break;
        }
    }

    private static function handleSubscriptionUpsert(WebhookReceived $event)
    {
        $object = StripeHelper::getEventObject($event);

        // dump($object);

        $ignore_statuses = ['incomplete_expired', 'incomplete'];

        if (in_array($object['status'], $ignore_statuses)) {
            return;
        }

        $user = StripeHelper::getUserByStripeID($object['customer']);

        if ($user) {
            foreach ($object['items']['data'] as $line_item) {

                // dump($line_item);

                $stripe_price_id = $line_item['plan']['id'];
                $current_period_end = $line_item['current_period_end'];

                $cancel_at = null;
                $canceled_at = null;

                if ($line_item['subscription'] == $object['id']) {
                    $cancel_at = $object['cancel_at'];
                    $canceled_at = $object['canceled_at'];
                }

                $subscription_config = PurchaseHelper::getSubscriptionPlanByStripePriceID($stripe_price_id);

                $plan = Plan::where('tier', $subscription_config['id'])->first();

                if ($plan) {
                    $user_plan = UserPlan::where('user_id', $user->id)->first();

                    if ($user_plan) {
                        $user_plan->update([
                            'plan_id' => $plan->id,
                            'current_period_end' => $current_period_end,
                            'cancel_at' => $cancel_at,
                            'canceled_at' => $canceled_at,
                        ]);
                    } else {
                        $user_plan = UserPlan::create([
                            'user_id' => $user->id,
                            'plan_id' => $plan->id,
                            'current_period_end' => $current_period_end,
                            'cancel_at' => $cancel_at,
                            'canceled_at' => $canceled_at,
                        ]);
                    }
                }
            }
        }
    }

    private static function handleSubscriptionDelete(WebhookReceived $event)
    {
        $object = StripeHelper::getEventObject($event);

        $user = StripeHelper::getUserByStripeID($object['customer']);

        if ($user) {

            foreach ($object['items']['data'] as $line_item) {

                $stripe_price_id = $line_item['plan']['id'];

                $subscription_config = PurchaseHelper::getSubscriptionPlanByStripePriceID($stripe_price_id);

                if ($subscription_config['type'] == 'subscription_plans') {
                    $free_plan = Plan::where('tier', 'free')->first();

                    $user_plan = UserPlan::where('user_id', $user->id)->first();

                    if ($user_plan) {
                        $user_plan->update([
                            'plan_id' => $free_plan->id,
                            'current_period_end' => null,
                            'cancel_at' => null,
                            'canceled_at' => null,
                        ]);
                    } else {
                        $user_plan = UserPlan::create([
                            'user_id' => $user->id,
                            'plan_id' => $free_plan->id,
                            'current_period_end' => null,
                            'cancel_at' => null,
                            'canceled_at' => null,
                        ]);
                    }
                }
            }
        }
    }
}
