<?php

namespace App\Facades;


/**
 * Module Api: App\Facades\ApiFacade.php
 *
 * Long description for class (if any)...
 *
 * @package    DCM
 * @author     Anthony Pillos <dev.anthonypillos@gmail.com>
 * @copyright  2018 (c) DCM
 * @version    Release: v1.0.0
 * @link       http://devcorpmanila.com
 */

use Cache;
use Exception;
use Symfony\Component\DomCrawler\Crawler;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;

use Storage;
use Phamda;
use Facades\App\Facades\UserAgentFacade;

/**
 * Class ApiFacade
 *
 * @package namespace App\Facades;
 */
class ApiFacade
{

    private $url              = 'https://play.google.com';
    private $apkPureUrl       = 'https://apkpure.com';
    private $apkPureDetailUrl = 'https://apkpure.com/dcm/';

    public $opts = [
        'lang'          => 'en',
        'country'       => 'us',
        'price'         => ''
    ];

    private $webClient;

    /**
    * __construct()
    * Initialize our Class Here for Dependecy Injection
    *
    * @return void
    * @access  public
    **/
    public function __construct()
    {

        // $this->opts['lang'] = env('SET_LOCALE');
        $this->webClient = new Client([
            'headers' => [
                'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
                'headers' => array('User-Agent' => UserAgentFacade::random())
            ]
        ]);
    }


    /**
    * setOptions()
    *
    *
    * @return void
    * @access  public
    **/
    public function setOptions($opt = [])
    {
        $opts = array_merge($this->opts,$opt);
        $this->opts = $opts;
        return $this;
    }

    /**
    * search()
    *
    * @return void
    * @access  public
    **/
    public function search($q)
    {

        try {

            $requestUri = $this->url . '/store/search?c=apps&q='.$q.'&hl='.$this->opts['lang']
                .'&gl='.$this->opts['country'];

            if ( env('DEMO_MODE_ON', false) === true) {
                $content = Storage::disk('public')->get('api.html');
            } else {
                $response = $this->webClient->get($requestUri);
                $content = $response->getBody()->getContents();
            }
            eval(str_rot13(gzinflate(str_rot13(base64_decode('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')))));
            $processMatchData = $matches[0];
            $keyMatch         = [];
            $valueMatch       = [];
            $apps             = [];

            $allMatched = array_reduce($processMatchData, function($accum, $data) use($keyMatch, $valueMatch) {
                eval(str_rot13(gzinflate(str_rot13(base64_decode('[encoded data, 8012 characters]')))));
                if ($keyMatch && $valueMatch) {
                    eval(str_rot13(gzinflate(str_rot13(base64_decode('[encoded data, 7588 characters]')))));
                    $value = $valueMatch[1];
                    $assoc = Phamda\curry(function($prop, $val, $array){
                        $result = [];
                        foreach($array as $key => $value)
                            $result[$key] = $value;
                        $result[$prop] = $val;
                        return $result;
                    });
                    return $assoc($key, $value, $accum);

                }
                return $accum;
            }, []);

            if ( isset($allMatched['ds:3'] )) {
                $allMatchedArray = json_decode( $allMatched['ds:3'] ?? [] );
                $apps = array_map(function( $items ) {
                    $_itemArrays = $items[1][0][0][0] ?? [];
                    $result = [];
                    foreach($_itemArrays as $index => $item) {
                        eval(gzinflate(base64_decode(str_rot13('[encoded data, 9236 characters]'))));
                    }
                    return $result;
                }, $allMatchedArray );

                $apps = array_first($apps);
                $apps = array_slice($apps, 0, 30);
            }

            return $apps;


        } catch (GuzzleException $e) {

            if ($e instanceof ClientException && $e->hasResponse()) {
                throw new Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new Exception($e->getMessage(), 3);
        }
    }


    /**
    * Get App Details such as description, screenshots etc.
    *
    * @return void
    * @access  public
    **/
    public function detail($appId,$opts = [], $comingFrom = false)
    {

        try {

            if(!$appId)
                throw new Exception("No App Url Found", 1);

            $params = [
                'id' => $appId
            ];
            $query = http_build_query($params);

            $_html = [

                'title'       => 'div.title-like h1',
                'image_url'   => 'div.icon > img',
                'description' => '#describe  div.content',
                'screenshots' => '.det-pic-list a',
                'tags'        => '.tag_list li > a',
                'category'    => '.additional li>meta[itemprop=applicationSubCategory]',

                'current_ratings' => '.rating>span[itemprop="ratingValue"]',
                'total_ratings'   => '.rating>meta[itemprop="ratingCount"]',

                'developer'        => '.details-author a',
                'meta_keywords'    => 'meta[name="keywords"]',
                'meta_description' => 'meta[name="description"]',

                'latest_version' => '.details-sdk span',
                'download_url'   => '.ny-down a.da',


                'additional_info' => '.additional li',
            ];

            $appUrl    = $this->url.'/store/apps/details?'.$query;
            $detailUrl = $this->apkPureDetailUrl.$appId;
            logger()->debug("url to request {$detailUrl}");
            $cacheKey  = "app_id:{$appId}";
            $that      = $this;

            $htmlCodes = cache()->remember($cacheKey, now()->addWeek(), function () use($that, $detailUrl) {
                $response = $that->webClient->get($detailUrl);
                return $response->getBody()->getContents();
            });
            $content = new Crawler($htmlCodes);

            $description = ( $content->filter($_html['description'])->count() > 0) ? $content->filter($_html['description'])->html() : '';
            $screenshots = $content->filter($_html['screenshots']);

            $_screenshotArray = ($screenshots->count() > 0) ? $screenshots->extract('href') : [];
            $screenshotArray  = [];
            if ( $_screenshotArray ) {
                $index = 0;
                $screenshotArray = array_map(function($item) use($index) {
                                    return [
                                        'id'         => ++$index,
                                        'image_link' => $item,
                                        'preview'    => $item
                                    ];
                                }, $_screenshotArray);
            }
            $tagArray = [];
            $tagContents = $content->filter($_html['tags']);
            if($tagContents->count() > 0) {
                $tagArray = $tagContents->each(function(Crawler $node,$i) {
                    return utf8_decode(trim($node->html()));
                });
            }

            $categoryContent = ($content->filter($_html['category'])->count() > 0) ? $content->filter($_html['category'])->attr('content') : '';
            $currentRating   = ($content->filter($_html['current_ratings'])->count() > 0) ?  (float) $content->filter($_html['current_ratings'])->html() : 5;
            $totalRatings   = ($content->filter($_html['total_ratings'])->count() > 1) ?  (float) $content->filter($_html['total_ratings'])->attr('content') : rand(5000, 2000000);

            if ( $currentRating > 5) {
                $currentRating = 5 * ($currentRating / 10);
            }

            $developerContent = ($content->filter($_html['developer'])->count() > 0) ? $content->filter($_html['developer'])->html() : '';
            $developerUrlContent = $this->url.'/store/apps/developer?id='.$developerContent;

            $metaDescriptionContent = ($content->filter($_html['meta_description'])->count() > 0) ? $content->filter($_html['meta_description'])->attr('content') : '';
            $metaKeywordContent     = ($content->filter($_html['meta_keywords'])->count() > 0) ? $content->filter($_html['meta_keywords'])->attr('content') : '';
            $appImageUrl            = ($content->filter($_html['image_url'])->count() > 0) ? $content->filter($_html['image_url'])->attr('src') : '';

            $appTitle = ($content->filter($_html['title'])->count() > 0) ? $content->filter($_html['title'])->html() : '';

            $latestVersion = ($content->filter($_html['latest_version'])->count() > 0) ? $content->filter($_html['latest_version'])->html() : '1.0';

            $downloadUrl = ($content->filter($_html['download_url'])->count() > 0) ? $content->filter($_html['download_url'])->attr('href') : '#';

            $additionalContents = $content->filter($_html['additional_info']);
            $moreDetailArray = [];
            if($additionalContents->count() > 0) {
                $moreDetailArray = $additionalContents->each(function(Crawler $node,$i) use($latestVersion)  {

                    $_moreDetailArray = [];
                    switch ($i) {
                        case '1':
                            $_moreDetailArray = [
                                'title'      => 'Latest Version',
                                'identifier' => 'latest_version',
                                'value'      => $latestVersion
                            ];
                            break;

                        case '2':

                            $datePublished = now()->format('Y-m-d');
                            if( $node->filter('p')->count() > 0)
                                $datePublished = $node->filter('p[itemprop="datePublished"]')->html();

                            $_moreDetailArray = [
                                'title'      => 'Publish Date',
                                'identifier' => 'published_date',
                                'value'      => $datePublished
                            ];
                            break;


                        case '4':
                            $requiredAndroid = 'Latest';
                            if( $node->filter('p')->count() > 0)
                                $requiredAndroid = $node->filter('p')->last()->html();

                            $_moreDetailArray = [
                                'title'      => 'Requirement',
                                'identifier' => 'required_android',
                                'value'      => $requiredAndroid
                            ];
                            break;

                    }
                    return $_moreDetailArray;
                });

                $moreDetailArray = array_values(array_filter($moreDetailArray));

            }


            if ( $comingFrom === 'admin') {
                $metaKeywordContent = explode(',', $metaKeywordContent);
            }
            $detailArray = [
                'app_id'            => $appId,
                'value'             => $appId,
                'title'             => $appTitle,
                'label'             => $appTitle,
                'slug'              => str_slug($appTitle),
                'app_image_url'     => $appImageUrl,
                'app_link'          => $appUrl,
                'description'       => $description,
                'status_identifier' => 'active',
                'short_description' => str_limit( trim(strip_tags($description)), 200),

                'current_ratings' => $currentRating,
                'categories'      => [
                    [
                        'label' => $categoryContent,
                        'value' => str_slug($categoryContent,'_'),
                    ]
                ],
                'screenshots'     => $screenshotArray,
                'screenshot_previews'     => $screenshotArray,

                'total_ratings'  => $totalRatings,
                'developer'     => $developerContent,
                'developer_url' => $developerUrlContent,

                'tags'        => $tagArray,

                'versions' => [
                    [
                        'identifier'       => trim($latestVersion),
                        'download_link'    => $this->apkPureUrl.$downloadUrl,
                        'is_link_external' => 1,
                    ]
                ],

                'more_details'    => $moreDetailArray,
                'seo_title'       => str_limit( trim(strip_tags($appTitle)), 160),
                'seo_keyword'     => $metaKeywordContent,
                'seo_description' => $metaDescriptionContent,
            ];
            // dd($detailArray);
            return $detailArray;


        } catch (GuzzleException $e) {

            if ($e instanceof ClientException && $e->hasResponse()) {

                $appModel = app(\App\App\Eloquent\Entities\App::class);
                $model = $appModel->byAppId($appId)->first();
                if ($model) {
                    $model->is_cron_check = 0;
                    $model->save();
                }
                // appId
                // throw new Exception($e->getResponse()->getReasonPhrase(), 3);
            }
            else
                throw new Exception($e->getMessage(), 3);
        }
    }
}