<?php

namespace Tests\Feature;

use App\Models\Company; 
use App\Models\CompanySubscriptionRates; 
use App\Models\CompanySubscriptions; 

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

use Carbon\Carbon;

use Tests\TestCase;

class CompanySubscriptionExpirationTest extends TestCase
{
    use RefreshDatabase; 

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

    /**
     * Create Company via factory
     * 
     * @return Company 
     */
    private function createCompany(): Company
    {
        return Company::factory()->create();
    }

    /**
     * Create Company Subscription Rate via factory
     * 
     * @return CompanySubscriptionRates 
     */
    private function createCompanySubscriptionRate(): CompanySubscriptionRates
    {
        return CompanySubscriptionRates::factory()->create();
    }

    /**
     * Create Company Subscription Rate via factory
     * 
     * @param array $factoryState
     * 
     * @return CompanySubscriptions 
     */
    private function createCompanySubscription(array $factoryState = []): CompanySubscriptions
    {
        return  CompanySubscriptions::factory()
            ->state($factoryState)
            ->create();
    }
    
    /**
     * Test Montly Expiration.
     * 
     * @return void 
     */
    public function test_expiration_monthly(): void
    {
        $company                   = $this->createCompany();
        $companySubscriptionRate   = $this->createCompanySubscriptionRate();

        $factoryState              =
        [
            "company_id"                =>  $company->id,
            "subscription_rate_id"      =>  $companySubscriptionRate->id,
            "mode_of_payment"           =>  "monthly",
            "is_monthly_expired"        =>  "false",
            "current_month_paid"        =>  Carbon::now()->subMonth()->format('Y-m-d')
        ]; 

        $companySubscription       =  $this->createCompanySubscription( factoryState : $factoryState);

        //* From ProcessCheckMontlySubscription Job
        $subscriptions = CompanySubscriptions::select(
                'id',
                'current_month_paid',
                'duration',
                'is_expired',
                'is_monthly_expired',
            )
            ->where('mode_of_payment', 'monthly')
            ->where('is_monthly_expired', 'false')
            ->where('current_month_paid', '<=', Carbon::now()->subDays(1)->format('Y-m-d'))
            ->limit(100)
            ->get();

        foreach ($subscriptions as $subscription) 
        {
            CompanySubscriptions::where('id', $subscription->id)
                ->update(
                    [
                        'is_monthly_expired' => 'true'
                    ]
                );
        }

        $companySubscription = CompanySubscriptions::findOrFail($companySubscription->id); 

        $this->assertTrue($companySubscription->is_monthly_expired == 'true', "Company Subscription Column is_monthly_expired is true"); 
    }

    /**
     * Test Yearly Expiration.
     * 
     * @return void 
     */
    public function test_expiration_duration(): void
    {
        $company                   = $this->createCompany();
        $companySubscriptionRate   = $this->createCompanySubscriptionRate();

        $factoryState              = 
        [
            "company_id"           => $company->id,
            "subscription_rate_id" => $companySubscriptionRate->id,
            "duration"             => Carbon::now()->subMonth(),
        ];

        $companySubscription       =  $this->createCompanySubscription(factoryState: $factoryState);

        //* From ProcessCompanySubscriptionChecking 
        $subscriptions = CompanySubscriptions::select(
                'id',
                'duration',
                'is_expired',
            )
            ->where('duration', '<=', Carbon::now()->subDays(1)->format('Y-m-d'))
            ->where('is_expired', 'false')
            ->limit(100)
            ->get();

        foreach ($subscriptions as $subscription) 
        {
            CompanySubscriptions::where('id', $subscription->id)
                ->update(
                    [
                        'is_expired' => 'true'
                    ]
                );
        }

        $companySubscription = CompanySubscriptions::findOrFail($companySubscription->id);

        $this->assertTrue($companySubscription->is_expired == 'true', "Company Subscription Column is_expired is true"); 
    }
}
