<?php

namespace Tests\Feature;

use App\Models\JobseekerSubscription;
use App\Models\JobSeekerSubscriptionRates; 
use App\Models\JobSeekerSubscriptionFreeTrial;
use App\Models\Worker; 
use App\Modules\Jobseeker\JobSeekerSubscriptionManagementModule; 

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

use Carbon\Carbon; 

use Tests\TestCase;

class JobSeekerSubscriptionExpirationTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Set Up Test
     * 
     * @return void 
     */
    protected function setUp(): void
    {
        parent::setUp();
    }

    /**
     * Create Worker via factory  
     * 
     * @param array $factoryState 
     * 
     * @return Worker 
     */
    private function createWorker(array $factoryState = []): Worker
    {
        return Worker::factory()
            ->state($factoryState)
            ->create();
    }

    /**
     * Create Job Seeker Subscription via factory  
     * 
     * @param array $factoryState 
     * 
     * @return JobseekerSubscription
     */
    private function createJobSeekerSubscription(array $factoryState = []): JobseekerSubscription
    {
        return JobseekerSubscription::factory()
            ->state($factoryState)
            ->create();
    }

    /**
     * Create Job Seeker Subscription via factory  
     * 
     * @param array $factoryState 
     * 
     * @return JobseekerSubscriptionFreeTrial
     */
    private function createJobSeekerSubscriptionFreeTrial(array $factoryState = []): JobseekerSubscriptionFreeTrial
    {
        return JobseekerSubscriptionFreeTrial::factory()
            ->state($factoryState)
            ->create();
    }

    /**
     * Create Job Seeker Subscription Rate via factory  
     * 
     * @param array $factoryState 
     * 
     * @return JobseekerSubscription
     */
    private function createJobSeekerSubscriptionRate(array $factoryState = []): JobSeekerSubscriptionRates
    {
        return JobSeekerSubscriptionRates::factory()
            ->state($factoryState)
            ->create();
    }
    
    /**
     * Test Expiration on Duration on Free Trial 
     * 
     * @return void 
     */
    public function test_expiration_duration_on_free_trial(): void
    {
        $subscriptionFreeTrial = $this->createJobSeekerSubscriptionFreeTrial(
            [
                'days'  =>  15 
            ]
        ); 

        $jobSeeker             = $this->createWorker(
            [
                'worker_id'  => null,
                'date_hired' => null,
            ]
        ); 

            $this->createJobSeekerSubscription(
            [
                'worker_id'   => $jobSeeker->id,
                'rate_id'     => 0,
                'duration'    => Carbon::now()->subDays($subscriptionFreeTrial->days), 
                'status'      => 'trial',
                'customer_id' => null,
            ]
        ); 

        (new JobSeekerSubscriptionManagementModule())->itemsSetStatusToExpire();

        $this->assertDatabaseHas(
            JobseekerSubscription::class,
            [
                'worker_id' => $jobSeeker->id,
                'rate_id'   => 0, 
                'status'    => 'expired',
            ]
        );
    }

    /**
     * Test Expiration on Duration on Free Trial 
     * 
     * @return void 
     */
    public function test_expiration_duration_on_subscribed_rate(): void
    {
        $subscriptionRate = $this->createJobSeekerSubscriptionRate(
            [
                'month' => 1 
            ]
        );

        $jobSeeker             = $this->createWorker(
            [
                'worker_id'  => null,
                'date_hired' => null,
            ]
        );

        $jobSeekerSubscription = $this->createJobSeekerSubscription(
            [
                'worker_id'   => $jobSeeker->id,
                'rate_id'     => $subscriptionRate->id,
                'duration'    => Carbon::now()->subMonths($subscriptionRate->month),
                'status'      => 'trial',
                'customer_id' => null,
            ]
        );

        (new JobSeekerSubscriptionManagementModule())->itemsSetStatusToExpire();

        $this->assertDatabaseHas(
            JobseekerSubscription::class,
            [
                'worker_id' => $jobSeeker->id,
                'rate_id'   => $subscriptionRate->id,
                'status'    => 'expired',
            ]
        );
    }
}
