<?php

namespace common\modules\blog\forms;

use common\modules\blog\entities\BlogCategory;
use common\modules\blog\entities\BlogPost;
use core\forms\CompositeForm;
use core\forms\MetaForm;
use core\validators\SlugValidator;
use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper;
use yii\web\UploadedFile;
use Yii;

/**
 * @property MetaForm $meta
 * @property BlogTagForm $tags
 */
class BlogPostForm extends CompositeForm
{
	public $type;

    public $category_id;
    public $title;
    public $description;
    public $content;
    public $image;
    public $video;
    public $published_at;
    public $slug;
    public $reset_image;
    public $status;

	public $_post;

    public function __construct(BlogPost $post = null, $config = [])
    {
        if ($post) {
            $this->category_id = $post->category_id;
            $this->title = $post->title;
            $this->description = $post->description;
            $this->content = $post->content;
            $this->video = $post->video;
            $this->published_at = $post->published_at;
            $this->slug = $post->slug;
            $this->meta = new MetaForm($post->meta);
            $this->tags = new BlogTagForm($post);
            $this->status = $post->status;
            $this->_post = $post;
        } else {
            $this->meta = new MetaForm();
            $this->tags = new BlogTagForm();
            $this->status = 0;
        }
        parent::__construct($config);
    }

    public function rules(): array
    {
        return [
            [['category_id', 'title'], 'required'],
            [['title', 'video'], 'string', 'max' => 255],
            [['category_id', 'status'], 'integer'],
            [['description', 'content'], 'string'],
            [['image'], 'image'],
	        ['reset_image', 'boolean'],
	        ['published_at', 'safe'],
	        ['slug', SlugValidator::class],
	        //[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : null],
	        //[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : ['type' => BlogPost::TYPE_PUBLIC]],
	        //[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['AND', ['<>', 'id', $this->_post->id], ['type' => BlogPost::TYPE_PUBLIC]] : ['type' => BlogPost::TYPE_PUBLIC]],
	        [['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => function (ActiveQuery $query) {
        	    if ($this->type != BlogPost::TYPE_PUBLIC) {
		            $query->andWhere($this->type . '=' . BlogPost::TYPE_PUBLIC);
	            }

        	    $query->andWhere(['type' => BlogPost::TYPE_PUBLIC]);
        	    if ($this->_post) {
        	    	$query->andWhere(['<>', 'id', $this->_post->id]);
	            }
	            return $query;
	        }],
        ];
    }

    public function attributeLabels()
    {
	    return [
		    'id' => Yii::t('blog', 'ID'),
		    'category_id' => Yii::t('blog', 'Category'),
		    'published_at' => Yii::t('blog', 'Published At'),
		    'created_at' => Yii::t('blog', 'Created At'),
		    'updated_at' => Yii::t('blog', 'Updated At'),
		    'title' => Yii::t('blog', 'Title'),
		    'description' => Yii::t('blog', 'Description'),
		    'content' => Yii::t('blog', 'Content'),
		    'image' => Yii::t('blog', 'Image'),
		    'video' => Yii::t('blog', 'Video'),
		    'status' => Yii::t('blog', 'Status'),
		    'meta_json' => Yii::t('blog', 'Meta Json'),
		    'comments_count' => Yii::t('blog', 'Comments Count'),
		    'views' => Yii::t('blog', 'Views'),
		    'slug' => Yii::t('blog', 'Slug'),
		    'reset_image' => Yii::t('blog', 'Reset Image'),
	    ];
    }

    public function attributeHints() {
	    return [
		    'published_at' => Yii::t('blog', 'The article will be published after the specified date if its status is not a draft'),
		    'slug' => Yii::t('pages', 'SEO link will be generated automatically if not specified'),
	    ];
    }

	public function categoriesList(): array
    {
        return ArrayHelper::map(BlogCategory::find()->orderBy('sort')->asArray()->all(), 'id', 'name');
    }

    protected function internalForms(): array
    {
        return ['meta', 'tags'];
    }

    public function beforeValidate(): bool
    {
        if (parent::beforeValidate()) {
	        $this->image = UploadedFile::getInstance($this, 'image');
            $this->published_at = strtotime($this->published_at);
            return true;
        }
        return false;
    }
}