<?php

namespace Tests\Services\ForeignHaiRoboticsService;

use App\Batch;
use App\MaterialBox;
use App\Order;
use App\OrderCommodity;
use App\Services\BatchService;
use App\Services\ForeignHaiRoboticsService;
use App\Services\StationService;
use App\Services\StationTaskBatchService;
use App\Station;
use App\StationRuleBatch;
use App\StationTask;
use App\StationTaskBatch;
use App\StationTaskCommodity;
use App\StationTaskMaterialBox;
use Tests\TestCase;
use App\Traits\TestMockSubServices;

class MarkBinProcessedTest extends TestCase
{
    use TestMockSubServices;

    /** @var ForeignHaiRoboticsService $service */
    public $service;
    private $data;
    private $batchAmount = 1;
    private $orderAmount = 2;
    private $orderCommodityAmount = 4;

    function setUp(): void
    {
        parent::setUp();
        $this->service = $this->subMock([
            'class' => ForeignHaiRoboticsService::class,
            'methods' => [
                'putBinToStore' => true,
            ],
            'subServices' => [
                [
                    'serviceName' => 'stationService',
                    'class' => StationService::class,
                    'methods' => [
                        'broadcastBinMonitor' => true,
                    ],
                ],
            ]
        ]);
        $this->data['batches']
            = factory(Batch::class, $this->batchAmount)
            ->create();
        $this->data['station_task_batches']
            = factory(StationTaskBatch::class)
            ->createMany($this->makeArray($this->batchAmount, [
                'batch_id' => function () {
                    return $this->getTargetFieldCirculately($this->data['batches']);
                }
            ]));
        $this->data['orders'] =
            factory(Order::class)
                ->createMany($this->makeArray($this->orderAmount, [
                    'batch_id' => function () {
                        return $this->getTargetFieldCirculately($this->data['batches']);
                    }
                ]));
        $this->data['orderCommodities'] =
            factory(OrderCommodity::class)
                ->createMany($this->makeArray($this->orderCommodityAmount, [
                    'order_id' => function () {
                        return $this->getTargetFieldCirculately($this->data['orders']);
                    }
                ]));
        $this->data['station_rule_batches']
            = factory(StationRuleBatch::class)
            ->createMany($this->makeArray($this->batchAmount, [
                'owner_id' => function () {
                    return $this->getTargetFieldCirculately($this->data['batches'], '', 'owner_id');
                }
            ]));
        $this->data['material_boxes']
            = factory(MaterialBox::class)
            ->createMany($this->makeArray($this->orderCommodityAmount, [
                'code' => function () {
                    return $this->getTargetFieldCirculately($this->data['orderCommodities'], MaterialBox::class, 'location');
                }
            ]));
        $this->data['station_task_material_boxes']
            = factory(StationTaskMaterialBox::class)
            ->createMany($this->makeArray($this->orderCommodityAmount, [
                'status' => '处理中',
                'material_box_id' => function () {
                    return $this->getTargetFieldCirculately($this->data['material_boxes']);
                },
                'station_task_batch_id' => function () {
                    return $this->getTargetFieldCirculately($this->data['station_task_batches']);
                }
            ]));
        $this->data['stationTaskCommodities'] =
            factory(StationTaskCommodity::class)
                ->createMany($this->makeArray($this->orderCommodityAmount, [
                    'status' => '处理中',
                    'material_box_id' => function () {
                        return $this->getTargetFieldCirculately($this->data['material_boxes']);
                    },
                    'station_task_batch_id' => function () {
                        return $this->getTargetFieldCirculately($this->data['station_task_batches'],StationTaskCommodity::class);
                    }
                ]));
    }

    public function testReturned()
    {
        foreach ($this->data['material_boxes'] as $box) {
            $this->service->markBinProcessed(
                '',
                $box['code'],
                true,
                '',
                '',
                true);
        }
        $this->assertEquals(
            ['完成'],
            array_unique(data_get(
                StationTaskMaterialBox::query()->whereIn('id', data_get($this->data['station_task_material_boxes'], '*.id'))->get(),
                '*.status'))
        );
        $this->assertEquals(
            ['完成'],
            array_unique(data_get(
                StationTaskCommodity::query()->whereIn('id', data_get($this->data['stationTaskCommodities'], '*.id'))->get()
                , '*.status'))
        );
    }

    function tearDown(): void
    {
        MaterialBox::query()
            ->whereIn('id', data_get($this->data['batches'], '*.stationTaskBatch.materialBoxes.*.id') ?? [])
            ->delete();
        StationTaskMaterialBox::query()
            ->whereIn('id', data_get($this->data['batches'], '*.stationTaskBatch.stationTaskMaterialBoxes.*.id') ?? [])
            ->delete();
        StationTaskCommodity::query()
            ->whereIn('id', data_get($this->data['batches'], '*.stationTaskBatch.stationTaskCommodities.*.id') ?? [])
            ->delete();
        StationTaskBatch::query()
            ->whereIn('id', data_get($this->data['batches'], '*.stationTaskBatch.id') ?? [])
            ->delete();
        StationTask::query()
            ->whereIn('id', data_get($this->data['batches'], '*.stationTaskBatch.stationTask.id') ?? [])
            ->delete();
        StationRuleBatch::query()
            ->whereIn('id', data_get($this->data['station_rule_batches'], '*.id') ?? [])
            ->delete();
        OrderCommodity::query()
            ->whereIn('id', data_get($this->data['orderCommodities'], '*.id') ?? [])
            ->delete();
        Order::query()
            ->whereIn('id', data_get($this->data['orders'], '*.id') ?? [])
            ->delete();
        Batch::query()
            ->whereIn('id', data_get($this->data['batches'], '*.id') ?? [])
            ->delete();
        parent::tearDown();
    }
}
