<?php

namespace CCDN\Helpers\Entities;

use CCDN\Helpers\Exception\CCDNRuntimeException;
use JsonSerializable;

/**
 * Class Config
 *
 * @property-read string|null $api_key
 * @property-read string|null $status_api_key
 *
 * @property-read string|null $kinopoisk_id_field
 * @property-read string|null $imdb_id_field
 * @property-read string|null $world_art_id_field
 * @property-read string|null $embed_field
 * @property-read string|null $upload_posters
 * @property-read string|null $set_all_date
 *
 * @property-read string|null $button_group_permission
 * @property-read string|null $video_quality_field
 * @property-read string|null $video_voice_field
 * @property-read string|null $video_first_voice_field
 * @property-read string|null $video_voice_priority - json
 * @property-read string|null $video_voices_disabled - json
 * @property-read string|null $post_status_field
 * @property-read string|null $episode_count_field
 * @property-read string|null $ccdn_id_field
 * @property-read string|null $content_ads_filter
 * @property-read string|null $collaps_franchise_ads_status_field
 * @property-read string|null $trailer_field
 * @property-read string|null $season_franchise_status
 *
 * @property-read string|null $serial_episode_field
 * @property-read string|null $serial_episode_field_suffix
 * @property-read string|null $serial_season_field
 * @property-read string|null $serial_season_field_suffix
 * @property-read string|null $set_season_episode_to_embed
 * @property-read string|null $premier_format_date
 *
 * NEW FRANCHISE property
 *
 * @property-read string|null $new_franchise_name
 * @property-read string|null $new_franchise_approve
 * @property-read string|null $new_franchise_origin_name
 * @property-read string|null $new_franchise_year
 * @property-read string|null $new_franchise_rating_imdb
 * @property-read string|null $new_franchise_rating_kinopoisk
 * @property-read string|null $new_franchise_rating_world_art
 * @property-read string|null $new_franchise_download_poster
 * @property-read string|null $new_franchise_download_poster_url
 * @property-read string|null $new_franchise_download_poster_url_with_domain
 * @property-read string|null $new_franchise_poster
 * @property-read string|null $new_franchise_country
 * @property-read string|null $new_franchise_director
 * @property-read string|null $new_franchise_actors
 * @property-read string|null $new_franchise_age
 * @property-read string|null $new_franchise_genres
 * @property-read string|null $new_franchise_time
 * @property-read string|null $new_franchise_slogan
 * @property-read string|null $new_franchise_screenwriter
 * @property-read string|null $new_franchise_producer
 * @property-read string|null $new_franchise_operator
 * @property-read string|null $new_franchise_composer
 * @property-read string|null $new_franchise_design
 * @property-read string|null $new_franchise_editor
 * @property-read string|null $new_franchise_actors_dubbing
 * @property-read string|null $new_franchise_budget
 * @property-read string|null $new_franchise_fees_use
 * @property-read string|null $new_franchise_fees_rus
 * @property-read string|null $new_franchise_fees_world
 * @property-read string|null $new_franchise_rate_mpaa
 * @property-read string|null $new_franchise_trivia
 * @property-read string|null $new_franchise_description
 * @property-read string|null $new_franchise_short_desc
 * @property-read string|null $new_franchise_premier
 * @property-read string|null $new_franchise_premier_rus
 * @property-read string|null $new_franchise_trailer
 * @property-read string|null $new_franchise_search_year_in_cat
 * @property-read string|null $new_franchise_filed_description
 * @property-read string|null $category_bundle - json
 * @property-read string|null $type_bundle - json
 * @property-read string|null $country_bundle - json
 * @property-read string|null $serial_status_bundle - json
 *
 * @property-read string|null $new_franchise_update_title
 * @property-read string|null $new_franchise_add_season
 * @property-read string|null $new_franchise_season_format
 * @property-read string|null $new_franchise_add_episode
 * @property-read string|null $new_franchise_add_episode_inc
 * @property-read string|null $new_franchise_add_season_inc
 * @property-read string|null $new_franchise_episode_format
 * @property-read string|null $new_franchise_title_prefix
 * @property-read string|null $new_franchise_title_pattern
 * @property-read string|null $new_franchise_title_pattern_not_season
 * @property-read string|null $new_franchise_add_season_custom_filed
 * @property-read string|null $new_franchise_add_episode_custom_filed
 * @property-read string|null $new_franchise_franchise_type_film
 * @property-read string|null $new_franchise_franchise_type_cartoon
 * @property-read string|null $new_franchise_franchise_type_cartoon_series
 * @property-read string|null $new_franchise_franchise_type_series
 * @property-read string|null $new_franchise_franchise_type_tv_show
 * @property-read string|null $new_franchise_franchise_type_anime_film
 * @property-read string|null $new_franchise_franchise_type_anime_series
 *
 * @property-read string|null $new_franchise_update_title_two
 * @property-read string|null $new_franchise_add_season_two
 * @property-read string|null $new_franchise_season_format_two
 * @property-read string|null $new_franchise_add_episode_two
 * @property-read string|null $new_franchise_add_episode_inc_two
 * @property-read string|null $new_franchise_add_season_inc_two
 * @property-read string|null $new_franchise_episode_format_two
 * @property-read string|null $new_franchise_title_prefix_two
 * @property-read string|null $new_franchise_title_two_pattern
 * @property-read string|null $new_franchise_title_two_pattern_not_season
 * @property-read string|null $new_franchise_add_season_custom_filed_two
 * @property-read string|null $new_franchise_add_episode_custom_filed_two
 * @property-read string|null $new_franchise_franchise_type_film_two
 * @property-read string|null $new_franchise_franchise_type_cartoon_two
 * @property-read string|null $new_franchise_franchise_type_cartoon_series_two
 * @property-read string|null $new_franchise_franchise_type_series_two
 * @property-read string|null $new_franchise_franchise_type_tv_show_two
 * @property-read string|null $new_franchise_franchise_type_anime_film_two
 * @property-read string|null $new_franchise_franchise_type_anime_series_two
 *
 * @property-read string|null $new_franchise_update_title_alt
 * @property-read string|null $new_franchise_add_season_alt
 * @property-read string|null $new_franchise_season_format_alt
 * @property-read string|null $new_franchise_add_episode_alt
 * @property-read string|null $new_franchise_add_episode_inc_alt
 * @property-read string|null $new_franchise_add_season_inc_alt
 * @property-read string|null $new_franchise_episode_format_alt
 * @property-read string|null $new_franchise_title_prefix_alt
 * @property-read string|null $new_franchise_title_alt_pattern
 * @property-read string|null $new_franchise_title_alt_pattern_not_season
 * @property-read string|null $new_franchise_add_season_custom_filed_alt
 * @property-read string|null $new_franchise_add_episode_custom_filed_alt
 * @property-read string|null $new_franchise_franchise_type_film_alt
 * @property-read string|null $new_franchise_franchise_type_cartoon_alt
 * @property-read string|null $new_franchise_franchise_type_cartoon_series_alt
 * @property-read string|null $new_franchise_franchise_type_series_alt
 * @property-read string|null $new_franchise_franchise_type_tv_show_alt
 * @property-read string|null $new_franchise_franchise_type_anime_film_alt
 * @property-read string|null $new_franchise_franchise_type_anime_series_alt
 * @property-read string|null $new_franchise_franchise_type
 *
 * MODULE property
 *
 * @property-read string|null $module_update_serial
 * @property-read string|null $module_date_no_edit
 * @property-read string|null $update_post_by_quality
 * @property-read string|null $update_post_by_original_voice_acting
 * @property-read string|null $module_has_original_voice_acting_field
 *
 * @property-read string|null $module_update_title
 * @property-read string|null $module_add_season
 * @property-read string|null $module_season_format
 * @property-read string|null $module_add_episode
 * @property-read string|null $module_add_episode_inc
 * @property-read string|null $module_add_season_inc
 * @property-read string|null $module_episode_format
 * @property-read string|null $module_title_prefix
 * @property-read string|null $module_title_pattern
 * @property-read string|null $module_title_pattern_not_season
 * @property-read string|null $module_add_season_custom_filed
 * @property-read string|null $module_add_episode_custom_filed
 * @property-read string|null $module_franchise_type_film
 * @property-read string|null $module_franchise_type_cartoon
 * @property-read string|null $module_franchise_type_cartoon_series
 * @property-read string|null $module_franchise_type_series
 * @property-read string|null $module_franchise_type_tv_show
 * @property-read string|null $module_franchise_type_anime_film
 * @property-read string|null $module_franchise_type_anime_series
 *
 * @property-read string|null $module_update_title_two
 * @property-read string|null $module_add_season_two
 * @property-read string|null $module_season_format_two
 * @property-read string|null $module_add_episode_two
 * @property-read string|null $module_add_episode_inc_two
 * @property-read string|null $module_add_season_inc_two
 * @property-read string|null $module_episode_format_two
 * @property-read string|null $module_title_prefix_two
 * @property-read string|null $module_title_two_pattern
 * @property-read string|null $module_title_two_pattern_not_season
 * @property-read string|null $module_add_season_custom_filed_two
 * @property-read string|null $module_add_episode_custom_filed_two
 * @property-read string|null $module_franchise_type_film_two
 * @property-read string|null $module_franchise_type_cartoon_two
 * @property-read string|null $module_franchise_type_cartoon_series_two
 * @property-read string|null $module_franchise_type_series_two
 * @property-read string|null $module_franchise_type_tv_show_two
 * @property-read string|null $module_franchise_type_anime_film_two
 * @property-read string|null $module_franchise_type_anime_series_two
 *
 * @property-read string|null $module_update_title_alt
 * @property-read string|null $module_add_season_alt
 * @property-read string|null $module_season_format_alt
 * @property-read string|null $module_add_episode_alt
 * @property-read string|null $module_add_episode_inc_alt
 * @property-read string|null $module_add_season_inc_alt
 * @property-read string|null $module_episode_format_alt
 * @property-read string|null $module_title_prefix_alt
 * @property-read string|null $module_title_alt_pattern
 * @property-read string|null $module_title_alt_pattern_not_season
 * @property-read string|null $module_add_season_custom_filed_alt
 * @property-read string|null $module_add_episode_custom_filed_alt
 * @property-read string|null $module_franchise_type_film_alt
 * @property-read string|null $module_franchise_type_cartoon_alt
 * @property-read string|null $module_franchise_type_cartoon_series_alt
 * @property-read string|null $module_franchise_type_series_alt
 * @property-read string|null $module_franchise_type_tv_show_alt
 * @property-read string|null $module_franchise_type_anime_film_alt
 * @property-read string|null $module_franchise_type_anime_series_alt
 *
 * BUTTON property
 *
 * @property-read string|null $button_name
 * @property-read string|null $button_origin_name
 * @property-read string|null $button_download_poster
 * @property-read string|null $button_download_poster_url
 * @property-read string|null $button_year
 * @property-read string|null $button_rating_imdb
 * @property-read string|null $button_rating_kinopoisk
 * @property-read string|null $button_rating_world_art
 * @property-read string|null $button_poster
 * @property-read string|null $button_country
 * @property-read string|null $button_director
 * @property-read string|null $button_actors
 * @property-read string|null $button_age
 * @property-read string|null $button_slogan
 * @property-read string|null $button_screenwriter
 * @property-read string|null $button_producer
 * @property-read string|null $button_operator
 * @property-read string|null $button_composer
 * @property-read string|null $button_design
 * @property-read string|null $button_editor
 * @property-read string|null $button_actors_dubbing
 * @property-read string|null $button_budget
 * @property-read string|null $button_fees_rus
 * @property-read string|null $button_fees_world
 * @property-read string|null $button_rate_mpaa
 * @property-read string|null $button_fees_use
 * @property-read string|null $button_genres
 * @property-read string|null $button_time
 * @property-read string|null $button_description
 * @property-read string|null $button_short_desc
 * @property-read string|null $button_trivia
 * @property-read string|null $button_premier
 * @property-read string|null $button_premier_rus
 * @property-read string|null $button_trailer
 * @property-read string|null $button_set_category
 * @property-read string|null $button_custom_filed_description
 * @property-read string|null $button_franchise_type
 * @property-read string|null $button_download_poster_url_with_domain
 *
 * MODULE CALENDAR property
 *
 * @property-read string|null $module_calendar_serial_type_divided
 *
 * @property-read int|null $module_calendar_full_all_releases
 * @property-read int|null $module_calendar_full_sort_episodes
 * @property-read int|null $module_calendar_hide_released
 * @property-read string|null $module_calendar_full_date_format
 *
 * @property-read string|null $module_calendar_main_after_today
 * @property-read string|null $module_calendar_main_before_today
 * @property-read string|null $module_calendar_main_date_format
 * @property-read string|null $module_calendar_main_date_format_availability
 * @property-read string|null $module_calendar_main_sort
 *
 * COLLECTION property
 *
 * @property-read string|null $collection_field
 * @property-read string|null $collections_bundle - json
 *
 * FUTURE FRANCHISE property
 *
 * @property-read string|null $future_franchises_category
 * @property-read string|null $future_franchises_premier
 *
 *
 * @package CCDN\Helpers\Entities
 */
class Config implements JsonSerializable
{
    /**
     * @var array
     */
    private $config;

    public function __construct(array $config)
    {
        foreach ($config as $item) {
            if (empty($item['key']) || $item['value'] === '') {
                $this->config[$item['key']] = null;
                continue;
            }

            $this->config[$item['key']] = $item['value'];
        }
    }

    /**
     * @param  string  $name
     *
     * @return mixed|null
     */
    public function __get($name)
    {
        return isset($this->config[$name]) ? $this->config[$name] : null;
    }

    /**
     * @param  string  $name
     * @param  mixed  $value
     */
    public function __set($name, $value)
    {
        throw new CCDNRuntimeException(__CLASS__.'::class read-only');
    }

    /**
     * @param $name
     *
     * @return bool
     */
    public function __isset($name)
    {
        return isset($this->config[$name]);
    }

    /**
     * @inheritDoc
     */
    public function jsonSerialize()
    {
        $this->config['video_voice_priority'] = $this->getJsonDecode('video_voice_priority');
        $this->config['video_voices_disabled'] = $this->getJsonDecode('video_voices_disabled');
        $this->config['category_bundle'] = $this->getJsonDecode('category_bundle');
        $this->config['type_bundle'] = $this->getJsonDecode('type_bundle');
        $this->config['collections_bundle'] = $this->getJsonDecode('collections_bundle');

        return $this->config;
    }

    /**
     * @param  string  $key
     * @param  bool  $assoc
     * @return array|null
     */
    public function getJsonDecode($key, $assoc = true)
    {
        $field = $this->get($key);

        $data = json_decode($field, $assoc);

        if (json_last_error() === JSON_ERROR_NONE) {
            return $data;
        }

        $data = html_entity_decode($field);

        return json_decode($data, $assoc);
    }

    /**
     * @param  string|null  $key
     *
     * @return string|null
     */
    public function get($key)
    {
        return isset($this->config[$key]) ? $this->config[$key] : null;
    }

}
