<?php

namespace App\Libs\Backoffice\Generic\Fields;

use App\Libs\Backoffice\Generic\ContentType;
use App\Libs\Contracts\Backoffice\DuplicatableField;
use App\Libs\Contracts\Backoffice\ExternalField;
use App\Libs\Exception\InvalidConfigurationException;
use App\Libs\Facades\ContentTypes;
use Illuminate\Support\Arr;

class SinglePickerField extends BaseField implements ExternalField, DuplicatableField
{
    protected $order = false;
    protected $objectType = false;
    protected $maxSize = false;
    protected $pivotTable = false;

    public function __construct($config)
    {
        unset($config["multiLanguage"]);
        unset($config["inList"]);
        unset($config["search"]);
        unset($config["sort"]);

        parent::__construct($config);

        $this->relationField = true;

        if (empty($config["objectType"])) {
            throw new InvalidConfigurationException("The {$this->name} configuration is missing the object type");
        }

        $this->objectType = $config["objectType"];

        if (!empty($config["pivotTable"])) {
            $this->pivotTable = $config["pivotTable"];
        }

        if (!empty($config["order"])) {
            $this->order = $config["order"];
        }

        if (!empty($config["maxSize"])) {
            $this->maxSize = $config["maxSize"];
        }
    }

    public function isOrderable()
    {
        return $this->order;
    }

    public function setOrderable($order)
    {
        $this->order = $order;
    }

    public function getPivotTable()
    {
        return $this->pivotTable;
    }

    public function setPivotTable($tableName)
    {
        $this->pivotTable = $tableName;
    }

    public function getObjectType()
    {
        return $this->objectType;
    }

    public function getContentType()
    {
        return ContentTypes::find($this->objectType);
    }

    public function setObjectType($objectType)
    {
        $this->objectType = $objectType;
    }

    public function getMaxSize()
    {
        return $this->maxSize;
    }

    public function setMaxSize($maxSize)
    {
        $this->maxSize = $maxSize;
    }

    public function toForm($model, $enabled = true, $hidden = false)
    {
        if (!$model->exists) {
            return "";
        }

        $relationName = $this->getName();
        $relation = $model->$relationName();

        $contentType = $this->getContentType();
        $relationModelType = $contentType->getModelType();

        $relationModel = new $relationModelType;

        $languageRelationship = $relationModel->languages();
        $languageModel = $languageRelationship->getRelated();
        $websiteRelationship = $relationModel->websites();

        $websiteObjectModel = $websiteRelationship->getRelated();

        $query = $relationModel->full();
        if (!$this->pivotTable) {
            $query->where($relation->getQualifiedForeignKeyName(), $model->getKey());
        } else {
            $query->join($relation->getTable(), $relationModel->getTable().'.'.$relation->getRelatedKeyName(), '=',
                $relation->getQualifiedRelatedPivotKeyName());
            $query->where($relation->getQualifiedForeignPivotKeyName(), $model->getKey());
        }

        if ($this->isOrderable()) {
            $query->orderBy("{$websiteObjectModel->getTable()}.position", "asc");
        } else {
            $query->orderBy("{$languageModel->getTable()}.title", "asc");
        }

        if (!$this->pivotTable) {
            $query->selectRaw("{$relationModel->getTable()}.{$relationModel->getKeyName()}, {$languageModel->getTable()}.title, {$websiteObjectModel->getTable()}.website_object_id");
        } else {
            $query->selectRaw("{$relationModel->getTable()}.{$relationModel->getKeyName()}, {$languageModel->getTable()}.title, {$websiteObjectModel->getTable()}.website_object_id");
        }
        $list = $query->get();

        return view(
            "admin.generic.components.forms.singlepicker",
            array(
                "id" => $this->getName(),
                "name" => $this->getName(),
                "label" => $this->getLabel(),
                "order" => $this->isOrderable(),
                "maxSize" => $this->getMaxSize(),
                "list" => $list,
                "hide" => $hidden,
                "enabled" => $enabled,
                "childContentType" => $contentType,
                "parentId" => $model->getKey(),
                "parent" => $this->getParent(),
                "info" => $this->getInfo(),
                "parentContentType" => ($this->pivotTable ? $model->content_type : false),
                "blocksMode" => $this->blocksMode,
            ));

    }


    public function getValidationData($copyAllLang = false)
    {
        return null;
    }

    public function save($model, $values)
    {
        /*   if($this->isWebsiteFiltered()){
               return $this->_saveWebsite($model, $values);
           }else{*/
        return $this->_saveNoWebsite($model, $values);
        //   }
    }

    protected function _saveNoWebsite($model, $values)
    {
        $relationName = $this->getName();
        $relation = $model->$relationName();

        $ids = Arr::flatten($values);

        if ($this->isOrderable()) {
            $syncData = array();
            $position = 1;
            foreach ($ids as $id) {
                $syncData[$id] = array("position" => $position);
                $position = $position + 1;
            }

            $model->$relationName()->sync($syncData);
        } else {
            $model->$relationName()->sync($ids);
        }
    }

    protected function _saveWebsite($model, $values)
    {
        if (empty($this->objectTypes)) {
            return;
        }

        $type = $this->getName();
        $websiteObject = $model->getActiveWebsiteEntry();
        $relation = $websiteObject->related();

        $ids = Arr::flatten($values);

        if ($this->isOrderable()) {
            $syncData = array();
            $position = 1;
            foreach ($ids as $id) {
                $syncData[$id] = array("position" => $position, "type" => $type);
                $position = $position + 1;
            }
            $relation->wherePivot("type", $type)->sync($syncData);
        } else {
            $syncData = array();
            foreach ($ids as $id) {
                $syncData[$id] = array("type" => $type);
            }
            $relation->wherePivot("type", $type)->sync($syncData);
        }
    }

    public static function getScript()
    {
        return array(
            "singlePicker" => path_asset('path.backoffice.js_path').'/view/backend-single-picker.js'
        );

    }

    public function duplicate($sourceModel, $model)
    {
        $relationName = $this->getName();

        $items = $sourceModel->$relationName()->full()->orderBy('website_objects.position')->get();
        $contentType = ContentTypes::find($this->objectType);
        $relation = $model->$relationName();
        $pivotSync = [];

        $i = 1;
        foreach ($items as $item) {
            if (!$this->pivotTable) {
                $itemCopy = ContentType::duplicateContent(
                    $contentType, $item,
                    'published',
                    [
                        $relation->getForeignKeyName() => $model->id,
                    ]);
            } else {
                $itemCopy = ContentType::duplicateContent($contentType, $item, 'published', [], [], $i);
                $pivotSync[] = $itemCopy->id;
            }
            $i++;
        }

        if ($this->pivotTable) {
            $relation->sync($pivotSync);
        }
    }
}


