<?php

use App\Http\Controllers\GadaiController;
use App\Services\Reports\KawalanStokService;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;

class KawalanStokServiceTest extends TestCase
{
    private $kodCawangan = 'kb2';
    private $startDate = '2023-03-23';
    private $endDate = '2023-03-23';
    /**
     * A basic test example.
     *
     * @return void
     */
    public function test_have_errors()
    {
        $request = new Request;
        $request->startDate = $this->startDate;
        $request->endDate = $this->endDate;
        $ringkasanHarianService = new KawalanStokService($this->kodCawangan, $request);

        $this->expectNotToPerformAssertions();
        return $ringkasanHarianService->getLaporanCawangan();

    }

    public function test_how_many_seconds_both_methods_takes_to_complete()
    {
        $day1 = '2023-03-20';
        $day2 = '2023-03-21';

        $function_execute_from_service = function () use ($day1, $day2) {
            $request = new Request;
            $request->startDate = $this->startDate;
            $request->endDate = $this->startDate;
            $ringkasanHarianService = new KawalanStokService($this->kodCawangan, $request);

            $this->expectNotToPerformAssertions();
            return $ringkasanHarianService->getLaporanCawangan();
        };

        $function_execute_from_originated = function () {
            (new GadaiController())->getLaporanKawalanStok($this->kodCawangan, $this->startDate);
        };

        $this->calculate_function_execution_time($function_execute_from_service, 'service');
        $this->calculate_function_execution_time($function_execute_from_originated, 'originated');

    }

    public function test_both_method_produces_the_same_output()
    {

        $function_execute_from_service = function () {
            $request = new Request;
            $request->startDate = $this->startDate;
            $request->endDate = $this->startDate;
            $ringkasanHarianService = new KawalanStokService($this->kodCawangan, $request);

            return $ringkasanHarianService->getLaporanCawangan();
        };

        $function_execute_from_originated = function () {
            return (new GadaiController())->getLaporanKawalanStok($this->kodCawangan, $this->startDate);
        };

        $outputOriginated = $function_execute_from_originated();
        $outputService = $function_execute_from_service();

        $this->assertEquals($outputOriginated, $outputService);
    }

    private function calculate_function_execution_time($test_function, $context)
    {

        sleep(2);

        $startTime = hrtime(true);

        $output = $test_function();

        $endTime = hrtime(true);

        $eta = $endTime - $startTime;
        // convert nanoseconds to milliseconds
        $eta /= 1e+6;
        dump("Code block from $context was running for $eta milliseconds");

        return $output;

    }

    public function test_both_method_produces_the_same_output_with_multiple_inputs()
    {

        // Example usage to generate 50 random dates and store them in an array
        $randomDatesArray = [];

        for ($i = 0; $i < 50; $i++) {
            $maxDate = '2023-09-31'; // Adjust the maximum date as needed
            $randomDatesArray[] = $this->generateRandomDate($maxDate)->toDateString();
        }


        foreach ($randomDatesArray as $testDate) {
            $function_execute_from_service = function () use ($testDate) {
                $request = new Request;
                $request->startDate = $testDate;
                $request->endDate = $testDate;
                $ringkasanHarianService = new KawalanStokService($this->kodCawangan, $request);

                return $ringkasanHarianService->getLaporanCawangan();
            };

            $function_execute_from_originated = function () use ($testDate) {
                return (new GadaiController())->getLaporanKawalanStok($this->kodCawangan, $testDate);
            };

            $outputOriginated = json_decode($function_execute_from_originated()->content());
            $outputService = json_decode($function_execute_from_service()->content());


            dump($testDate . ': Done test');
            $this->assertEquals($outputOriginated, $outputService);

        }

    }

    public function generateRandomDate($maxDate = null)
    {
        // Set a default range, for example, the last year
        $startDate = Carbon::now()->subYear();

        // If a maximum date is provided, use it; otherwise, use the current date
        $endDate = $maxDate ? Carbon::parse($maxDate) : Carbon::now();

        // Calculate the difference in seconds between start and end date
        $differenceInSeconds = $endDate->diffInSeconds($startDate);

        // Generate a random number of seconds within the difference
        $randomSeconds = mt_rand(0, $differenceInSeconds);

        // Add the random number of seconds to the start date
        $randomDate = $startDate->copy()->addSeconds($randomSeconds);

        return $randomDate;
    }

}
