<?php

namespace App\Modules\Jobseeker\Subscription;

use App\Models\JobseekerPayment;
use App\Models\JobseekerSubscription;

use Exception;

use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

use Carbon\Carbon;

use Stripe;

class Payment
{
    public $userData;

    public function __construct()
    {
        Stripe\Stripe::setApiKey(config('stripe.secret_key'));
        
        $this->userData = Auth::user();
    }

    public function buySubscription(array $payload)
    {
        $jobseeker  = $this->userData;
        $date_today = Carbon::now()->format('Y-m-d-h-i-s');
        $invoice_no = 'IVN-' . $date_today . '-' . Str::random(10);
        $days_toAdd = 30 * (int) $payload['month'];

        $subscription = $this->get_jobseeker_subscription($jobseeker->id);

        if ($subscription) 
        {
            // $current_duration =  $subscription->duration;
            if ($subscription->duration >= $date_today) 
            {
                $current_duration = $subscription->duration;
            } 
            else 
            {
                $current_duration = Carbon::now()->format('Y-m-d');
            }
        } 
        else 
        {
            $current_duration = Carbon::now()->format('Y-m-d');
        }

        try 
        {
            DB::beginTransaction();

            $customer = \Stripe\Customer::create(
                [
                    'email' => $jobseeker->email_address,
                    'source' => $payload['token'],
                ]
            );
            
            $customer_id = $customer->id;

            $charge = \Stripe\Charge::create(
                [
                    'customer' => $customer_id,
                    'amount' => (int) $payload['rate'] * 100,
                    'currency' => 'usd',
                    'receipt_email' => $jobseeker->email_address,
                ]
            );

            if ($charge->status == "succeeded") 
            {
                $subcription_data = array(
                    'customer_id' => $customer_id,
                    'worker_id'   => $jobseeker->id,
                    'rate_id'     => $payload['id'],
                    'duration'    => Carbon::create($current_duration)->addDays($days_toAdd)->format('Y-m-d'),
                    'status'      => 'subscribed',
                );

                $subscription_transaction = $this->create_jobseeker_subscription($jobseeker->id, $subcription_data);

                $subcription_payment = array(
                    'jobseeker_subscription_id' => $subscription_transaction->id,
                    'rate_id'                   => $payload['id'],
                    'invoice_no'                => $invoice_no,
                    'customer_id'               => $jobseeker->id,
                    'charge_id'                 => $charge->id,
                    'amount_paid'               => $payload['rate'],
                    'duration'                  => Carbon::create($current_duration)->addDays($days_toAdd)->format('Y-m-d'),
                );

                $payment_transaction = $this->create_jobseeker_payment($subcription_payment);

                if ($subcription_data && $payment_transaction) 
                {
                    DB::commit();
                
                    return [
                        'result'      => $charge->status,
                        'invoice_no'  => $invoice_no,
                        'receipt_url' => $charge->receipt_url,
                        'rate_name'   => $payload['name'],
                        'note'        => 'Successfully Purchased Subscription!',
                    ];
                } 
                else 
                {
                    DB::rollBack();

                    return  [
                        'result'      => 'failed',
                    ];
                }
            }

        } 
        catch (Exception $e) 
        {
            http_response_code(500);

            echo json_encode(
                [
                    'error' => $e->getMessage()
                ]
            );
        }
    }

    public function create_jobseeker_subscription($id, $data)
    {
        return JobseekerSubscription::updateOrCreate(
            [
                'worker_id' => $id
            ],
            $data
        );
    }

    public function create_jobseeker_payment($data)
    {
        return JobseekerPayment::create($data);
    }

    public function get_jobseeker_subscription($id)
    {
        return JobseekerSubscription::where('worker_id', $id)->first();
    }
}
