<?php

namespace idoit\Module\CustomFields;

use isys_component_template_language_manager as LanguageManager;
use isys_module_custom_fields as CustomFields;

/**
 * Class PropertyTypes
 *
 * @package idoit\Module\CustomFields
 */
class PropertyTypes
{
    public const ALLOW_INLINE          = 'allowInline';
    public const AVAILABLE_SINGLEVALUE = 'availableSingleValue';
    public const AVAILABLE_MULTIVALUE  = 'availableMultiValue';
    public const DISPLAY_IN_TABLE      = 'displayInTable';
    public const TEMPLATE              = 'template';

    // Dependency types
    public const DEPENDENCY_PRIMARY   = 'primary';
    public const DEPENDENCY_SECONDARY = 'secondary';

    /**
     * @param LanguageManager $language
     *
     * @return array
     */
    public static function getAll(LanguageManager $language): array
    {
        $properties = [
            [
                'title'                     => $language->get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE__TEXT'),
                'value'                     => 'f_text',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/text.tpl'
            ],
            [
                'title'                     => $language->get('LC_UNIVERSAL__NUMERIC_ONLY'),
                'value'                     => 'f_numeric',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/numeric.tpl'
            ],
            [
                'title'                     => $language->get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE__TIME'),
                'value'                     => 'f_time',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/default.tpl'
            ],
            [
                'title'                     => $language->get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE__TEXT_MASKED'),
                'value'                     => 'f_password',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/default.tpl'
            ],
            [
                'title'                     => $language->get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE__TEXTAREA'),
                'value'                     => 'f_textarea',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/text.tpl'
            ],
            [
                'title'                     => $language->get('LC__SYSTEM__CUSTOM_CATEGORIES__FIELD_TYPE__HTML_EDITOR'),
                'value'                     => 'f_wysiwyg',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/default.tpl'
            ],
            [
                'title'                     => 'Dialog+',
                'value'                     => 'f_popup',
                'popup'                     => 'dialog_plus',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/dialog_plus.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__YES_NO_FIELD'),
                'value'                     => 'f_dialog',
                'extra'                     => 'yes-no',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/dialog.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__CHECKBOXES'),
                'value'                     => 'f_popup',
                'popup'                     => 'checkboxes',
                'multiselection'            => 1,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/checkboxes.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__OBJECT_BROWSER'),
                'value'                     => 'f_popup',
                'popup'                     => 'browser_object',
                'relation'                  => 0,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/object_browser.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__OBJECT_RELATIONSHIP'),
                'value'                     => 'f_popup',
                'popup'                     => 'browser_object',
                'relation'                  => 1,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/object_browser.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__OBJECT_BROWSER_MULTISELECTION'),
                'value'                     => 'f_popup',
                'popup'                     => 'browser_object',
                'relation'                  => 0,
                'multiselection'            => 1,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/object_browser.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__OBJECT_RELATIONSHIP_MULTISELECTION'),
                'value'                     => 'f_popup',
                'popup'                     => 'browser_object',
                'relation'                  => 1,
                'multiselection'            => 1,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/object_browser.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__HORIZONTAL_LINE'),
                'value'                     => 'hr',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => false,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/hr.tpl'
            ],
            [
                'title'                     => 'HTML',
                'value'                     => 'html',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => false,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/html.tpl'
            ],
            [
                'title'                     => 'Javascript',
                'value'                     => 'script',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => false,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/javascript.tpl'
            ],
            [
                'title'                     => 'Link',
                'value'                     => 'f_link',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/default.tpl'
            ],
            [
                'title'                     => $language->get('LC_UNIVERSAL__DATETIME'),
                'value'                     => 'f_popup',
                'extra'                     => 'date-datetime',
                'popup'                     => 'calendar',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/calendar.tpl'
            ],
            [
                'title'                     => $language->get('LC__MODULE__CUSTOM_FIELDS__DIALOG_PLUS_MULTI'),
                'value'                     => 'f_popup',
                'popup'                     => 'dialog_plus',
                'multiselection'            => 1,
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/dialog_plus.tpl'
            ],
            [
                'title'                     => $language->get('LC__BROWSER__TITLE__FILE'),
                'value'                     => 'f_popup',
                'popup'                     => 'file',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => true,
                self::ALLOW_INLINE          => true,
                self::DISPLAY_IN_TABLE      => true,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/file_browser.tpl'
            ],
            [
                'title'                     => 'Report',
                'value'                     => 'f_popup',
                'popup'                     => 'report_browser',
                self::AVAILABLE_SINGLEVALUE => true,
                self::AVAILABLE_MULTIVALUE  => false,
                self::ALLOW_INLINE          => false,
                self::DISPLAY_IN_TABLE      => false,
                self::TEMPLATE              => CustomFields::getPath() . 'templates/fields/default.tpl'
            ]
        ];

        // Here we process the 'value' for the frontend to save some JS overhead.
        return array_map(function ($property) {
            $addition = implode(',', array_filter([
                $property['extra'],
                $property['popup'],
                $property['relation'],
                $property['multiselection']
            ], function ($value) {
                return trim($value ?? '') !== '';
            }));

            if (!file_exists($property[self::TEMPLATE])) {
                $property[self::TEMPLATE] = CustomFields::getPath() . '/templates/fields/not_available.tpl';
            }

            $property['configValue'] = $property['value'] . (empty($addition) ? '' : ',' . $addition);

            return $property;
        }, $properties);
    }

    /**
     * @param array           $configuration
     * @param LanguageManager $language
     *
     * @return array|null
     */
    public static function getTypeByConfiguration(array $configuration, LanguageManager $language): ?array
    {
        $types = self::getAll($language);

        $types = array_filter($types, function ($type) use ($configuration) {
            return $type['value'] === $configuration['type'];
        });
        if (count($types) === 1) {
            return current($types);
        }

        if (isset($configuration['popup'])) {
            $types = array_filter($types, function ($type) use ($configuration) {
                return $type['popup'] === $configuration['popup'];
            });

            if (count($types) === 1) {
                return current($types);
            }
        }

        // Check for "multiselection" property.
        $types = array_filter($types, function ($type) use ($configuration) {
            // Made the comparison less strict to allow "true == 1".
            return (!isset($configuration['multiselection']) && !isset($type['multiselection']))
                || (!isset($configuration['multiselection']) && !$type['multiselection'])
                || ($type['multiselection'] == $configuration['multiselection']);
        });

        if (count($types) === 1) {
            return current($types);
        }

        // Check for "relation" property.
        $types = array_filter($types, function ($type) use ($configuration) {
            return (!isset($configuration['relation']) && !isset($type['relation']))
                || (!isset($configuration['relation']) && !$type['relation'])
                || ($type['relation'] === $configuration['relation']);
        });

        if (count($types) === 1) {
            return current($types);
        }

        if (isset($configuration['extra'])) {
            $types = array_filter($types, function ($type) use ($configuration) {
                return $type['extra'] === $configuration['extra'];
            });

            if (count($types) === 1) {
                return current($types);
            }
        }

        return null;
    }
}
