<?php

namespace App\Libs\Backoffice\Generic\Fields;

use App\Libs\Contracts\Backoffice\DuplicatableField;
use App\Libs\Contracts\Backoffice\ListableField;
use App\Libs\Contracts\Backoffice\VersionableField;
use App\Libs\Exception\InvalidConfigurationException;
use App\Libs\Facades\Localization;
use Illuminate\Database\Eloquent\Builder;
use App\Models\WebsiteObject;

class DatePickerField extends BaseField implements ListableField, VersionableField, DuplicatableField
{
    protected $allowedInputTypes = array("datetime", "date", "time");
    protected $inputType = "datetime";
    protected $woMultilang = false;
    protected $convertToLocalTimezone = false;

    public function __construct($config)
    {
        parent::__construct($config);

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

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

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

    public function getInputType()
    {
        return $this->inputType;
    }

    public function setInputType($inputType = "datetime")
    {
        if (!in_array($inputType, $this->allowedInputTypes)) {
            throw new InvalidConfigurationException("The field {$this->getName()} has an invalid inputType. Allowed values are datetime, date or time");
        }

        $this->inputType = $inputType;
    }

    protected function _getIcon()
    {
        switch ($this->getInputType()) {
            case "datetime":
            case "date":
                return "glyphicon-calendar";
            case "time":
                return "glyphicon-time";
            default:
                return "glyphicon-calendar";
        }
    }

    public function buildSelect(Builder $query)
    {
        if ($this->isMultiLanguage()) {
            $tablePrefix = $query->getModel()->languages()->getRelated()->getTable();
        } else {
            $tablePrefix = $query->getModel()->getTable();
        }

        $query->addSelect("{$tablePrefix}.{$this->name}");
        return $query;
    }

    public function buildWhere(Builder $query, $searchPhrase)
    {
        if (empty($searchPhrase) || !$this->isSearchable()) {
            return $query;
        }

        if ($this->isMultiLanguage()) {
            $tablePrefix = $query->getModel()->languages()->getRelated()->getTable();
        } else {
            $tablePrefix = $query->getModel()->getTable();
        }

        $query->orWhere("{$tablePrefix}.{$this->name}", 'like', "%{$searchPhrase}%");
        return $query;
    }

    public function buildOrder(Builder $query, $sortOrder = "asc")
    {
        if ($this->isMultiLanguage()) {
            $tablePrefix = $query->getModel()->languages()->getRelated()->getTable();
        } else {
            $tablePrefix = $query->getModel()->getTable();
        }

        $query->orderBy("{$tablePrefix}.{$this->getName()}", $sortOrder);
        return $query;
    }

    public function toArray()
    {
        $array = parent::toArray();
        $array["inputType"] = $this->inputType;
        return $array;
    }

    public function toGridHeader()
    {
        return '<th data-column-id="'.$this->getName().'">'.ucfirst($this->getLabel()).'</th>';
    }

    public function toForm($model, $enabled = true, $hidden = false)
    {
        $html = "";
        $defaultLang = Localization::getDefaultLocale();
        if ($this->isMultiLanguage()) {
            $languages = Localization::getSupportedLanguages();

            foreach ($languages as $language) {
                $fieldName = $this->getName();
                $name = $fieldName."[{$language->id}]";
                $id = $fieldName."_{$language->id}";
                $errorKey = $fieldName.".".$language->id;
                $value = null;

                if ($model->exists) {
                    if ($this->woMultilang) {
                        $wo = WebsiteObject::find($model->website_object_id);
                        $languageModel = $wo->languages->findByLocale($language->id);
                    } else {
                        $languageModel = $model->languages->findByLocale($language->id);
                    }
                    if (!empty($languageModel)) {
                        $value = $languageModel->$fieldName;
                    }
                }

                $html .= view(
                    "admin.generic.components.forms.datepicker",
                    array(
                        "id" => $id,
                        "errorKey" => $errorKey,
                        "name" => $name,
                        "fieldName" => $fieldName,
                        "label" => $this->getLabel(),
                        "value" => $value,
                        "inputType" => $this->getInputType(),
                        "icon" => $this->_getIcon(),
                        "language" => $language->id,
                        "languages" => $languages,
                        "defaultLang" => $defaultLang,
                        "hide" => ($hidden || $language->id != $defaultLang),
                        "enabled" => $enabled,
                        "parentHidden" => ($hidden && !empty($this->parent)),
                        "parent" => $this->parent,
                        "info" => $this->getInfo(),
                        "blocksMode" => $this->blocksMode,
                        "convertToLocalTimezone" => $this->convertToLocalTimezone
                    ));
            }
        } else {
            $fieldName = $this->getName();
            $value = null;

            if ($model->exists) {
                $value = $model->$fieldName;
            }

            $html .= view(
                "admin.generic.components.forms.datepicker",
                array(
                    "id" => $this->getName(),
                    "errorKey" => $this->getName(),
                    "name" => $this->getName(),
                    "fieldName" => $this->getName(),
                    "label" => $this->getLabel(),
                    "value" => $value,
                    "inputType" => $this->getInputType(),
                    "icon" => $this->_getIcon(),
                    "hide" => $hidden,
                    "enabled" => $enabled,
                    "parentHidden" => ($hidden && !empty($this->parent)),
                    "parent" => $this->parent,
                    "info" => $this->getInfo(),
                    "blocksMode" => $this->blocksMode,
                    "convertToLocalTimezone" => $this->convertToLocalTimezone
                ));
        }

        return $html;
    }

    public function getValidation()
    {
        $validation = parent::getValidation();

        switch ($this->getInputType()) {
            case "datetime":
                $rule = "date_format:Y-m-d H:i:s";
                break;
            case "date":
                $rule = "date_format:Y-m-d";
                break;
            case "time":
                $rule = "date_format:H:i";
                break;

        }

        if (empty($validation)) {
            return $rule;
        } else {
            return $validation."|".$rule;
        }

    }
}


