<?php
use Monashee\PhpSimpleHtmlDomParser\PhpSimpleHtmlDomParser as DomParser;
use Carbon\Carbon;
class AnalyzeService
{
    private $response = [
        'status' => false
    ];

    private $site;
    private $protocol;
    private $redirectName = '';
    private $settings;

    public function __construct()
    {
        $this->settings = LSetting::getSettings();
    }

    public function prepare($url)
    {
        $url = Str::lower(trim($url));

        $protocol = get_protocol($url);
        $siteName = get_site_name($url);

        // Geçersiz Url
        if (!$siteName) {
            $this->response['message'] = [DBLang::get('invalid_website_url')];

            return $this->send();
        }

        // DBde var mı
        WebSite::removeWebSite($siteName); // Yarım kalanları çıkar
        $result = WebSite::siteExists($siteName);

        // var
        if ($result) {
            $this->response['redirect'] = URL::route('site.name', $siteName);
            $this->response['status'] = true;

            return $this->send();
        }

        $siteData = get_web_page($protocol, $siteName);

        // Web sitesinde farklı bir yönlendirme var mı?
        $responseHost = parse_url($siteData['header']['url'], PHP_URL_HOST);
        $responseHost = str_replace('www.', '', $responseHost);

        if($responseHost != $siteName){
            $redirectName = $responseHost;
        }

        if($siteData['source'] == ''){
            if(isset($redirectName)){
                $siteData['source'] = @file_get_contents($protocol . '://' . $redirectName);
            }else{
                $siteData['source'] = @file_get_contents($protocol . '://' . $siteName);
            }

        }

        if($siteData['source'] === false){
            $this->response['message'] = [ DBLang::get('not_response_error') ];
            return $this->send();
        }

        if($siteData['source'] == ''){
            $this->response['message'] = [ DBLang::get('analyse_error') . ' 001'];
            return $this->send();
        }

        $saveFile = @file_put_contents( public_path() . "/tmp/". md5($siteName) . ".txt", $siteData['source']);

        if(! $saveFile){
            $this->response['message'] = [ DBLang::get('analyse_error') . ' 002'];
            return $this->send();
        }

        // Website tablosuna ekliyoruz
        if(isset($redirectName)){
            $siteHash = WebSite::add($protocol, $siteName, $redirectName);
        }else{
            $siteHash = WebSite::add($protocol, $siteName);
        }

        // WebSite tablosuna da eklendiyse artık işlemleri başlatabiliriz.
        if ($siteHash) {
            $this->response['hash'] = $siteHash;
            $this->response['protocol'] = $protocol;
            $this->response['name'] = $siteName;
            $this->response['status'] = true;

            return $this->send();
        }else{
            $this->json['message'] = ['Error'];
            return $this->send();
        }
    }

    public function prepareReAnalyze($siteName){


        $site = WebSite::getSiteByName($siteName);

        // var
        if (! isset($site->id)) {
            $this->json['message'] = [ DBLang::get('analyse_error') ];
            return $this->send();
        }

        Keyword::where('site_id', $site->id)->delete();


        $siteData = get_web_page($site->protocol, $site->name);

        // Web sitesinde farklı bir yönlendirme var mı?
        $responseHost = parse_url($siteData['header']['url'], PHP_URL_HOST);
        $responseHost = str_replace('www.', '', $responseHost);

        if($responseHost != $site->name){
            $redirectName = $responseHost;
        }

        if($siteData['source'] == ''){
            if(isset($redirectName)){
                $siteData['source'] = @file_get_contents($site->protocol . '://' . $redirectName);
            }else{
                $siteData['source'] = @file_get_contents($site->protocol . '://' . $siteName);
            }

        }

        if($siteData['source'] === false){
            $this->response['message'] = [ DBLang::get('not_response_error') ];
            return $this->send();
        }

        if($siteData['source'] == ''){
            $this->response['message'] = [ DBLang::get('analyse_error') . ' 001'];
            return $this->send();
        }

        $saveFile = @file_put_contents( public_path() . "/tmp/". md5($siteName) . ".txt", $siteData['source']);

        if(! $saveFile){
            $this->response['message'] = [ DBLang::get('analyse_error') . ' 002'];
            return $this->send();
        }

        // WebSite tablosuna da eklendiyse artık işlemleri başlatabiliriz.

        $this->response['hash'] = $site->hash;
        $this->response['protocol'] = $site->protocol;
        $this->response['name'] = $site->name;
        $this->response['status'] = true;

        return $this->send();

    }

    public function analyze($type, $hash)
    {

        header('Content-Type: text/html; charset=utf-8');

        $siteData = WebSite::where('hash', $hash)->remember(5)->first();

        if(! $siteData){
            return $this->send();
        }

        if(! method_exists($this, $type) ){
            return $this->send();
        }

        $this->protocol = $siteData->protocol;
        $this->site   = $siteData->name;
        if($siteData->redirect_name != ''){
            $this->redirectName = $siteData->redirect_name;
        }

        $data = call_user_func([$this, $type]);

        if(is_array($data)){
            $siteData->$type = base64_encode(serialize($data));
        }

        if($type == 'whois'){
            $siteData->country_code = $data['server_country_short_name'];
            $siteData->country_name = $data['server_country_name'];
            $siteData->ip_address = $data['server_ip_address'];
        }

        if($type == 'meta'){
            $siteData->site_title = $data['site_title'];
            $siteData->site_description = $data['site_description'];
            $siteData->site_keywords = $data['site_keywords'];
        }

        if($type == 'search'){
            $siteData->google_rank = $data['google_pagerank'];
            $siteData->google_adsense_id = $data['google_adsense_id'];
        }

        if($type == 'alexa'){
            $siteData->alexa_rank = $data['global_rank'];
        }

        $siteData->save();

        $this->response['status'] = true;

        return $this->send();

    }

    public function save($hash)
    {
        $siteData = WebSite::getSiteByHash($hash);

        if (
            isset($siteData->id)
            && $siteData->html != ''
            && $siteData->dmoz != ''
            && $siteData->alexa != ''
            && $siteData->search != ''
            && $siteData->meta != ''
            && $siteData->social != ''
            && $siteData->whois != ''
            && $siteData->color != ''
        ) {

            //$site = WebSite::find($siteData->id);
            $siteData->status = 1;
            $siteData->analyzed_at = Carbon::now();

            if ($this->settings->after_a_website_analysis == 0) {
                $siteData->publish = 1;

                $websiteCountry = Country::getCountryByCode($siteData->country_code);

                $websiteCount = WebSite::getWebSiteCount($siteData->country_code);
                $websiteCount++;
                Country::updateWebSiteCount($websiteCountry->id, $websiteCount);

            }

            $siteData->save();

            if ($siteData->site_keywords != '') {
                $keywords = explode(',', $siteData->site_keywords);
                $keywords = array_map(function ($keyword) {
                    return trim(strtolower_tr($keyword));
                }, $keywords);

                $keywords = array_unique($keywords);

                Keyword::add($siteData->id, $keywords);
            }

            @unlink(public_path('tmp/' . md5($siteData->name) . '.txt'));
            @unlink(public_path('tmp/site_' . md5($siteData->name) . '.txt'));
            @unlink(public_path('tmp/text_' . md5($siteData->name) . '.txt'));

            $this->response['status'] = true;
            $this->response['name'] = $siteData->name;

        }else{
            $this->response['message'] = 'An error occurred during the analysis. Please re-analyze.';
        }

        return $this->send();
    }

    private function alexa()
    {
        $alexaData = new AlexaService($this->site, new DomParser);
        return $alexaData->get();
    }

    private function search()
    {
        $search = [];

        $googleData = new GoogleService($this->site, $this->getSource());
        $search = array_merge($search, $googleData->get());

        $bingData = new BingService($this->site, $this->settings->api_bing_account);
        $search = array_merge($search, $bingData->get());

        $yahooData = new YahooService($this->site, new DomParser);
        $search = array_merge($search, $yahooData->get());

        return $search;
    }

    private function dmoz()
    {
        $dmozData = new DmozService($this->site, new DomParser);
        return $dmozData->get();
    }

    private function social()
    {

        $socialData = new SocialService($this->protocol, $this->site);
        return $socialData->get();
    }

    private function whois()
    {
        $whoisData = new WhoisService($this->site);
        return $whoisData->get();
    }

    private function html()
    {
        $htmlData = new HtmlService($this->getSite(), $this->getSource(), new DomParser());
        return $htmlData->get();
    }

    private function meta()
    {
        $metaService = new MetaService( $this->getSource(), new DomParser() );
        return $metaService->get();
    }

    private function color()
    {
        if($this->settings->api_pagepeeker_status){
            $apiKey = $this->settings->api_pagepeeker_key;
        }else{
            $apiKey = '';
        }
        $colorService = new ColorService($this->site, new GetMostCommonColors(), $apiKey);
        return $colorService->get();
    }

    private function getSite()
    {
        if($this->redirectName != ''){
            $site = $this->redirectName;
        }else{
            $site = $this->site;
        }

        return $site;
    }

    private function getSource()
    {
        $file = public_path() . '/tmp/' . md5($this->site). '.txt';
        if(file_exists($file)){
            $source = fopen($file, 'r');
            $sourceContent = fread($source, filesize($file));
            fclose($source);
        }else{
            $sourceContent = '';
            $sourceContent = '';
        }
        return $sourceContent;
    }

    private function send()
    {
        return $this->response;
    }



}