<?php

namespace Tests\Unit\Customer\FeatureService;

use App\Feature;
use App\Services\FeatureService;
use Illuminate\Support\Str;
use Ramsey\Uuid\Uuid;
use Tests\TestCase;

class FeatureServiceTest extends TestCase
{
    /** @var FeatureService */
    public $service;
    public $data;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = app(FeatureService::class);
        $this->data = [
           "models" => factory(Feature::class,3)->create()->toArray(),
        ];
    }

    /**
     * @group customer
     */
    public function testGetMapArray(){
        $models = $this->service->getMapArray();
        $this->assertGreaterThanOrEqual(3,count($models));
    }
    /**
     * @group customer
     */
    public function testTranslationFeature(){
        $str = $this->data["models"][0]["id"]."&(".$this->data["models"][1]["id"]."|".$this->data["models"][2]["id"].")";
        $result = $this->service->translationFeature($str);
        $this->assertEquals(3,count($result));
        $this->assertEquals($this->data["models"][1]["type"],$result[1]["type"]);
        $this->assertEquals(false,$result[0]["strategyGroupStartSign"]);
        $this->assertEquals(true,$result[1]["strategyGroupStartSign"]);
        $this->assertEquals("并且",$result[1]["calculation"]);
        $this->assertEquals(true,$result[2]["strategyGroupEndSign"]);
        $this->assertEquals("或",$result[2]["calculation"]);
    }
    /**
     * @group customer
     */
    public function testAnalysisFeature(){
        $models = $this->data["models"];
        $params = [
            [
                "strategyGroupStartSign" => true,
                "calculation" => "",
                "type"=>$models[0]["type"],
                "logic"=>$models[0]["logic"],
                "describe"=>$models[0]["describe"],
                "strategyGroupEndSign" => false,
            ],[
                "strategyGroupStartSign" => false,
                "calculation" => "并且",
                "type"=>$models[1]["type"],
                "logic"=>$models[1]["logic"],
                "describe"=>$models[1]["describe"],
                "strategyGroupEndSign" => true,
            ],[
                "strategyGroupStartSign" => false,
                "calculation" => "或",
                "type"=>$models[2]["type"],
                "logic"=>$models[2]["logic"],
                "describe"=>$models[2]["describe"],
                "strategyGroupEndSign" => false,
            ]
        ];
        $expected = "(".$models[0]["id"]."&".$models[1]["id"].")|".$models[2]["id"];
        $result = $this->service->analysisFeature($params);
        $this->assertIsArray($result);
        $this->assertCount(2,$result);
        $this->assertArrayHasKey("feature",$result);
        $this->assertEquals($expected,$result["feature"]);
    }
    /**
     * @group customer
     */
    public function testFormatFeature(){
        $model1 = factory(Feature::class)->make([
            "id" => 1,
            "type"=>"商品名称",
            "logic"=>"包含",
            "describe"=>"衣服"
        ]);
        $model2 = factory(Feature::class)->make([
            "id" => 2,
            "type"=>"订单类型",
            "logic"=>"不包含",
            "describe"=>"创建"
        ]);
        $model3 = factory(Feature::class)->make([
            "id"=>3,
            "type"=>"承运商",
            "logic"=>"等于",
            "describe"=>"顺丰"
        ]);
        $features = [1=>$model1,2=>$model2,3=>$model3];
        $result = $this->service->formatFeature($features,"1&(2|3)");
        $expected = "商品名称 包含 衣服 并且 (订单类型 不包含 创建 或 承运商 等于 顺丰)";
        $this->assertEquals($expected,$result);
        $columnMapping = ["商品名称"=>"commodity_name","订单类型"=>"order_type","承运商"=>"logistic_name"];
        $result = $this->service->formatFeature($features,"1&(2|3)",$columnMapping);
        $expected = "commodity_name like '%衣服%' and (order_type not like '%创建%' or logistic_name = '顺丰')";
        $this->assertEquals($expected,$result);
    }
    /**
     * @group customer
     */
    public function testMatchFeature(){
        $model1 = factory(Feature::class)->create([
            "type" => "商品名称",
            "logic"=>"包含",
            "describe"=>Uuid::uuid1(),
        ]);
        $model2 = factory(Feature::class)->create([
            "type" => "订单类型",
            "logic"=>"不包含",
            "describe"=>Uuid::uuid1(),
        ]);
        $model3 = factory(Feature::class)->create([
            "type" => "店铺类型",
            "logic"=>"等于",
            "describe"=>Uuid::uuid1(),
        ]);
        $this->data["models"][] = $model1->toArray();
        $this->data["models"][] = $model2->toArray();
        $this->data["models"][] = $model3->toArray();

        $columnMapping = ["商品名称"=>"commodity","订单类型"=>"order","店铺类型"=>"shop"];
        $matchObject = ["commodity"=>Str::random(2).$model1->describe,"order"=>$model1->describe,"shop"=>$model3->describe];
        $value = $model1->id."&(".$model2->id."&".$model3->id.")";
        $result = $this->service->matchFeature($value,$columnMapping,$matchObject);
        $this->assertEquals(true,$result);

        $columnMapping = ["商品名称"=>"commodity","订单类型"=>"order","店铺类型"=>"shop","packages"=>"ps"];
        $matchObject = ["ps"=>[["a"=>1,"commodity"=>Str::random(2).$model1->describe]],"order"=>$model1->describe,"shop"=>$model3->describe];
        $value = $model1->id."&(".$model2->id."&".$model3->id.")";
        $result = $this->service->matchFeature($value,$columnMapping,$matchObject,true);
        $this->assertEquals(true,$result);

        $matchObject = ["commodity"=>$model1->describe.Str::random(2),"order"=>$model2->describe.Str::random(2),"shop"=>"1"];
        $result = $this->service->matchFeature($value,$columnMapping,$matchObject);
        $this->assertEquals(false,$result);
    }

    public function tearDown(): void
    {
        Feature::destroy(array_column($this->data["models"],"id"));
        parent::tearDown();
    }
}
