<?php

declare(strict_types=1);

namespace Akeneo\Test\Common\Structure\Attribute;

use Akeneo\Channel\Infrastructure\Component\Model\Locale;
use Akeneo\Channel\Infrastructure\Component\Model\LocaleInterface;
use Akeneo\Test\Common\EntityWithValue\Code;
use Akeneo\Pim\Structure\Component\Model;
use Akeneo\Pim\Structure\Component\AttributeTypes;

/**
 * @Todo This builder should be improved. For now, you can use to create a identifier attribute with a code
 *
 * @author    Arnaud Langlade <arnaud.langlade@akeneo.com>
 * @copyright 2017 Akeneo SAS (http://www.akeneo.com)
 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class Builder
{
    /** @var string */
    private $code;

    /** @var string */
    private $type;

    /** @var string */
    private $groupCode;

    /** @var bool */
    private $isUnique;

    /** @var bool */
    private $localizable;

    /** @var LocaleInterface[]  */
    private $availableLocales = [];

    /** @var bool */
    private $scopable;

    /** @var string */
    private $backendType;

    /** @var string[] */
    private array $guidelines = [];

    public function __construct()
    {
        $this->code = Code::fromString('code');
        $this->type = new Type(AttributeTypes::IDENTIFIER);
        $this->isUnique = false;
        $this->localizable = false;
        $this->specificlocalizable = false;
        $this->scopable = false;
        $this->backendType = AttributeTypes::BACKEND_TYPE_TEXT;
    }

    /**
     * @return Model\Attribute
     */
    public function build(): Model\Attribute
    {
        $attribute = new Model\Attribute();
        $attribute->setCode((string) $this->code);
        $attribute->setType((string) $this->type);
        $attribute->setUnique($this->isUnique);
        $attribute->setScopable($this->scopable);
        $attribute->setLocalizable($this->localizable);
        foreach ($this->availableLocales as $availableLocale) {
            $attribute->addAvailableLocale($availableLocale);
        }
        $attribute->setDecimalsAllowed(false);
        $attribute->setBackendType($this->backendType);
        if (null !== $this->groupCode) {
            $group = new Model\AttributeGroup();
            $group->setCode($this->groupCode);
            $attribute->setGroup($group);
        }
        foreach ($this->guidelines as $localeCode => $localeGuidelines) {
            $attribute->addGuidelines($localeCode, $localeGuidelines);
        }

        return $attribute;
    }

    /**
     * @param string $code
     *
     * @return Builder
     */
    public function withCode(string $code): Builder
    {
        $this->code = $code;

        return $this;
    }

    public function withType(string $type): Builder
    {
        $this->type = $type;

        return $this;
    }

    public function withGroupCode(string $groupCode): Builder
    {
        $this->groupCode = $groupCode;

        return $this;
    }

    public function aTextAttribute(): Builder
    {
        $this->type = new Type(AttributeTypes::TEXT);
        $this->backendType = AttributeTypes::BACKEND_TYPE_TEXT;

        return $this;
    }

    public function aPriceCollectionAttribute(): Builder
    {
        $this->type = new Type(AttributeTypes::PRICE_COLLECTION);
        $this->backendType = AttributeTypes::BACKEND_TYPE_PRICE;

        return $this;
    }

    public function aUniqueAttribute(): Builder
    {
        $this->type = new Type(AttributeTypes::TEXT);
        $this->isUnique = true;
        $this->localizable = false;
        $this->scopable = false;
        $this->isUnique = true;
        $this->backendType = AttributeTypes::BACKEND_TYPE_TEXT;

        return $this;
    }

    /**
     * @return Builder
     */
    public function aIdentifier(): Builder
    {
        $this->type = new Type(AttributeTypes::IDENTIFIER);
        $this->localizable = false;
        $this->scopable = false;
        $this->isUnique = true;
        $this->backendType = AttributeTypes::BACKEND_TYPE_TEXT;
        $this->guidelines = ['en_US' => 'guidelines'];

        return $this;
    }

    public function localizable(): Builder
    {
        $this->localizable = true;

        return $this;
    }

    public function localeSpecific(array $locales): Builder
    {
        $this->availableLocales = $locales;

        return $this;
    }

    public function scopable(): Builder
    {
        $this->scopable = true;

        return $this;
    }
}
