<?php

declare(strict_types=1);

/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Jet Theme Backend for Magento 2 (System)
 */

namespace Amasty\JetTheme\Observer\Framework\View\Layout;

use Amasty\JetTheme\Model\Config\Source\Fonts\FontType;
use Amasty\JetTheme\Model\ConfigProvider;
use Amasty\JetTheme\Model\FontManager;
use Amasty\JetTheme\Model\StoreThemeMapper;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\View\Asset\Repository as AssetRepo;
use Magento\Framework\View\Page\Config as PageConfig;

class Builder implements ObserverInterface
{
    public const DEFAULT_FONT_PATH = 'fonts/roboto/';
    public const DEFAULT_FONT_NAME_BOLD = 'bold/Roboto-700.woff2';
    public const DEFAULT_FONT_NAME_REGULAR = 'regular/Roboto-400.woff2';
    public const FONT_ATTRIBUTES = [
        'rel' => 'preload',
        'as' => 'font',
        'type' => 'font/woff2',
        'crossorigin' => 'anonymous'
    ];
    public const NON_LATIN_FONT_PATH = 'Amasty_JetNonLatinFonts/fonts/';
    public const ICON_FONT = 'fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2';
    public const GSTATIC_FONT_URL = 'https://fonts.gstatic.com/';

    /**
     * @var PageConfig
     */
    private $pageConfig;

    /**
     * @var AssetRepo
     */
    private $assetRepo;

    /**
     * @var ConfigProvider
     */
    private $configProvider;

    /**
     * @var FontManager
     */
    private $fontManager;

    /**
     * @var StoreThemeMapper
     */
    private $storeThemeMapper;

    public function __construct(
        PageConfig $pageConfig,
        AssetRepo $assetRepo,
        ConfigProvider $configProvider,
        FontManager $fontManager,
        StoreThemeMapper $storeThemeMapper
    ) {
        $this->pageConfig = $pageConfig;
        $this->assetRepo = $assetRepo;
        $this->configProvider = $configProvider;
        $this->fontManager = $fontManager;
        $this->storeThemeMapper = $storeThemeMapper;
    }

    /**
     * @param Observer $observer
     * @return void
     */
    public function execute(Observer $observer): void
    {
        if (!$this->storeThemeMapper->isCurrentThemeJetTheme()) {
            return;
        }

        $this->pageConfig->addRemotePageAsset(
            $this->getFontUrl(self::ICON_FONT),
            'link_rel',
            ['attributes' => self::FONT_ATTRIBUTES]
        );
        switch ($this->configProvider->getFontType()) {
            case FontType::GOOGLE:
                $this->processGoogleFonts();
                break;
            case FontType::NON_LATIN:
                $this->processNonLatinFont();
                break;
            default:
                $this->processDefaultFonts();
                break;
        }
    }

    private function processNonLatinFont(): void
    {
        $font = self::NON_LATIN_FONT_PATH . $this->configProvider->getNonLatinFontSetting() . '.woff2';
        $this->pageConfig->addRemotePageAsset(
            $this->getFontUrl($font),
            'link_rel',
            ['attributes' => self::FONT_ATTRIBUTES]
        );
    }

    /**
     * @return void
     */
    private function processGoogleFonts(): void
    {
        $googleFontSetting = $this->configProvider->getGoogleFontSetting();
        $this->pageConfig->addRemotePageAsset(
            self::GSTATIC_FONT_URL,
            'link_rel',
            ['attributes' => ['rel' => 'preconnect', 'crossorigin' => '']]
        );

        $this->pageConfig->addRemotePageAsset(
            $this->fontManager->getFontUrl($googleFontSetting),
            'link_rel',
            ['attributes' => ['rel' => 'preload', 'as' => 'style']]
        );

        $this->pageConfig->addRemotePageAsset(
            $this->fontManager->getFontUrl($googleFontSetting),
            'link_rel',
            ['attributes' => ['rel' => 'stylesheet']]
        );
    }

    /**
     * @return void
     */
    private function processDefaultFonts(): void
    {
        $preloadedFonts = [
            'bold_path' => self::DEFAULT_FONT_PATH . self::DEFAULT_FONT_NAME_BOLD,
            'regular_path' => self::DEFAULT_FONT_PATH . self::DEFAULT_FONT_NAME_REGULAR,
        ];

        foreach ($preloadedFonts as $font) {
            $this->pageConfig->addRemotePageAsset(
                $this->getFontUrl($font),
                'link_rel',
                ['attributes' => self::FONT_ATTRIBUTES]
            );
        }
    }

    /**
     * @param string $font
     * @return string
     */
    private function getFontUrl(string $font): string
    {
        return $this->assetRepo->getUrl($font);
    }
}
