<?php

namespace App\Http\Controllers\Parser;

use App\Http\Controllers\Controller;
use App\Price;
use App\Section;
use App\Services\Parser\PlanningService;
use Symfony\Component\DomCrawler\Crawler;

class ParseResidentComplexPlanningController extends Controller
{
//    const URL = 'https://novostroyki.lun.ua';

    const URL = 'https://lun.ua';

    /**
     * @param $page
     */
    public function index()
    {
        //кількість сторінок
        ////        $residentComplexes[] = $this->mainPage($page);

        for ($i = 1; $i <= 12; $i++) {
            dump('star parse');
            dump("page $i");
            $residentComplexes = [];
            $residentComplexes[] = $this->mainPage($i);
            dump('end parse');
            dump('Start write in file...');
            $filename = 'resident-complex-' . $i . '.json';
            $file = fopen(public_path() . '/parser/' . $filename, "w");
            fwrite($file, json_encode($residentComplexes));
            dump('write in file success!');
        }
    }

    public function mainPage($page)
    {
        $link = 'https://novostroyki.lun.ua/uk/новобудови-львова-та-області?page=' . $page;
        dump($link);
        $html = file_get_contents($link);
        $crawler = new Crawler(null, $link);
        $crawler->addHtmlContent($html, 'UTF-8');
        $home = $crawler->filterXPath('//div[@class="card"]');
        $links = $this->getLinks($home);
        $complex = [];
        foreach ($links as $href) {
//            if ($href == '/uk/жк-парус-city-львів')
//            if ($href == '/uk/жк-кам-янецький-львів')
//            if ($href == '/uk/жк-велика-британія-львів')
//                if ($href == '/uk/жк-ріел-сіті-львів')
                $complex[] = $this->indexPage($href);
        }

        return $complex;
    }

    /**
     * @param $href
     * @return array
     */
    public function indexPage($href)
    {
        set_time_limit(300);
        $link = self::URL . $href;
        $html = file_get_contents($link);
        dump($link);
        // Create new instance for parser.
        $crawler = new Crawler(null, $link);
        $crawler->addHtmlContent($html, 'UTF-8');
        //name
        $name = $crawler->filterXPath('//div[@class="BuildingContacts-title"]/h1')->text();
        try {
            $parseSections = $crawler->filterXPath('//div[@class="BuildingConstruction-items"]');
            $sections = $this->parseSection($parseSections);
        } catch (\Exception $exception) {
            $sections = [];
            dump($link);
        }

        try {
            $numRooms = $crawler->filter('section.BuildingPrices > div[data-table]');
            $buildingPrice = $this->getBuildingPrice($numRooms);
        } catch (\Exception $exception) {
            dump('building price not fount');
        }
//        //Галерея ЖК
//        $img = $crawler->filterXPath('//div[@class="BuildingGallery-image"]');
//        $images = $this->getImageValue($img);
        try {
            $planning = (new PlanningService())->getPlanning($link, $html);
        } catch (\Exception $exception) {
            dump('planning not fount');
        }
//        try {
//            $statusBulding = $crawler->filterXPath('//div[@class="BuildingConstruction-item"]')->text();
//
//            $status = explode("—", $this->myTrim($this->getBuildingStatus(explode("\n", $statusBulding))));
//        } catch (\Exception $exception) {
//            $status = [];
//            dump('Building Not found');
//            dump($link);
//        }
//        try {
//            $street = $crawler->filterXPath('//div[@class="BuildingLocation-address h2"]')->text();
//            $street = trim($street);
//        } catch (\Exception $exception) {
//            $street = "";
//            dump('Street not found');
//        }
//        try {
//            $cityOrRegion = $crawler->filterXPath('//div[@class="BuildingLocation-breadcrumbs"]/a[1]')->text();
//        } catch (\Exception $exception) {
//            $cityOrRegion = "";
//            dump('City not found');
//        }
//        try {
//            $district = $crawler->filterXPath('//div[@class="BuildingLocation-breadcrumbs"]/a[2]')->text();
//        } catch (\Exception $exception) {
//            $district = "";
//            dump('District not found');
//        }
//
//
//        try {
//            $developer = $crawler->filterXPath('//div[@class="BuildingContacts-developer-name"]/span')->text();
//        } catch (\Exception $exception) {
//            $developer = "";
//            dump('Not found developer');
//            dump($link);
//        }

//        try {
//            $credit = $crawler->filter('.BuildingCreditInstallments')->count() > 0 ? true : false;
//        } catch (\Exception $exception) {
//            dump('credit block not fount');
//        }
//
//        try {
//            $characteristic = $this->characteristic($crawler);
//        } catch (\Exception $exception) {
//            dump('characteristic not fount');
//        }
//
//
//        try {
//            //Координати
//            $cord = $crawler->filterXPath('//div[@class="BuildingLocation-route"]/a')->attr('href');
//            $cords = $this->arrayExplore($cord);
//        } catch (\Exception $exception) {
//            dump('coordinates not fount');
//        }
        //Характеристики ЖК
//        $characteristickeys = $this->getCharacteristicKey($crawler);
//        $characteristicValues = $this->getCharacteristic($crawler);
//
//        $characteristicKeys = [];
//        foreach ($this->getCharacteristicKey($crawler) as $value) {
//            $characteristicKeys[] = $value[0];
//        }
//
//        $characteristicValues = [];
//        foreach ($this->getCharacteristic($crawler) as $value) {
//            $characteristicValues[] = $value[0];
//        }
//
//        $characteristic = array_combine($characteristicKeys, $characteristicValues);
        $complex = [
            'section' => $sections,
//            'status_build' => $status,
//            'url' => $href,
//            'city' => $cityOrRegion,
//            'district' => $district,
//            'street' => $street,
//            'developer' => $developer,
            'name' => $name,
//            'siteLink' => $siteLink,
//            'images' => null,
//            'cords' => isset($cords) ? $cords : false,
//            'credit' => isset($credit) ? $credit : false,
//            'characteristic' => isset($characteristic) ? $characteristic : null,
//            'price' => $firstResult,
//            'plans' => $finalResult,
            'planning' => isset($planning) ? $planning : [],
//            'dropDownPlans' => $dropDownResult,
//            'dropDownWithHeaderResult' => $dropDownWithHeaderResult,
//            'process_build' => isset($process_build) ? $process_build : [],
            'building_price' => $buildingPrice
        ];

        return $complex;
    }

    public function characteristic(Crawler $crawler)
    {
        $data = [];
        $characteristicNodes = $crawler->filter('.BuildingAttributes-items')->children();
        foreach ($characteristicNodes as $key => $node) {
            $characteristicElement = new Crawler($node);
            $name = $characteristicElement->filter('.BuildingAttributes-name')->count() > 0 ? $characteristicElement->filter('.BuildingAttributes-name')->text() : "";
            $value = $characteristicElement->filter('.BuildingAttributes-value')->count() > 0 ? $characteristicElement->filter('.BuildingAttributes-value')->text() : "";
            $strToLowerName = !empty($name) ? mb_strtolower($name) : null;
            $strToLowerValue = !empty($value) ? mb_strtolower($value) : null;
            if (!empty($strToLowerName) && !empty($strToLowerValue)) {
                $data[$strToLowerName] = $strToLowerValue;
            }
        }

        return $data;
    }

    private function getBuildingStatus(array $states, $checkNumber = false)
    {
        foreach ($states as $status) {
            if ($checkNumber) {
                if (!empty($status)
                    && (preg_match("/[0-9]$/", $status) || 'дата введення в експлуатацію не заявлена')) {
                    return $status;
                }
            } else {
                if (!empty($status)) {
                    return $status;
                }
            }
        }

        return "";
    }

    private function getBuildingPrice(Crawler $numRooms): array
    {
        $numbersOfRoom = [];
        foreach ($numRooms as $key => $numRoom) {
            $itemCrawler = new Crawler($numRoom);
            $header = $itemCrawler->filter('div.BuildingPrices-queues')->count() > 0 ? $itemCrawler->filter('div.BuildingPrices-queues')->text() : 'general';
            $priceElements = $itemCrawler->filter('.BuildingPrices-row')->count() > 0 ? $itemCrawler->filter('.BuildingPrices-row') : [];
            $numbersOfRoom[$key] = [
                'header' => $header
            ];
            foreach ($priceElements as $priceElement) {
                $priceElementsCrawler = new Crawler($priceElement);
                $element = $priceElementsCrawler->filter('.BuildingPrices-cell');
                $numbersOfRoom[$key]['price'][] = $this->getBulidingTable($element);
            }
        }

        return $numbersOfRoom;
    }

    private function getBulidingTable(Crawler $table): array
    {
        $tableData = [];
        $isPricesExist = $table->count() >= 5 ? true : false;
        if ($isPricesExist) {
            $tableData = [
                'room' => $table->eq(1)->count() ? trim($table->eq(1)->text()) : "",
                'full_price' => $table->eq(2)->count() ? trim($table->eq(2)->text()) : "",
                'space' => $table->eq(3)->count() ? trim($table->eq(3)->text()) : "",
                'price_per_square_meter' => $table->eq(4)->count() ? trim($table->eq(4)->text()) : ""
            ];
        }

        return $tableData;
    }

    private function getImageRooms($numRooms)
    {
        $values = [];
        try {
            foreach ($numRooms as $item) {
                $itemCrawler = new Crawler($item);
                $values[] = $itemCrawler->filterXPath('//div[@class="BuildingPrices-cell -img"]/img')->attr('data-src');
            }
        } catch (\Exception $exception) {
            dump($exception->getMessage());
        }

        return $values;
    }

    private function parseSection($sections)
    {
        $values = [];
        try {
            foreach ($sections->children() as $key => $item) {
                $itemCrawler = new Crawler($item);
//                $parse = $itemCrawler->filterXPath('//div')->text();
                if ($itemCrawler->filter('div.BuildingConstruction-info')->count() > 0) {
                    $parse = $itemCrawler->filter('div.BuildingConstruction-info')->children();
                    $parseCount = $itemCrawler->filter('div.BuildingConstruction-info')->count();
                    if ($parseCount > 1) {
                        $values[$key]['status'] = $this
                            ->myTrim($this->getBuildingStatus(explode("\n", $parse->getNode(0)->textContent)));
                        $values[$key]['quarterly'] = $this
                            ->myTrim($this->getBuildingStatus(explode("\n", $parse->getNode(1)->textContent), true));
                    } elseif ($parseCount > 0) {
                        $values[$key]['status'] = $this
                            ->myTrim($this->getBuildingStatus(explode("\n", $parse->getNode(0)->textContent)));
                    }
                }
            }
        } catch (\Exception $exception) {
            dump('PARSE Section not found');
        }

        return $values;
    }

    private function parseBuildingProcessPage(string $content): array
    {
        $match = [];
        preg_match_all('/\[(.*)\]/', $content, $match);
        if (!isset($match[0])) {
            return [];
        }
        $data = json_decode($match[0][14], true);
        if (isset($data[0]) && !empty($data[0])) {
            return $data;
        }

        return [];
    }

    public function getCharacteristicKey($key)
    {
        $table = $key->filter('table')->filter('tr')->each(function ($tr, $i) {
            return $tr->filter('th')->each(function ($td, $i) {
                return trim($td->text());
            });
        });

        return $table;
    }

    public function getCharacteristic($key)
    {
        $table = $key->filter('table')->filter('tr')->each(function ($tr, $i) {
            return $tr->filter('td')->each(function ($td, $i) {
                return trim($td->text());
            });
        });

        return $table;
    }

    public function getValue($keys)
    {
        $values = [];
        foreach ($keys as $item) {
            $itemCrawler = new Crawler($item);
            $value = $itemCrawler->filterXPath('//div')->text();
            $values[] = $value;
        }

        return $values;
    }

    public function getImageValue($images)
    {
        $values = [];
        foreach ($images as $item) {
            $itemCrawler = new Crawler($item);
            $value = $itemCrawler->filterXPath('//img')->attr('data-srcset');
            if ($value === null) {
                $value = $itemCrawler->filterXPath('//img')->attr('data-flickity-lazyload-src');
            } else {
                $link = explode(" ", $value);
                if (count($link) > 0) {
                    $value = $link[0];
                }
            }
            $values[] = $value;
        }

        return $values;
    }

    public function arrayExplore($cord)
    {
        $cord_str = substr($cord, 51);
        $explore_cords = explode(",", $cord_str);
        $cords = [
            'latitude' => $explore_cords[0],
            'longitude' => $explore_cords[1]
        ];

        return $cords;
    }

    public function getLinks($links)
    {
        $values = [];
        foreach ($links as $item) {
            $itemCrawler = new Crawler($item);
            $value = $itemCrawler->filterXPath('//a')->attr('href');
            $values[] = $value;
        }

        return $values;
    }

    public function getPlanRooms($url)
    {
        $html = file_get_contents(self::URL . $url);
        $crawler = new Crawler();
        $crawler->addHtmlContent($html, 'UTF-8');
        $imgLinks = $crawler->filterXPath('//div[@class="PlansCard-image"]');
        $sizeSquere = $crawler->filterXPath('//div[@class="PlansCard-info"]');
        $plans = $this->getOneImagePlan($imgLinks, $sizeSquere);

//
        return $plans;
    }

    public function processBuild($link)
    {
        $page = $link . '/хід-будівництва';
        try {
            $html = file_get_contents($page);
        } catch (\Exception $exception) {
            return [];
        }
        $arrayOptions = $this->parseBuildingProcessPage($html);
        $courseOfConstructionArray = [];
        foreach ($arrayOptions as $key => $arrayOption) {
            $albums = isset($arrayOption['albums']) ? $arrayOption['albums'] : [];
            foreach ($albums as $album) {
                $images = isset($album['images']) ? $album['images'] : [];
                foreach ($images as $image) {
                    list($month, $year) = $this->getMonthAndYearFromConrseOfConstruction($image['date']);
                    if (!empty($month) && !empty($year)) {
                        $courseOfConstructionArray[$year][$month][] = [
                            'normal' => $image['normal'],
                            'large' => $image['large']
                        ];
                    }
                }
            }
        }

        return $courseOfConstructionArray;
    }

    private function getMonthAndYearFromConrseOfConstruction($format)
    {
        $date = explode(" ", trim($format));
        $monthNumber = '';
        $year = count($date) > 1 ? $date[1] : '';
        $dateMonths = [
            'січень' => 1,
            'лютий' => 2,
            'березень' => 3,
            'квітень' => 4,
            'травень' => 5,
            'червень' => 6,
            'липень' => 7,
            'серпень' => 8,
            'вересень' => 9,
            'жовтень' => 10,
            'листопад' => 11,
            'грудень' => 12
        ];
        foreach ($dateMonths as $month => $numMonth) {
            if ($month == $date[0]) {
                $monthNumber = $numMonth;
            }
        }

        return [$monthNumber, $year];
    }

    private function myTrim($str)
    {
        return trim(preg_replace('/[[:cntrl:]]/', '', $str));
    }
}
