<?php

namespace NewOrderCountingRecordService;

use App\Order;
use App\OrderCountingRecord;
use App\Owner;
use App\Services\NewOrderCountingRecordService;
use App\User;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Arr;
use Tests\TestCase;

class TransfersToConditionsTest extends TestCase
{
    protected $newOrderCountingRecordService;
    protected $data;

    protected function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
        cache()->flush();
        $this->newOrderCountingRecordService = new NewOrderCountingRecordService();
        $user = User::query()->where('name', 'yang')->first();
        $this->actingAs($user);
        $this->data['dates'] = [
            'right'=>[
                ['startAt'=>Carbon::now()->subDays(2),'endAt'=>Carbon::now()->addDays(2)],
                ['startAt'=>Carbon::now()->subYears(1),'endAt'=>Carbon::now()->addYears(1)],
            ],
            'wrong'=>[
                ['startAt'=>Carbon::now()->addDays(2),'endAt'=>Carbon::now()->subDays(2)],
                ['startAt'=>Carbon::now()->addYears(1),'endAt'=>Carbon::now()->subYears(1)],
            ]
        ];
        $this->data['units'] = ['year'=>'年','month'=>'月','week'=>'周','day'=>'日'];
        $this->data['owners']=factory(Owner::class)->times(2)->create();
    }

    protected function tearDown(): void
    {
        cache()->flush();
        Owner::destroy(data_get($this->data['owners'],'*.id'));
        parent::tearDown(); // TODO: Change the autogenerated stub
    }

    public function test_transfersToConditions_format()
    {
        foreach($this->data['units'] as $unit){
            foreach($this->data['dates']['right'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $this->assertIsArray($result);
            }
            foreach($this->data['dates']['wrong'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $this->assertIsArray($result);
            }
        }
    }
    public function test_transfersToConditions_ifEmpty()
    {
        foreach($this->data['units'] as $unit){
            foreach($this->data['dates']['right'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $this->assertNotEmpty($result);
            }
            foreach($this->data['dates']['wrong'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $this->assertEmpty($result['data']);
                $this->assertNotEmpty($result['unit']);
            }
        }
    }

    public function test_transfersToConditions_ifDatesMatches()
    {
        foreach($this->data['units'] as $unit){
            foreach($this->data['dates']['right'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $datesExpected=[];
                switch ($unit){
                    case '年': $datesExpected=collect($date['startAt']->yearsUntil($date['endAt'], 1)->toArray())
                        ->map(function(Carbon $date){
                            return $date->firstOfYear();
                        })->toArray();
                        break;
                    case '月': $datesExpected=collect($date['startAt']->monthsUntil($date['endAt'], 1)->toArray())
                        ->map(function(Carbon $date){
                            return $date->firstOfMonth();
                        })->toArray();break;
                    case '日': $datesExpected=collect($date['startAt']->daysUntil($date['endAt'], 1)->toArray())
                        ->map(function(Carbon $date){
                            return $date->startOfDay();
                        })->toArray();break;
                }
                $datesExpected=array_map(function($date){
                    return $date->toDateString();
                },$datesExpected);
                $actualDays = array_keys($result['data']);
                $this->assertEquals($datesExpected, $actualDays);
            }
        }
    }

    public function test_transfersToConditions_ifOwnerIdMatches()
    {
        foreach($this->data['units'] as $unit){
            foreach($this->data['dates']['right'] as $date){
                $result=$this->newOrderCountingRecordService->transfersToCondition($date['startAt'],$date['endAt'],$unit,data_get($this->data['owners'],'*.id'));
                $ownerIdsExpected=data_get($this->data['owners'],'*.id');
                $isMatch=true;
                foreach($result['data'] as $date=>$ownerIds){
                    if(json_encode($ownerIdsExpected)!=json_encode($ownerIds)){
                        $isMatch=false; break;
                    }
                }
                $this->assertTrue($isMatch);
            }
        }
    }

}
