<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\FileUtil;
use App\Models\Article;
use App\Models\RelationArticleFacility;
use App\Models\Review;
use App\Models\User;
use App\Services\CompanyApiService;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use App\Models\Facility;
use App\Models\MstPrefecture;
use App\Models\MstCity;
use App\Models\MstTown;
use App\Models\MstFacilityType;
use Illuminate\Support\Facades\Cookie;
use GuzzleHttp\Psr7;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class FacilityController extends Controller
{
    /**
     * 施設検索条件設定画面の表示
     * @return string
     */
    public function show()
    {
        $data['active'] = 'search';
        // 都道府県マスターを取得
        $data['pref'] = array_merge([['name' => '未選択', 'code' => '0']], MstPrefecture::getData());

        $defaultPrefCode = array_get(array_first($data['pref']), 'code');
        if (auth()->user()->company_id === 1) {
            $city = MstCity::getData($defaultPrefCode, null, auth()->user()->company_id);
            /*$num = count($city);
            for ($i = 0; $i < ($num - 1); $i++) {
                for ($j = $i + 1; $j < $num; $j++) {
                    if (isset($city[4])) {
                        $l1 = $city[4];
                        $city[4] = $city[2];
                        $city[2] = $l1;
                    }
                }
            }

            $city2 = $city;
            $num = count($city2);
            for ($i = 0; $i < ($num - 1); $i++) {
                for ($j = $i + 1; $j < $num; $j++) {
                    if (isset($city2[4])) {
                        $l2 = $city2[4];
                        $city2[4] = $city2[3];
                        $city2[3] = $l2;
                    }
                    if (isset($city2[45])) {
                        $l3 = $city2[45];
                        $city2[45] = $city2[5];
                        $city2[5] = $l3;
                    }
                }
            }*/
            $data['city'] = $city;
        } else {
            $data['city'] = MstCity::getData($defaultPrefCode, null, auth()->user()->company_id);
        }
        $data['town'] = [];

//        $data['facility_property'] = [
//            [
//                "name" => "買物施設",
//                "code" => 1
//            ],
//            [
//                "name" => "教育施設",
//                "code" => 2
//            ],
//            [
//                "name" => "公共・金融施設",
//                "code" => 3
//            ],
//            [
//                "name" => "公園・その他",
//                "code" => 4
//            ]
//        ];
        $data['facility_property'] = MstFacilityType::getData();
        return view('admin.pages.facility', $data);
    }

    public function getNearFacility(Request $request)
    {
        $buildingId = $request->get("building_id");
        $article = Article::where("building_id", $buildingId)->first();

        $articleEmpty = is_null($article) || empty($article);

        abort_if($articleEmpty, 404);

        $km = $request->get("km");

        $latitude = $article->lat;
        $longitude = $article->lng;

        if($latitude == null || $longitude == null){
            return 'false';
        }

        $facilityed = RelationArticleFacility::getFacilityDataByRainsNo($buildingId);
        $ar = [];
        foreach ($facilityed as $faed){
            $ar[] = $faed->facility_id;
        }
        if(!empty($ar)){
            $facilities = Facility::location($latitude, $longitude, $km)->whereNotIn('id', $ar)->get();
        }else{
            $facilities = Facility::location($latitude, $longitude, $km)->get();
        }

        $origins = $latitude.','.$longitude;
        $facilitiesChunk = $facilities->chunk(100);
        $distancesArr = [];
        $distances = [];
        $check_google = Cookie::get('google_distance_'.$buildingId);
        foreach ($facilitiesChunk as $facility) {
            $destinations = "";
            foreach ($facility as $key => $f) {
                if(!empty($check_google)){
                    $check_googles = \GuzzleHttp\json_decode($check_google);
                    $got = false;
                    foreach ($check_googles as $cg){
                        $got = false;
                        if($cg->fid == $f->id){
                            $facility[$key]->distance = $cg->distance;
                            $facility[$key]->duration = $cg->duration;
                            $got = true;
                            break;
                        }
                    }
                    if($got == false){
                        if ($key == 0) {
                            $destinations.= $f->lat.','.$f->lng;
                        } else {
                            $destinations.= "|".$f->lat.','.$f->lng;
                        }
                    }
                }else{
                    if ($key == 0) {
                        $destinations.= $f->lat.','.$f->lng;
                    } else {
                        $destinations.= "|".$f->lat.','.$f->lng;
                    }
                }
            }
            if(!empty($destinations)){
                $distancesList = $this->getMultipleDistanceFromGoogle($origins, $destinations);
                if(isset($distancesList->error_message)){
                    return $distancesList->error_message;
                }
                $distances = Arr::first(Arr::first($distancesList->rows));
                $distancesArr = array_merge($distancesArr, $distances);
            }
        }
        $facilities->map(function ($item, $key) use ($latitude, $longitude, $distancesArr, $check_google) {
            $item['distance'] = "";
            $item['duration'] = "";
            if(!empty($check_google)){
                $check_googles = \GuzzleHttp\json_decode($check_google);
                foreach ($check_googles as $cg){
                    if($cg->fid == $item['id']){
                        $item['distance'] = $cg->distance;
                        $item['duration'] = $cg->duration;
                        break;
                    }
                }
            }
            if($item['distance']==''){
                try {
                    $duration = ceil($distancesArr[$key]->distance->value / 80);
                    $distance = $distancesArr[$key]->distance->value;

                    $item['distance'] = $distance;
                    $item['duration'] = $duration;
                } catch (\Exception $exception) {
                } catch (\Error $error) {
                }
            }
            return $item;
        });
        $facilities = $facilities->sortBy("distance");
        $google_distance = array();
        foreach ($facilities->values()->all() as $i => $f){
            if(empty($facilities->values()->all()[$i]['file_path'])){
                $facilities->values()->all()[$i]['file_path'] = '../../img/noimage2.jpg';
            }
            $google_distance[] = [
                'fid'       =>  $f['id'],
                'distance'  =>  $f['distance'],
                'duration'  =>  $f['duration']
            ];
        }

        if(Cookie::get('google_distance_'.$buildingId) !== null){
            Cookie::queue(Cookie::forget('google_distance_'.$buildingId));
        }
        Cookie::queue('google_distance_'.$buildingId, \GuzzleHttp\json_encode($google_distance), '180');

        return $facilities->values()->all();
    }

    private function getDistanceFromGoogle($latitudeOrigin, $longitudeOrigin, $latitudeDestination, $longitudeDestination)
    {
        $key = env("GOOGLE_DISTANCE_KEY", "AIzaSyAvLqHslDD75YM0_3ZZYv_C9lYVKNLR_i0");
        $url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&mode=walking&origins={$latitudeOrigin},{$longitudeOrigin}&destinations={$latitudeDestination},{$longitudeDestination}&key={$key}";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        $response = curl_exec($curl) or die('error ' . curl_error($curl));
        curl_close($curl);

        return json_decode($response);
    }

    private function getMultipleDistanceFromGoogle($origins, $destinations)
    {
        $key = env("GOOGLE_DISTANCE_KEY", "AIzaSyAvLqHslDD75YM0_3ZZYv_C9lYVKNLR_i0");
        $url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&mode=walking&origins={$origins}&destinations={$destinations}&key={$key}";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        $response = curl_exec($curl) or die('error ' . curl_error($curl));
        curl_close($curl);

        return json_decode($response);
    }

    /**
     * 施設検索条件設定画面の表示
     * @return string
     */
    public function listShow(Request $request)
    {
        $data['active'] = 'search';
        // 都道府県マスターを取得
        $data['pref'] =  array_merge([['name' => '未選択', 'code' => '0']], MstPrefecture::getData());
        //$data['city'] = MstCity::getData(config('const.DEFAULT_PREF'));
        $data['city'] = MstCity::getData($request->get('address1'));
        $data['town'] = [];
        if (!empty($request->get('address2'))) {
            $defaultPrefCode = array_get(array_first($data['pref']), 'code');
            $data['town'] = MstTown::getData($defaultPrefCode, $request->get('address2'));
        }

        $data['facility_property'] = MstFacilityType::getData();
        // 検索条件
        $data['search_name'] = $request->search_name;
        $data['search_id'] = $request->search_id;
        $data['search_property'] = $request->search_property;
        $data['address1'] = $request->address1;
        $data['address2'] = $request->address2;
        $data['address3'] = $request->address3;


        // 施設を取得
        $facility = Facility::getDataByCondition($request->all(), 20, 1);
        foreach ($facility as &$row) {
            $property = MstFacilityType::getDataByCode($row->kind);
            if (!empty($property)) {
                $row['property'] = $property->name;
            } else {
                $row['property'] = '-';
            }

            $row->file_path = str_replace('public', '/storage', $row->file_path);

        }

        // 表示中のページの最初のアイテムのインデックス番号
        $first = $facility->firstItem();

        // 表示中のページの最後のアイテムのインデックス番号
        $last = $facility->lastItem();

        $data['facility_list'] = $facility;
        $data['first'] = $first;
        $data['last'] = $last;

        $data['search'] = $request->all();

        $data['user'] = Auth::user();
        return view('admin.pages.facility', $data);
    }

    /**
     * 施設検索結果画面の表示
     * @return string
     */
    public function list(Request $request)
    {
        $data['active'] = 'list';

        $q = Facility::query();

        if (isset($request->id)) {
            $q->where('id', '=', $request->id);
        }
        if (isset($request->name)) {
            $q->where('name', 'LIKE', '%' . $request->name . '%');
            $q->orWhere('name_kana', 'LIKE', '%' . $request->name . '%');
        }
        if (isset($request->facility_charge)) {
            $q->where('facility_charge', 'LIKE', '%' . $request->name . '%');
            $q->orWhere('facility_charge_kana', 'LIKE', '%' . $request->name . '%');
        }
        if (isset($request->facility_tel)) {
            $q->where('facility_tel', '=', $request->facility_tel);
        }
        if (isset($request->facility_fax)) {
            $q->where('facility_fax', '=', $request->facility_fax);
        }
        $result = $q->get();
        $data['list'] = $result;
        return view('admin.pages.facility-list', $data);
    }

    /**
     * 施設登録画面の表示
     * @return string
     */
    public function registFacility(Request $request)
    {
        $data['active'] = 'regist';
        $data['kind'] = MstFacilityType::getData();
        $data['pref'] = MstPrefecture::getData();

        $user = Auth::user();
        $defaultPrefCode = array_get(array_first($data['pref']), 'code');
        if ($user->company_id === 1) {
            $city = MstCity::getData($defaultPrefCode, null, $user->company_id);
            $num = count($city);
            /*for ($i = 0; $i < ($num - 1); $i++) {
                for ($j = $i + 1; $j < $num; $j++) {
                    if (isset($city[4])) {
                        $l1 = $city[4];
                        $city[4] = $city[2];
                        $city[2] = $l1;
                    }
                }
            }

            $city2 = $city;
            $num = count($city2);
            for ($i = 0; $i < ($num - 1); $i++) {
                for ($j = $i + 1; $j < $num; $j++) {
                    if (isset($city2[4])) {
                        $l2 = $city2[4];
                        $city2[4] = $city2[3];
                        $city2[3] = $l2;
                    }
                    if (isset($city2[45])) {
                        $l3 = $city2[45];
                        $city2[45] = $city2[5];
                        $city2[5] = $l3;
                    }
                }
            }*/
            $data['city'] = $city;
        } else {
            $data['city'] = MstCity::getData($defaultPrefCode, null, $user->company_id);
        }
        $data['town'] = '';
        if(!empty($data['pref'])){
            $data['town'] = MstTown::getData($data['pref'][0]['code'], $data['city'][0]['code']);
        }

        $all = $request->all();
        $data['user'] = Auth::user();
        if($user->company_id == 3) {
            $data['staff_list'] = User::getData($user->company_id);
            return view('admin.pages.facility-regist-3', $data);
        }
        return view('admin.pages.facility-regist', $data);
    }

    /**
     * 施設検索結果画面の表示
     * @return string
     */
    public function regist(Request $request, CompanyApiService $apiService)
    {
        $user = Auth::user();
        if($user->company_id == 3){
            $cols = ['name', 'kind', 'zip', 'address1', 'address2', 'address3', 'address4', 'lat', 'lng', 'memo', 'staff', 'tag', 'campaign', 'type', 'open', 'peak', 'holiday', 'budget', 'reserve' , 'url', 'payment', 'parking', 'access', 'menu', 'comment', 'target', 'breadth', 'facility_other',
                'p1_comment', 'p2_comment', 'p3_comment', 'p4_comment', 'p5_comment', 'p6_comment', 'kokai', 'category', 'area', 'tel', 'parking'];
        }else{
            $cols = ['name', 'kind', 'zip', 'address1', 'address2', 'address3', 'address4', 'lat', 'lng', 'memo'];
        }


//      dd($request->all());
//      $images = $request->photo_images;
//        $not_save = explode(',', $request->not_save_img_id);
//        if (count($not_save) == 1 && $not_save[0] == "") {
//            $not_save = [];
//        }

        $save_data = [];
        foreach ($cols as $col) {
            $save_data[$col] = $request->{$col};
            if($user->company_id == 3){
                if($col == 'facility_other'){
                    $save_data['facility'] = $request->{$col};
                }
            }
        }
        $save_data['company_id'] = $user->company_id;
        if($user->company_id == 3) {
            unset($save_data['facility_other']);
        }

        $facility = new Facility;
        $facility->fill($save_data)->save();
        if (isset($request->photo_image) || isset($request->file_single_input)){
            $file = $request->photo_image ?? $request->file_single_input;
            $path = FileUtil::orientateImage($file, 'public/company_'.\auth()->user()->company_id.'/facility');
            Facility::where('id', $facility->id)->update(['file_path' => $path]);
            if($user->company_id == 1){
                $this->uploadRemoteMic($path);
            }
        }

//        if (!empty($images)) {
//            foreach ($images as $key => $obj) {
//                $save_data = [];
//                foreach ($cols as $col) {
//                    $col_name = $col . '_' . $key;
//                    $save_data[$col] = $request->{$col_name};
//                    if($user->company_id == 3){
//                        if($col == 'facility_other'){
//                            $save_data['facility'] = $request->{$col_name};
//                        }
//                    }
//                }
//                $save_data['company_id'] = $user->company_id;
//                if($user->company_id == 3) {
//                    unset($save_data['facility_other']);
//                }
//                $facility = new Facility;
//                $facility->fill($save_data)->save();
//                if (!in_array($key, $not_save)) {
//                    $extension = $obj->getClientOriginalExtension();
//                    $path = 'public/company_'.$user->company_id.'/facility/facility_image_' . $facility->id . '.' . $extension;
//                    $this->saveImage($obj, $path);
//                    Facility::where('id', $facility->id)->update(['file_path' => $path]);
//                    if($user->company_id == 1){
//                        $this->uploadRemoteMic($path);
//                    }
//                }
//            }
//        } else {
//            $facility = new Facility;
//            $request->merge(['company_id' => $user->company_id]);
//            $facility->fill($request->all())->save();
//        }

        if($user->company_id == 3) {
            for ($i = 1; $i <= 6; $i ++ ){
                if (isset($request['photo'.$i])) {
                    $path = FileUtil::orientateImage($request['photo'.$i], 'public/company_'.\auth()->user()->company_id.'/facility');
                    Facility::where('id', $facility->id)->update(['photo'.$i => $path]);
                    if ($user->company_id == 1) {
                        $this->uploadRemoteMic($path);
                    }
                } else if ($request['del_photo'.$i] == 1) {
                    Facility::where('id', $facility->id)->update(['photo'.$i => null]);
                }
            }
        }

        $request->session()->flash('message', 'この施設を登録・保存しました。');
        $data_facility = Facility::where('id', $facility->id)->first();
        $apiService->registFacility($data_facility);
        return redirect("/admin/editFacility/" . $facility->id)->with('message', '施設を登録しました。');
    }

    /**
     * 施設検索結果画面の表示
     * @return string
     */
    public function editFacility(Request $request)
    {

        $data['active'] = 'regist';
        $id = $request->id;

        $facility = Facility::getDataById($id);
        $facility->file_path = str_replace('public', '/storage', $facility->file_path);
        $facility->photo1 = str_replace('public', '/storage', $facility->photo1);
        $facility->photo2 = str_replace('public', '/storage', $facility->photo2);
        $facility->photo3 = str_replace('public', '/storage', $facility->photo3);
        $facility->photo4 = str_replace('public', '/storage', $facility->photo4);
        $facility->photo5 = str_replace('public', '/storage', $facility->photo5);
        $facility->photo6 = str_replace('public', '/storage', $facility->photo6);
        $data['facility_info'] = $facility;
        $data['kind'] = MstFacilityType::getData();
        $data['pref'] = MstPrefecture::getData();
        if(!empty($data['pref'])) {
            $pref = !empty($facility->address1) ? $facility->address1 : $data['pref'][0]['code'];
        }
        $user = Auth::user();
        $defaultPrefCode = $facility->address1 ?? array_get(array_first($data['pref']), 'code');

        if ($user->company_id === 1) {
            $city = MstCity::getData($defaultPrefCode, null, $user->company_id);
            $num = count($city);
            $data['city'] = $city;
        } else {
            $data['city'] = MstCity::getData($defaultPrefCode, null, $user->company_id);
        }

        $city = !empty($facility->address2) ? $facility->address2 : $data['city'][0]['code'];
        $data['town'] = '';
        if(isset($pref)){
            $data['town'] = MstTown::getData($pref, $city);
        }

        $all = $request->all();
        if ($user->company_id == 3){
            $data['user'] = $user;
            $data['staff_list'] = User::getData($user->company_id);
            return view('admin.pages.facility-edit-3', $data);
        }
        return view('admin.pages.facility-edit', $data);
    }


    private function saveImage($img, $path){
        $imageObject = \Image::make($img);
        $image = \Image::make($img)->exif();
        $org_height = $image['COMPUTED']['Height'] ?? $imageObject->height();
        $org_width = $image['COMPUTED']['Width'] ?? $imageObject->width();
        if ($org_height > $org_width) {
            $rate = config('const.MAX_LENGTH') / $org_height;
            $width = $org_width * $rate;
            $height = config('const.MAX_LENGTH');
        } else {
            $rate = config('const.MAX_LENGTH') / $org_width;
            $width = config('const.MAX_LENGTH');
            $height = $org_height * $rate;
        }
        $image = \Image::make($img);
        $image->orientate();
        $image->resize($width, null, function ($constraint) {
            return $constraint->aspectRatio();
        });
        $streamedImage = $image->stream();
        Storage::put($path, $streamedImage->__toString());
    }

    /**
     * 施設検索結果画面の表示
     * @return string
     */
    public function edit(Request $request, $id, CompanyApiService $apiService)
    {
        $URL = url('');
        $user = Auth::user();
        $all = $request->all();
        $all['company_id'] = $user->company_id;
        $unset_field = ['_token', 'file_path', 'file_single_input', 'del_img', 'scroll_list-address2', 'list-address2', 'list-address3', 'scroll_list-address3'];
        if($user->company_id == 3){
            if(isset($all['review'])){
                $review = 1;
            }
            $all['facility'] = $all['facility_other'];
            $unset_field1 = ['facility_other', 'file_path_photo1', 'del_photo1', 'file_path_photo2', 'del_photo2', 'file_path_photo3', 'del_photo3', 'file_path_photo4', 'del_photo4', 'file_path_photo5', 'del_photo5', 'file_path_photo6', 'del_photo6', 'review'];
            $unset_field = array_merge($unset_field, $unset_field1);
        }

        foreach ($unset_field as $field){
            unset($all[$field]);
        }

        $facility = Facility::findOrFail($id);

        Facility::where('id', $facility->id)->update($all);

        if (isset($request->file_single_input)) {
            $path = FileUtil::orientateImage($request->file_single_input, 'public/company_'.\auth()->user()->company_id.'/facility');
            Facility::where('id', $facility->id)->update(['file_path' => $path]);
            if($user->company_id == 1){
                $this->uploadRemoteMic($path);
            }
        } else if ($request->del_img == 1) {
            Facility::where('id', $facility->id)->update(['file_path' => null]);
        }
        if($user->company_id == 3) {
            for ($i = 1; $i <= 6; $i ++ ){
                if (isset($request['photo'.$i])) {
                    $path = FileUtil::orientateImage($request['photo'.$i], 'public/company_'.\auth()->user()->company_id.'/facility');
                    Facility::where('id', $facility->id)->update(['photo'.$i => $path]);
                    if ($user->company_id == 1) {
                        $this->uploadRemoteMic($path);
                    }
                } else if ($request['del_photo'.$i] == 1) {
                    Facility::where('id', $facility->id)->update(['photo'.$i => null]);
                }
            }
            if (isset($review)) {
                header('Location: /admin/facilityReview/' . $facility->id);
                die();
            }
        }

        $data_facility = Facility::where('id', $facility->id)->first();
        $apiService->editFacility($facility->id, $data_facility);

        $request->session()->flash('message', 'この施設を登録・保存しました。');
        return back();
    }

    public function delete($id, CompanyApiService $apiService)
    {
        Facility::where('id', $id)->delete();
        RelationArticleFacility::where('facility_id', '=', $id)->delete();
        $apiService->delFacility($id);
        return back();
    }
    public static function uploadRemoteMic($file_path)
    {
        $ar_folder = explode('/', $file_path);
        unset($ar_folder[count($ar_folder) - 1]);
        $folder = implode('/', $ar_folder);
        $folder = str_replace('public', 'storage', $folder);

        $url = env("URL_MIC_EXPORT", "");
        $path = storage_path("app".DIRECTORY_SEPARATOR.$file_path);
        try {
            $client = new Client(['verify' => false]);
            $r = $client->request('POST', $url, [
                'multipart' => [
                    [
                        'name'     => 'file_name',
                        'contents' => Psr7\Utils::tryFopen($path, 'r'),
                    ],
                    [
                        'name'     => 'folder',
                        'contents' => "/".$folder."/",
                    ],
                ]
            ]);

            $code = $r->getStatusCode();
            $body = $r->getBody();
            $remainingBytes = $body->getContents();
            //dd($remainingBytes);
        } catch (\Error $error) {
            var_dump($error);
        }
    }
    public function editReview(Request $request)
    {

        $data['active'] = 'regist';

        $data['facility_id'] = $request->id;

        $id = $request->id;

        $review = Review::getDataByFacility($id);

        foreach ($review as $i => $rv){
            $review[$i]['r_photo'] = str_replace('public', '/storage', $rv['r_photo']);
        }

        $data['reviews'] = $review;

        $user = Auth::user();


        $all = $request->all();
        $data['user'] = $user;

        return view('admin.pages.facility-review', $data);
    }
}
