<?php namespace Eae\Backoffice\Generic\Fields;

use LaravelLocalization;
use Config;
use View;
use RequestContext;
use Input;
use Lang;
use WebsiteObject;
use Eae\Backoffice\Generic\ContentType;
use Eae\Support\Contracts\SavableFieldInterface;
use ContentTypes;

class LinkField extends BaseField implements SavableFieldInterface {
    
    protected $required = false;
    protected $objectTypes = array();
    protected $maxLabel = 0;
    
    public function __construct($config){
        unset($config["validation"]);
        unset($config["preValidation"]);
        unset($config["inList"]);
        unset($config["search"]);
        unset($config["sort"]);
        
        parent::__construct($config);
        
        if (!empty($config["required"])) {
            $this->required = $config["required"]; 
        }
        
        if (!empty($config["maxLabel"])) {
            $this->maxLabel = $config["maxLabel"]; 
        }
        
        if (!empty($config["objectTypes"])) {
            $this->setObjectTypes($config["objectTypes"]); 
        }
    }
    
    public function isRequired(){
        return $this->required;    
    }
    
    public function setRequired($required){
        $this->required = $required;
    }

    public function toForm($model, $enabled = true, $hidden = false){
        $html = "";
       
        $fieldName = $this->getName();
        $label = "";
        $isExternal = false;
        $enabled = true;
        $isExternal = false;
        $selectedObjectId = null;
        $linkUrl = "";
        $linkLabel = "";
        
        $websiteModel = new WebsiteObject(); 
        $relation = $websiteModel->related();

        $query = WebsiteObject::with("objectable")
            ->whereIn("object_type", $this->getObjectTypesModelsType());
        
        $objects = $query->get();
        
        $fullList = array();
        
        foreach($this->getContentTypes() as $contentType){
            $fullList[$contentType->getModelType()] = array(
                "label" => ucfirst($contentType->getLabel()),
                "list" => array());                         
        } 
        
        
        foreach($objects as $object){ 
            $fullList[$object->object_type]["list"][] = (object) array(
                "id" => $object->id,
                "title" => $object->objectable->title
            );                    
        }
        
        foreach($fullList as $listType){
            usort($listType["list"], function( $firstItem, $secondItem){
                if ($firstItem->title == $secondItem->title) {
                    return 0;
                } 
                
                return ($firstItem->title < $secondItem->title) ? -1 : 1;   
            });

        } 
        
        $postData = Input::old($this->getName());
       
        $errors = RequestContext::get("errors");
        $hasErrors = false;
        
        $html = "";
        if($this->isMultiLanguage()){
            $locales = LaravelLocalization::getSupportedLocales();
            $defaultLocale = LaravelLocalization::getDefaultLocale();
            
            foreach ($locales as $locale => $localeData) { 
                $hasErrors = false;
                $name = $fieldName . "[{$locale}]";
                $id = $fieldName . "_{$locale}";
                $errorKey = $fieldName . "." . $locale; 
                $isExternal = false;
                $selectedObjectId = null;
                $linkUrl = "";
                $linkLabel = "";
                
                if(!empty($errors) && !$errors->isEmpty()){
                    if ($errors->has("{$this->getName()}.{$locale}.label") || 
                        $errors->has("{$this->getName()}.{$locale}.url") ||
                        $errors->has("{$this->getName()}.{$locale}.selectedObjectId")) {
                            $hasErrors = true;    
                    }
                }
                
                if ($model->exists) {
                    $languageModel = $model->languages->findByLocale($locale);
                    
                    if(!empty($languageModel)){
                        $value = $languageModel->$fieldName;
                    }
                    
                    if (!empty($value)) {
                        $value = json_decode($value);
                        $linkLabel = $value->label;
                        $isExternal = $value->isExternal;
                        $linkUrl = $isExternal ? $value->url : null;
                        $selectedObjectId = !$isExternal ? $value->objectId : null;
                    }
                } else {
                    $isExternal = isset($postData[$locale]['isExternal']);
                }   
                            
                $html .= View::make(
                    "admin.generic.components.forms.link", 
                    array(
                        "id"            => $id,
                        "errorKey"      => $errorKey,
                        "hasErrors"     => $hasErrors,
                        "name"          => $name,
                        "label"         => $this->getLabel(),
                        "language"      => $locale,
                        "defaultLang"   => $defaultLocale,
                        "enabled"       => $enabled,
                        "parentHidden"  => ($hidden && !empty($this->parent)),
                        "parent"        => $this->parent,
                        "required"      => $this->isRequired(),
                        "maxLength"     => 50,
                        "fullList"      => $fullList,
                        "hide"          => ($hidden || $locale != $defaultLocale),
                        
                        "isExternal"    => $isExternal,
                        "linkLabel"     => $linkLabel,
                        "selectedObjectId"=> $selectedObjectId,
                        "linkUrl"       => $linkUrl,
                        "info"          => $this->getInfo() 
                    ));    
            }
        } else {
            if(!empty($errors) && !$errors->isEmpty()){
                if ($errors->has("{$this->getName()}.label") || 
                    $errors->has("{$this->getName()}.url") ||
                    $errors->has("{$this->getName()}.selectedObjectId")) {
                        $hasErrors = true;    
                }
            }
            
            if ($model->exists) {
                $value = $model->$fieldName;
                
                if (!empty($value)) {
                    $value = json_decode($value);
                    $linkLabel = $value->label;
                    $isExternal = $value->isExternal;
                    $linkUrl = $isExternal ? $value->url : null;
                    $selectedObjectId = !$isExternal ? $value->objectId : null;
                }
            }
            
            $html .= View::make(
                "admin.generic.components.forms.link", 
                array(
                    "id"            => $this->getName(),
                    "errorKey"      => $this->getName(),
                    "hasErrors"     => $hasErrors,
                    "name"          => $this->getName(),
                    "label"         => $this->getLabel(),
                    "isExternal"    => $isExternal,
                    "enabled"       => $enabled,
                    "parentHidden"  => ($hidden && !empty($this->parent)),
                    "parent"        => $this->parent, 
                    "required"      => $this->isRequired(),
                    "maxLength"     => 50,
                    "fullList"      => $fullList,
                    "isExternal"    => $isExternal,
                    "linkLabel"     => $linkLabel,
                    "selectedObjectId"=> $selectedObjectId,
                    "linkUrl"       => $linkUrl,
                    "info"          => $this->getInfo() 
                ));
        }
        
        return $html;
    }
    
    public function save($model, $values){
        $isExternal = isset($values['isExternal']) && $values['isExternal'] == 'true' ? true : false;
        $fieldStructure = array (
            'label'         => $values['label'],
            'isExternal'    => $isExternal,
            'url'           => $isExternal ? $values['url'] : null,
            'objectId'      => !$isExternal ? $values['selectedObjectId'] : null
        );
        $fieldName = $this->getName();
        $model->$fieldName = json_encode($fieldStructure);
    }
    
    public function getValidation($subField = null){
        $rules = "";
        if($this->isRequired()){
            $rules = "required|";    
        }
        switch ($subField) {
        case 'label':
            if ($this->maxLabel > 0) {
                $rules .= "max:{$this->maxLabel}";
            }
            break;
        case 'url':
            $rules .= "url";
            break;
        case 'selectedObjectId':
            $rules .= "integer";
            break;
        }
        return $rules;
    }
    
    public function getValidationData($copyAllLang = false){
        $validation = array(
            "rules" => array(), 
            "values" => "",
            "labels" => array());
        
        $fieldName = $this->getName();
        $fieldValue = Input::get($fieldName);
       
        if ($this->isMultiLanguage()) {
            foreach ($fieldValue as $lang => $langValue) {
                $fieldValue[$lang] = $langValue;
            }
        }
 
        if ($this->isMultiLanguage()) {
            $locales = LaravelLocalization::getSupportedLanguagesKeys();
            $defaultLocale = \Config::get('app.locale');
            
            if($copyAllLang){

                foreach($locales as $locale){
                    if($locale == $defaultLocale){
                        continue;
                    }  

                    if(empty($fieldValue[$locale])){
                        $fieldValue[$locale] = $fieldValue[$defaultLocale];        
                    }
                }
            }
            
            
            $labelRules = generateLangRules(
                array($fieldName => $this->getValidation('label')), 
                $locales,
                'label');
                
            $urlRules = array();
            foreach ($locales as $locale) {      
                if (isset($value[$locale]['isExternal']) == 'true') {
                    $urlRules[$fieldName . '.' . $locale . '.url'] = $this->getValidation('url');
                } else {
                    $urlRules[$fieldName . '.' . $locale . '.selectedObjectId'] = $this->getValidation('selectedObjectId');
                }
            } 
            $validation["rules"] = array_merge($labelRules, $urlRules);    
            
            $labelLabel = generateLangLabels(
                $fieldName, Lang::get('backend.link_label'), $locales, 'label');
            $urlLabel = generateLangLabels(
                $fieldName, Lang::get('backend.link_url'), $locales, 'url');
            $isExternalLabel = generateLangLabels(
                $fieldName, Lang::get('backend.link_object'), $locales, 'selectedObjectId');
            $validation["labels"] = array_merge($labelLabel, $urlLabel, $isExternalLabel); 
        } else {
            $validation["rules"][$fieldName . '.label'] = $this->getValidation('label');
            if (isset($value['isExternal']) == 'true') {
                $validation["rules"][$fieldName . '.url'] = $this->getValidation('url');
            } else {
                $validation["rules"][$fieldName . '.selectedObjectId'] = $this->getValidation('selectedObjectId');
            }
            $validation["labels"][$fieldName . '.label'] = Lang::get('backend.link_label');
            $validation["labels"][$fieldName . '.url'] = Lang::get('backend.link_url');
            $validation["labels"][$fieldName . '.selectedObjectId'] = Lang::get('backend.link_object');
        }
        
        $validation["values"][$fieldName] = $fieldValue;

        return $validation;    
    }
    
    public static function getScript(){
        return array("linkField" => 
            Config::get('path.backoffice.js_path') . '/view/generic/backend-link-field.js');
    }
    
    public function toArray(){
        $array = parent::toArray();
        $array["required"] = $this->required;
        return $array;  
    }
    
    public function getObjectTypesModelsType(){
        $modelsType = array();
        foreach($this->objectTypes as $objectType){
            $contentType = ContentTypes::find($objectType);
            $modelsType[] = $contentType->getModelType();       
        }
        return $modelsType;    
    }
    
    public function getContentTypes(){
        $contentTypes = array();
        foreach($this->objectTypes as $objectType){
            $contentType = ContentTypes::find($objectType);
            $contentTypes[] = $contentType;
        }
        return $contentTypes;    
    }
    
    public function setObjectTypes($objectTypes = array()){
        if(!empty($objectTypes)){
            $this->websiteFiltered = true;
        }
        
        $this->objectTypes = $objectTypes;
    }
    
    public function getObjectTypes () {
        return $this->objectTypes;
    }
}
  

