<?php

namespace App\Helpers;

use App\AlbumSources\AmazonS3Source;
use App\AlbumSources\IAlbumSource;
use App\AlbumSources\LocalFilesystemSource;
use App\AlbumSources\OpenStackSource;
use App\AlbumSources\RackspaceSource;
use App\Configuration;

class ConfigHelper
{
    /** @var mixed Cache of configuration values */
    private $cache;

    public function allowedAlbumViews()
    {
        return ['default', 'slideshow'];
    }

    public function allowedDateFormats()
    {
        return [
            'Y-m-d - H:i',
            'd/m/Y - H:i',
            'd-m-Y - H:i',
            'd.m.Y - H:i',
            'd/M/Y - H:i',
            'd-M-Y - H:i',
            'm/d/Y - H:i',
            'm-d-Y - H:i',
            'm.d.Y - H:i',
            'jS F Y - H:i',
            'jS M. Y - H:i',
            'F jS Y - H:i',
            'M. jS Y - H:i'
        ];
    }

    public function albumSources()
    {
        $results = [];

        $classes = [
            LocalFilesystemSource::class,
            AmazonS3Source::class,
            OpenStackSource::class,
            RackspaceSource::class
        ];
        foreach ($classes as $class)
        {
            /** @var IAlbumSource $instance */
            $instance = new $class;
            $key = basename(str_replace('\\', '/', $class));
            $results[$key] = trans($instance->getName());
        }

        return $results;
    }

    public function allowedThemeNames()
    {
        $results = [];

        $directoryIterator = new \FilesystemIterator(dirname(dirname(__DIR__)) . '/resources/views/themes', \FilesystemIterator::SKIP_DOTS);

        /** @var \SplFileInfo $fileInfo */
        foreach ($directoryIterator as $fileInfo)
        {
            if (!$fileInfo->isDir() || strtolower($fileInfo->getFilename()) == 'base')
            {
                continue;
            }

            $themeName = strtolower($fileInfo->getFilename());
            $themeDisplayName = $themeName;

            $themeInfoFilename = sprintf('%s/theme.json', $fileInfo->getPathname());
            if (file_exists($themeInfoFilename))
            {
                $themeInfo = json_decode(file_get_contents($themeInfoFilename));
                if ($themeInfo !== false && isset($themeInfo->name))
                {
                    $themeDisplayName = $themeInfo->name;
                }
            }

            $results[$themeName] = $themeDisplayName;
        }

        return $results;
    }

    public function defaults()
    {
        $currentAppName = $this->get('app_name', false);

        return array(
            'albums_menu_parents_only' => false,
            'albums_menu_number_items' => 10,
            'allow_photo_comments' => false,
            'allow_photo_comments_anonymous' => true,
            'allow_self_registration' => true,
            'analytics_code' => '',
            'app_name' => trans('global.app_name'),
            'date_format' => $this->allowedDateFormats()[0],
            'default_album_view' => $this->allowedAlbumViews()[0],
            'enable_visitor_hits' => false,
            'facebook_app_id' => '',
            'facebook_app_secret' => '',
            'google_app_id' => '',
            'google_app_secret' => '',
            'hotlink_protection' => false,
            'items_per_page' => 12,
            'items_per_page_admin' => 10,
            'moderate_anonymous_users' => true,
            'moderate_known_users' => true,
            'photo_comments_allowed_html' => 'p,div,span,a,b,i,u',
            'photo_comments_thread_depth' => 3,
            'public_statistics' => true,
            'rabbitmq_enabled' => false,
            'rabbitmq_server' => 'localhost',
            'rabbitmq_password' => encrypt('guest'),
            'rabbitmq_port' => 5672,
            'rabbitmq_queue' => 'blue_twilight',
            'rabbitmq_username' => 'guest',
            'recaptcha_enabled_registration' => false,
            'recaptcha_secret_key' => '',
            'recaptcha_site_key' => '',
            'remove_copyright' => false,
            'require_email_verification' => true,
            'restrict_original_download' => true,
            'sender_address' => sprintf('hostmaster@%s', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost')),
            'sender_name' => (is_null($currentAppName) ? trans('global.app_name') : $currentAppName),
            'smtp_server' => 'localhost',
            'smtp_password' => '',
            'smtp_port' => 25,
            'smtp_username' => '',
            'social_facebook_login' => false,
            'social_google_login' => false,
            'social_twitter_login' => false,
            'social_user_feeds' => false,
            'social_user_profiles' => false,
            'theme' => 'default',
            'twitter_app_id' => '',
            'twitter_app_secret' => '',
        );
    }

    public function get($key, $defaultIfUnset = true)
    {
        if (is_null($this->cache))
        {
            $this->loadCache();
        }

        $config = isset($this->cache[$key]) ? $this->cache[$key] : null;

        if (is_null($config))
        {
            if ($defaultIfUnset)
            {
                $defaults = $this->defaults();
                return (isset($defaults[$key]) ? $defaults[$key] : null);
            }

            return null;
        }

        return $config->value;
    }

    public function getAll()
    {
        $results = array();

        /** @var Configuration $config */
        foreach (Configuration::all() as $config)
        {
            $results[$config->key] = $config->value;
        }

        return $results;
    }

    public function getOrCreateModel($key)
    {
        $config = isset($this->cache[$key]) ? $this->cache[$key] : null;
        if (is_null($config) || $config === false)
        {
            $config = new Configuration();
            $config->key = $key;
            $config->value = '';
            $config->save();

            $this->loadCache();
        }

        return $config;
    }

    public function isImageProcessingQueueEnabled()
    {
        return $this->get('rabbitmq_enabled') &&
            !empty($this->get('rabbitmq_server')) &&
            !empty($this->get('rabbitmq_port')) &&
            !empty($this->get('rabbitmq_username')) &&
            !empty($this->get('rabbitmq_password')) &&
            !empty($this->get('rabbitmq_queue'));
    }

    public function isSocialMediaLoginEnabled()
    {
        return  $this->get('social_facebook_login') ||
                $this->get('social_twitter_login') ||
                $this->get('social_google_login');
    }

    private function loadCache()
    {
        $this->cache = null;

        /** @var Configuration $config */
        foreach (Configuration::all() as $config)
        {
            $this->cache[$config->key] = $config;
        }
    }
}