<?php

namespace App\Console\Commands;

use App\Models\Article;
use App\Models\MstStore;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\Console\Commands\Converters\SuumoLandConverter;
use App\Console\Commands\Converters\SuumoHouseConverter;
use App\Console\Commands\Converters\SuumoMansionConverter;

class PostArticleToSuumo extends Command
{
    protected $signature = 'batch:suumo {id?} {cid?}';

    protected $description = 'Command description';

    const ACCOUNT = 't06889200001';
    const PASSWORD = 'zuka-32412019';

    const DIRECTORY = 'import/suumo';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $buildingId = $this->argument('id');
        $companyId = $this->argument('cid');

        $article = Article::where('building_id', $buildingId)
            ->first();

        $this->login(self::ACCOUNT, self::PASSWORD);

        if(in_array($article->property, [1, 2, 3])) {
           $this->updateOrCreateLand($article);
        } elseif(in_array($article->property, [4, 5])) {
           $this->updateOrCreateHouse($article);
        } elseif($article->property == null) {
            $this->updateOrCreateMansion($article);
        }
    }

    private function initDefaultCurl()
    {
        $curl = curl_init();

        $userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0';
        $cookiePath = Storage::path(self::DIRECTORY.'/cookie.txt');

        touch($cookiePath);

        curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiePath);
        curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiePath);
        curl_setopt($curl, CURLOPT_HEADER, true);

        return $curl;
    }

    private function login($account, $password)
    {
        $url = "https://manager.suumo.jp/chukai/login/login";

        $data = [
            'j_username' => $account, 'j_password' => $password,
            'id' => $account, 'pass' => $password,
        ];

        $curl = $this->initDefaultCurl();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

        return curl_exec($curl);
    }

    private function goToPage($url, array $data)
    {
        $curl = $this->initDefaultCurl();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);

        return curl_exec($curl);
    }

    private function updateOrCreateLand($article)
    {
        $createMansionUrl = "https://manager.suumo.jp/chukai/tn01Xx0104.do";

        $dataToPage = [
            'TB' => 12, 'BKTB' => 10, 'hanKubun' => '1T'
        ];

        if($article->suumo_no != null) {
            $dataToPage['bukkenCd'] = $article->suumo_no;
        }

        $response = $this->goToPage($createMansionUrl, $dataToPage);

        $hiddenInputs = $this->parseHiddenInputInMainForm($response);

        if(empty($hiddenInputs)) {
            $this->login(self::ACCOUNT, self::PASSWORD);
            $this->updateOrCreateLand($article);
        }

        $defaultData = $this->getDefaultRequestFromFile('land.json');
        $articleData = SuumoLandConverter::convert($article);

        $data = array_merge($defaultData, $hiddenInputs, $articleData);

        $url = 'https://manager.suumo.jp/chukai/tn01Xx0104/update1K';
        $referer = 'https://manager.suumo.jp/chukai/tn01Xx0104.do';

        $response = $this->submit($url, $referer, $data);

        $suumoNo = $this->getSuumoNo($response);

        if(empty($article->suumo_no) && $suumoNo) {
            $article->update(['suumo_no' => $suumoNo]);

            Log::info("Success import land suumo");
        }
    }

    private function updateOrCreateHouse($article)
    {
        $createMansionUrl = "https://manager.suumo.jp/chukai/tn01Xx0104.do";

        $dataToPage = [
            'TB' => 11, 'BKTB' => 10, 'hanKubun' => '1K'
        ];

        if($article->suumo_no != null) {
            $dataToPage['bukkenCd'] = $article->suumo_no;
        }

        $response = $this->goToPage($createMansionUrl, $dataToPage);

        $hiddenInputs = $this->parseHiddenInputInMainForm($response);

        if(empty($hiddenInputs)) {
            $this->login(self::ACCOUNT, self::PASSWORD);
            $this->updateOrCreateLand($article);
        }

        $defaultData = $this->getDefaultRequestFromFile('house.json');
        $articleData = SuumoHouseConverter::convert($article);

        $data = array_merge($defaultData, $hiddenInputs, $articleData);

        $url = 'https://manager.suumo.jp/chukai/tn01Xx0104/update1K';
        $referer = 'https://manager.suumo.jp/chukai/tn01Xx0104.do';

        $response = $this->submit($url, $referer, $data);

        $suumoNo = $this->getSuumoNo($response);

        if(empty($article->suumo_no) && $suumoNo) {
            $article->update(['suumo_no' => $suumoNo]);

            Log::info("Success import house suumo");
        }
    }

    private function updateOrCreateMansion($article)
    {
        $createMansionUrl = "https://manager.suumo.jp/chukai/tn01Xx0104.do";

        $dataToPage = [
            'TB' => 13, 'BKTB' => 10, 'hanKubun' => '1M'
        ];

        if($article->suumo_no != null) {
            $dataToPage['bukkenCd'] = $article->suumo_no;
        }

        $response = $this->goToPage($createMansionUrl, $dataToPage);

        $hiddenInputs = $this->parseHiddenInputInMainForm($response);

        $defaultData = $this->getDefaultRequestFromFile('mansion.json');
        $articleData = SuumoMansionConverter::convert($article);

        $data = array_merge($defaultData, $hiddenInputs, $articleData);

        $url = 'https://manager.suumo.jp/chukai/tn01Xx0104/update1M';
        $referer = 'https://manager.suumo.jp/chukai/tn01Xx0104.do';

        $response = $this->submit($url, $referer, $data);

        $suumoNo = $this->getSuumoNo($response);

        if(empty($article->suumo_no) && $suumoNo) {
            $article->update(['suumo_no' => $suumoNo]);

            Log::info("Success import mansion suumo");
        }
    }

    private function parseHiddenInputInMainForm($response)
    {
        $formPattern = '/<form name="tn01Xx0104ActionForm" id="mainForm" .*?>(.*?)<\/form><form name="bukkenIdoKeidoCache">/s';
        preg_match($formPattern, $response, $formMatches);

        if(count($formMatches) < 2) return [];

        $hiddenInputPattern = '/<input type="hidden" name="(?<name>.*?)" value="(?<value>.*?)".*?>/';
        preg_match_all($hiddenInputPattern, $formMatches[0], $inputMatches,PREG_SET_ORDER);

        if(count($inputMatches) < 2) return [];

        return collect($inputMatches)
            ->pluck('value', 'name')
            ->toArray();
    }

    private function getSuumoNo($response)
    {
        $suumoNoPattern = '/<span class="tar b">物件CD：(.*?)<\/span>/s';
        preg_match($suumoNoPattern, $response, $suumoNoMatches);

        return count($suumoNoMatches) >= 2 ? $suumoNoMatches[1] : null;
    }

    private function getDefaultRequestFromFile($filename)
    {
        $content = Storage::get(self::DIRECTORY.'/'.$filename);

        return json_decode($content, true);
    }

    private function submit($url, $referer, array $data)
    {
        $curl = $this->initDefaultCurl();

        $headers = [
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Language: ja,en-US;q=0.9,en;q=0.8', 'Cache-Control: max-age=0', 'Connection: keep-alive',
            'Host: manager.suumo.jp',
            'Origin: https://manager.suumo.jp',
            'Sec-Fetch-Mode: navigate',
            'Sec-Fetch-Site: same-origin',
            'Sec-Fetch-User: ?1',
            'Upgrade-Insecure-Requests: 1'
        ];

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($curl, CURLOPT_REFERER, $referer);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLINFO_HEADER_OUT, true);
        curl_setopt($curl, CURLOPT_MAXREDIRS,10);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($curl, CURLOPT_AUTOREFERER,true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

        return curl_exec($curl);
    }
}
