<?php
namespace front;

class LayoutEngine
{
  const menu_pattern = '/MENU:[0-9]*/';
  const menu_main_pattern = '/MENU_GLOWNE:[0-9]*/';
  const container_pattern = '/KONTENER:[0-9]*/';
  const language_pattern = '/LANG:[a-zA-Z0-9_-]*/';
  const products_promoted = '/PROMOWANE_PRODUKTY((:([0-9]*))?)/';
  const news_pattern = '/AKTUALNOSCI:([0-9]*)((:([0-9]*))?)/';
  const article_products_category_pattern = '/PRODUKTY_KATEGORIA:([0-9]*)((:([0-9]*))?)/';
  const news_list_pattern = '/AKTUALNOSCI_LISTA:([0-9]*)((:([0-9]*))?)/';
  const top_news_pattern = '/NAJPOULARNIEJSZE_ARTYKULY:([0-9]*)((:([0-9]*))?)/';
  const single_product_pattern = '/PRODUKT:[0-9]*/';
  const products_box = '/PRODUKTY_BOX:[0-9,]*/';
  const produkty_top = '/PRODUKTY_TOP((:([0-9]*))?)/';
  const produkty_new = '/PRODUKTY_NEW((:([0-9]*))?)/';

  public static function show()
  {
    global $page, $settings, $settings, $lang, $lang_id;

    $articleRepo = new \Domain\Article\ArticleRepository( $GLOBALS['mdb'] );
    $bannerRepo = new \Domain\Banner\BannerRepository( $GLOBALS['mdb'] );
    $layoutsRepo = new \Domain\Layouts\LayoutsRepository( $GLOBALS['mdb'] );
    $pagesRepo = new \Domain\Pages\PagesRepository( $GLOBALS['mdb'] );
    $scontainersRepo = new \Domain\Scontainers\ScontainersRepository( $GLOBALS['mdb'] );
    $categoryRepo = new \Domain\Category\CategoryRepository( $GLOBALS['mdb'] );
    $producerRepo = new \Domain\Producer\ProducerRepository( $GLOBALS['mdb'] );

    if ( (int) \Shared\Helpers\Helpers::get( 'layout_id' ) )
      $layout = $layoutsRepo->find( (int) \Shared\Helpers\Helpers::get( 'layout_id' ) );

    if ( \Shared\Helpers\Helpers::get( 'article' ) )
      $layout = $layoutsRepo->getArticleLayout( (int) \Shared\Helpers\Helpers::get( 'article' ) );

    if ( \Shared\Helpers\Helpers::get( 'product' ) )
      $layout = $layoutsRepo->getProductLayout( (int) \Shared\Helpers\Helpers::get( 'product' ) );

    if ( \Shared\Helpers\Helpers::get( 'category' ) )
      $layout = $layoutsRepo->getCategoryLayout( (int) \Shared\Helpers\Helpers::get( 'category' ) );

    if ( !$layout and \Shared\Helpers\Helpers::get( 'module' ) )
      $layout = $layoutsRepo->getDefaultLayout();

    if ( !$layout )
      $layout = $layoutsRepo->getActiveLayout( $page['id'] );

    if ( $settings['devel'] == true and file_exists( 'devel.html' ) )
      $html = file_get_contents( 'devel.html' );
    else
    {
      $html = $layout['html'];
    }

    if ( $settings['facebook_link'] )
      $html = str_replace( '</body>', self::facebook( $settings['facebook_link'] ) . '</body>', $html );

    $html = str_replace( '[COPYRIGHT]',
                            self::copyright(),
                            $html );

    $html = str_replace( '[BANER_STRONA_GLOWNA]', \front\Views\Banners::mainBanner( $bannerRepo->mainBanner( $lang_id ) ), $html );
    $html = str_replace( '[BANERY]',              \front\Views\Banners::banners( $bannerRepo->banners( $lang_id ) ), $html );

    $html = str_replace( '[KATEGORIE]', \Shared\Tpl\Tpl::view( 'shop-category/categories', [
                                            'level' => null,
                                            'current_category' => \Shared\Helpers\Helpers::get( 'category' ),
                                            'categories' => $categoryRepo->categoriesTree( $lang_id )
                                          ] ), $html );

    /* BOX - promowane produkty */
    preg_match_all( self::products_promoted, $html, $products_promoted_list );
    if ( is_array( $products_promoted_list[0] ) ) foreach( $products_promoted_list[0] as $products_promoted_tmp )
    {
      $products_promoted_tmp = explode( ':', $products_promoted_tmp );
      $products_promoted_tmp[1] ? $limit = $products_promoted_tmp[1] : $limit = 6;

      $products_promoted_tmp[1] ? $pattern = '[PROMOWANE_PRODUKTY:' . $products_promoted_tmp[1] . ']' : $pattern = '[PROMOWANE_PRODUKTY]';

      $html = str_replace(  $pattern,
                            \Shared\Tpl\Tpl::view( 'shop-product/promoted-products', [
                              'products' => ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->promotedProductIdsCached( $limit )
                            ] ),
                            $html
                          );
    }

    /* BOX - aktualnsci */
    preg_match_all( self::news_pattern, $html, $news_list );
    if ( is_array( $news_list[0] ) ) foreach( $news_list[0] as $news_list_tmp )
    {
      $news_list_tmp = explode( ':', $news_list_tmp );

      $news_list_tmp[2] != '' ? $news_limit = $news_list_tmp[2] : $news_limit = $settings['news_limit'];

      $news_list_tmp[2] != '' ? $pattern = '[AKTUALNOSCI:' . $news_list_tmp[1] . ':' . $news_list_tmp[2] . ']' : $pattern = '[AKTUALNOSCI:' . $news_list_tmp[1] . ']';
      $html = str_replace( $pattern, \front\Views\Articles::news(
                                                            $news_list_tmp[1],
                                                            $articleRepo->news( (int)$news_list_tmp[1], (int)$news_limit, $lang_id )
                                                          ), $html );
    }

    $html = str_replace( '[KOSZYK]',
                            \Shared\Tpl\Tpl::view( 'shop-basket/basket-mini', [
                              'basket' => \Shared\Helpers\Helpers::get_session( 'basket' ),
                              'lang_id' => $lang_id,
                              'coupon' => \Shared\Helpers\Helpers::get_session( 'coupon' )
                            ] ),
                            $html );
    $html = str_replace( '[NEWSLETTER]',
                            \front\Views\Newsletter::render(),
                            $html );
    $html = str_replace( '[UZYTKOWNIK_MINI_LOGOWANIE]',
                            \front\Views\ShopClient::miniLogin(),
                            $html );

    $html = str_replace( '[CSS]',           $layout['css'],                   $html );

    $html = str_replace( '[JAVA_SCRIPT]',   $layout['js'],                    $html );

    preg_match_all( self::menu_pattern, $html, $menu );
    if ( is_array( $menu[0] ) ) foreach( $menu[0] as $menu_tmp )
    {
      $menu_tmp = explode( ':', $menu_tmp );
      $html = str_replace( '[MENU:' . $menu_tmp[1] . ']', \front\Views\Menu::menu( $pagesRepo->frontMenuDetails( (int) $menu_tmp[1], $lang_id ), $page['id'] ), $html );
    }

    preg_match_all( self::menu_main_pattern, $html, $menu );
    if ( is_array( $menu[0] ) ) foreach( $menu[0] as $menu_tmp )
    {
      $menu_tmp = explode( ':', $menu_tmp );
      $html = str_replace(
        '[MENU_GLOWNE:' . $menu_tmp[1] . ']',
        \Shared\Tpl\Tpl::view( 'menu/main-menu', [
          'menu' => $pagesRepo->frontMenuDetails( (int) $menu_tmp[1], $lang_id )
        ] ),
        $html );
    }

    preg_match_all( self::language_pattern, $html, $language_list );
    if ( is_array( $language_list[0] ) ) foreach( $language_list[0] as $language_list_tmp )
    {
      $language_list_tmp = explode( ':', $language_list_tmp );
      $html = str_replace( '[LANG:' . $language_list_tmp[1] . ']', $lang[ $language_list_tmp[1] ], $html );
    }

    //
    // KATEGORIA SKLEPU
    //
    if ( \Shared\Helpers\Helpers::get( 'category' ) )
    {
      $category = $categoryRepo->frontCategoryDetails( (int)\Shared\Helpers\Helpers::get( 'category' ), $lang_id );

      if ( $category['language']['meta_title'] )
        $page['language']['title'] = $category['language']['meta_title'];
      else
        $page['language']['title'] = $category['language']['title'];

      $page['show_title'] = true;
      $page['language']['meta_keywords'] = $category['language']['meta_keywords'];
      $page['language']['meta_description'] = $category['language']['meta_description'];
      $page['language']['page_title'] = $category['language']['category_title'] ? $category['language']['category_title'] : $category['language']['title'];

      // CANONICAL
      $html = str_replace( '[CANONICAL]', '', $html );
    }


    //
    // ARTYKUŁ
    //
    if ( \Shared\Helpers\Helpers::get( 'article' ) )
    {
      $article = $articleRepo->articleDetailsFrontend( (int)\Shared\Helpers\Helpers::get( 'article' ), $lang_id );

      if ( $article['language']['meta_title'] )
        $page['language']['title'] = $article['language']['meta_title'];
      else
        $page['language']['title'] = $article['language']['title'];

      $page['show_title'] = false;
      $page['language']['meta_keywords'] = $article['language']['meta_keywords'];
      $page['language']['meta_description'] = $article['language']['meta_description'];

      // CANONICAL
      $html = str_replace( '[CANONICAL]', '', $html );
    }

    //
    // PRODUKT
    //
    if ( \Shared\Helpers\Helpers::get( 'product' ) )
    {
      $permutation_hash = isset( $_GET['permutation_hash'] ) ? str_replace( '_', '|', $_GET['permutation_hash'] ) : null;
      $product = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( \Shared\Helpers\Helpers::get( 'product' ), $lang_id, $permutation_hash );

      if ( $product['language']['meta_title'] )
        $page['language']['title'] = $product['language']['meta_title'];
      else
        $page['language']['title'] = $product['language']['name'];

      $page['show_title'] = false;
      $page['language']['meta_keywords'] = $product['language']['meta_keywords'];
      $page['language']['meta_description'] = $product['language']['meta_description'];

      // CANONICAL
      if ( $product['language']['canonical'] )
        $html = str_replace( '[CANONICAL]', '<link rel="canonical" href="' . $product['language']['canonical'] . '">', $html );
      else
        $html = str_replace( '[CANONICAL]', '', $html );
    }

    //
    // PRODUCENT
    //
    if ( \Shared\Helpers\Helpers::get( 'producer_id' ) )
    {
      $producer = $producerRepo->findForFrontend( (int)\Shared\Helpers\Helpers::get( 'producer_id' ), $lang_id );

      if ( $producer && !empty( $producer['languages'][$lang_id]['meta_title'] ) )
        $page['language']['meta_title'] = $producer['languages'][$lang_id]['meta_title'];
    }

    //
    // STRONA CMS
    //
    if ( $page )
    {
      // CANONICAL
      $html = str_replace( '[CANONICAL]', '', $html );
    }

    $html = str_replace( '[CANONICAL]', '', $html );
    $html = str_replace( '[ZAWARTOSC]', \front\App::route( $product, $category ), $html );

    /* pojedynczy produkt */
    preg_match_all( self::single_product_pattern, $html, $single_product_array );
    if ( is_array( $single_product_array[0] ) ) foreach( $single_product_array[0] as $single_product )
    {
      $single_product = explode( ':', $single_product );
      $html = str_replace(
        '[PRODUKT:' . $single_product[1] . ']',
        \Shared\Tpl\Tpl::view( 'shop-product/product-mini', [
          'product' => ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( (int)$single_product[1], $lang_id )
        ] ),
        $html
      );
    }

    /* lista produktów */
    preg_match_all( self::products_box, $html, $products_box_array );
    if ( is_array( $products_box_array[0] ) ) foreach( $products_box_array[0] as $products_box )
    {
      unset( $products_id ); unset( $product_id ); unset( $products );

      $products_box = explode( ':', $products_box );
      $products_id = explode( ',', $products_box[1] );

      foreach ( $products_id as $product_id )
        $products[] = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( (int)$product_id, $lang_id );


      $html = str_replace(
        '[PRODUKTY_BOX:' . $products_box[1] . ']',
        \Shared\Tpl\Tpl::view( 'shop-product/products-box', [
          'products' => $products
        ] ),
        $html
      );
    }

    /* lista popularnych produktów */
    preg_match_all( self::produkty_top, $html, $products_top_array );
    if ( is_array( $products_top_array[0] ) ) foreach( $products_top_array[0] as $products_top )
    {
      unset( $products_id_arr );
      unset( $limit );
      unset( $product_id );
      unset( $top_products_arr );

      $products_top = explode( ':', $products_top );
      $products_top[1] ? $limit = $products_top[1] : $limit = 6;

      $products_top[1] ? $pattern = '[PRODUKTY_TOP:' . $products_top[1] . ']' : $pattern = '[PRODUKTY_TOP]';

      $products_id_arr = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->topProductIds( $limit );

      foreach ( $products_id_arr as $product_id ){
        $top_products_arr[] = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( (int)$product_id, $lang_id );
      }

      $html = str_replace(  $pattern,
        \Shared\Tpl\Tpl::view( 'shop-product/products-top', [
          'products' => $top_products_arr,
        ] ),
        $html
      );
    }

    /* lista ostatnio dodanych produktów */
    preg_match_all( self::produkty_new, $html, $products_top_array );
    if ( is_array( $products_top_array[0] ) ) foreach( $products_top_array[0] as $products_top )
    {
      unset( $products_id_arr );
      unset( $limit );
      unset( $product_id );
      unset( $top_products_arr );

      $products_top = explode( ':', $products_top );
      $products_top[1] ? $limit = $products_top[1] : $limit = 10;

      $products_top[1] ? $pattern = '[PRODUKTY_NEW:' . $products_top[1] . ']' : $pattern = '[PRODUKTY_NEW]';

      $products_id_arr = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->newProductIds( $limit );


      foreach ( $products_id_arr as $product_id ){
        $top_products_arr[] = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->findCached( (int)$product_id, $lang_id );
      }

      $html = str_replace(  $pattern,
        \Shared\Tpl\Tpl::view( 'shop-product/products-new', [
          'products' => $top_products_arr,
        ] ),
        $html
      );
    }


    $html = str_replace( '[TITLE]', $page['language']['meta_title'] ? $page['language']['meta_title'] . ' | ' . $settings['firm_name'] : $page['language']['title'] . ' | ' . $settings['firm_name'], $html );
    $html = str_replace( '[META_KEYWORDS]', $page['language']['meta_keywords'], $html );
    $html = str_replace( '[META_DESCRIPTION]', $page['language']['meta_description'], $html );
    $html = str_replace( '[JEZYKI]', \front\Views\Languages::render( ( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->activeLanguages() ), $html );
    $html = str_replace( '[TYTUL_STRONY]', self::title( $page['language']['title'], $page['show_title'], $page['language']['page_title'] ), $html );
    $html = str_replace( '[WYSZUKIWARKA]', \front\Views\ShopSearch::simpleForm(), $html );

    /* atrybut noindex */
    if ( \Shared\Helpers\Helpers::get( 'article' ) )
    {
      $articleRepo->articleNoindex( (int)\Shared\Helpers\Helpers::get( 'article' ), $lang_id ) ? $noindex = 'noindex' : $noindex = 'all';
      $html = str_replace( '[META_INDEX]', '<meta name="robots" content="' . $noindex . '">', $html );
    }
    else
    {
      $page['language']['noindex'] ? $noindex = 'noindex' : $noindex = 'all';
      $html = str_replace( '[META_INDEX]', '<meta name="robots" content="' . $noindex . '">', $html );
    }

    if ( $page['language']['canonical'] )
      $html = str_replace( '</head>', '<link rel="canonical" href="' . $page['language']['canonical'] . '" /></head>', $html );

    while ( strpos( $html, '[PHP]' ) !== false )
    {
      $text = explode( '[PHP]', $html );
      $before = $text[0];
      for ( $i = 1; $i < count( $text ); $i++ )
      {
        $temp   = explode( '[/PHP]' , $text[$i] );
        $code   = $temp[0];

        ob_start();
        eval( $code );
        $out .= ob_get_contents();
        ob_end_clean();

        $out .= $temp[1];
      }
      $html = $before . $out;
    }

    /* BOX - blog produkty kategoria */
    preg_match_all( self::article_products_category_pattern, $html, $category_list );
    if ( is_array( $category_list[0] ) ) foreach( $category_list[0] as $category_list_tmp )
    {
      $category_list_tmp = explode( ':', $category_list_tmp );

      $category_list_tmp[2] != '' ? $products_limit = $category_list_tmp[2] : $products_limit = 4;

      $category_list_tmp[2] != '' ? $pattern = '[PRODUKTY_KATEGORIA:' . $category_list_tmp[1] . ':' . $category_list_tmp[2] . ']' : $pattern = '[PRODUKTY_KATEGORIA:' . $category_list_tmp[1] . ']';

      $html = str_replace(
                $pattern,
                \Shared\Tpl\Tpl::view( 'shop-category/blog-category-products', [
                        'products' => $categoryRepo->blogCategoryProducts( (int)$category_list_tmp[1], $lang_id, (int)$products_limit )
                      ] ),
                $html );
    }

    // prosta lista aktualności z wybranej podstrony
    preg_match_all( self::news_list_pattern, $html, $news_list_matches );
    if ( is_array( $news_list_matches[0] ) ) foreach( $news_list_matches[0] as $news_list_tmp )
    {
      $news_list_tmp = explode( ':', $news_list_tmp );
      $news_list_tmp[2] != '' ? $news_limit = $news_list_tmp[2] : $news_limit = $settings['news_limit'];
      $news_list_tmp[2] != '' ? $pattern = '[AKTUALNOSCI_LISTA:' . $news_list_tmp[1] . ':' . $news_list_tmp[2] . ']' : $pattern = '[AKTUALNOSCI_LISTA:' . $news_list_tmp[1] . ']';

      $newsArticles = $articleRepo->newsListArticles( (int)$news_list_tmp[1], (int)$news_limit, $lang_id );
      $html = str_replace( $pattern, \front\Views\Articles::newsList( $newsArticles ), $html );
    }

    // prosta lista z najpopularniejszymi artykułami
    preg_match_all( self::top_news_pattern, $html, $top_news_matches );
    if ( is_array( $top_news_matches[0] ) ) foreach( $top_news_matches[0] as $news_list_tmp )
    {
      $news_list_tmp = explode( ':', $news_list_tmp );
      $news_list_tmp[2] != '' ? $news_limit = $news_list_tmp[2] : $news_limit = $settings['news_limit'];
      $news_list_tmp[2] != '' ? $pattern = '[NAJPOULARNIEJSZE_ARTYKULY:' . $news_list_tmp[1] . ':' . $news_list_tmp[2] . ']' : $pattern = '[NAJPOULARNIEJSZE_ARTYKULY:' . $news_list_tmp[1] . ']';

      $topArticles = $articleRepo->topArticles( (int)$news_list_tmp[1], (int)$news_limit, $lang_id );
      $html = str_replace( $pattern, \front\Views\Articles::newsList( $topArticles ), $html );
    }

    $html = str_replace( '[ALERT]', self::alert(), $html );

    preg_match_all( self::container_pattern, $html, $container_list );
    if ( is_array( $container_list[0] ) ) foreach( $container_list[0] as $container_list_tmp )
    {
      $container_list_tmp = explode( ':', $container_list_tmp );
      $html = str_replace( '[KONTENER:' . $container_list_tmp[1] . ']', \front\Views\Scontainers::scontainer( $scontainersRepo->frontScontainerDetails( (int)$container_list_tmp[1], $lang_id ) ), $html );
    }

    return $html;
  }

  public static function facebook( $facebook_link )
  {
    $tpl = new \Shared\Tpl\Tpl;
    $tpl -> facebook_link = $facebook_link;
    return $tpl -> render( 'site/facebook' );
  }

  static public function title( $title, $show_title, $page_title )
  {
    return \Shared\Tpl\Tpl::view( 'site/title', [
      'title' => $title,
      'page_title' => $page_title,
      'show_title' => $show_title
    ] );
  }

  public static function alert()
  {
    if ( $alert = \Shared\Helpers\Helpers::get_session( 'alert' ) )
    {
      \Shared\Helpers\Helpers::delete_session( 'alert' );

      return $tpl = \Shared\Tpl\Tpl::view( 'site/alert', [
                'alert' => $alert
              ] );
    }

    if ( $error = \Shared\Helpers\Helpers::get_session( 'error' ) )
    {
      \Shared\Helpers\Helpers::delete_session( 'error' );

      $tpl = new \Shared\Tpl\Tpl;
      $tpl -> error = $error;
      return $tpl -> render( 'site/error' );
    }
  }

  public static function copyright()
  {
    $tpl = new \Shared\Tpl\Tpl;
    return $tpl -> render( 'site/copyright' );
  }

  public static function contact()
  {
    $tpl = new \Shared\Tpl\Tpl;
    return $tpl -> render( 'site/contact' );
  }

  public static function cookieInformation()
  {
    $tpl = new \Shared\Tpl\Tpl;
    return $tpl -> render( 'site/cookie-information' );
  }
}
