<?php

namespace App\Http\Controllers\Admin;

use App\Currency;
use App\Helpers\ImageSize;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\FileUploadTrait;
use App\Http\Requests\Admin\StoreResidentialComplexesRequest;
use App\Http\Requests\Admin\UpdateResidentialComplexesRequest;
use App\Http\Resources\ResidentialComplexPlanningPrice;
use App\Http\Resources\ResidentialComplexPrice;
use App\Price;
use App\Repository\PlanningPriceRepository;
use App\Repository\PriceRepository;
use App\Repository\ResidentialComplexRepository;
use App\ResidentialComplex;
use App\Services\ResidentialComplexPlanningPriceGenerator;
use App\Services\ResidentialComplexPriceGenerator;
use App\Services\ResidentialComplexService;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Gate;
use App\Http\Resources\ResidentialComplex as ResidentialComplexResource;

class ResidentialComplexesController extends Controller
{
    use FileUploadTrait;
    /** @var ResidentialComplexService */
    public $residentialComplexService;
    /** @var ResidentialComplexRepository */
    public $residentialComplexRepository;

    public function __construct(
        ResidentialComplexRepository $residentialComplexRepository,
        ResidentialComplexService $residentialComplexService
    ) {
        $this->residentialComplexRepository = $residentialComplexRepository;
        $this->residentialComplexService = $residentialComplexService;
    }

    /**
     * Display a listing of ResidentialComplex.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        if (!Gate::allows('residential_complex_access')) {
            return abort(401);
        }
        $residental_complex_id = $request->query->get('residental_complex_id');
        if (request('show_deleted') == 1) {
            if (!Gate::allows('residential_complex_delete')) {
                return abort(401);
            }
            $residential_complexes = ResidentialComplex::onlyTrashed()->get();
        } else {
            if (!empty($residental_complex_id)) {
                $residential_complexes = ResidentialComplex::where("id", $residental_complex_id)->get();
            } else {
                $residential_complexes = ResidentialComplex::paginate(15);
            }
        }
        $residential_complexes_pluck = ResidentialComplex::get()->pluck('name',
            'id')->prepend(trans('quickadmin.qa_residential_complex_filter'), '');

        return view('admin.residential_complexes.index',
            compact('residential_complexes', 'residential_complexes', 'residential_complexes_pluck',
                'residental_complex_id'));
    }

    /**
     * Show the form for creating new ResidentialComplex.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        if (!Gate::allows('residential_complex_create')) {
            return abort(401);
        }

        $developers = \App\Developer::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $count_of_room_per_flats = \App\RoomCount::get()->pluck('count', 'id');
        $room_types = \App\RoomType::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');;
        $cities = \App\City::query()->whereEnabled(true)->get()->pluck('name',
            'id')->prepend(trans('quickadmin.qa_please_select'), '');
//        $districts = \App\District::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $districts = ['' => trans('quickadmin.qa_please_select')];
        $street_names = \App\StreetName::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $classes = \App\ClassHousing::get()->pluck('name', 'id');
        $stage_of_constructions = \App\StageOfConstruction::get()->pluck('name', 'id');
        $heatings = \App\Heating::get()->pluck('name', 'id');
        $technology_buildings = \App\TechnologyBuilding::get()->pluck('name', 'id');
        $other_options = \App\OtherOption::get()->pluck('name', 'id');
        $icons = \App\ResidentalComplexIcon::get()->pluck('name', 'id');
        $recomended_residental_complex_ids = \App\ResidentialComplex::get()->pluck('name', 'id');
        $banks = \App\Bank::get()->pluck('name', 'id');
        $quarterly = \App\Quarterly::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');

//        $sections = \App\Section::get()->pluck('section_name', 'id')
//            ->prepend(trans('quickadmin.qa_please_select_general'), '');

        $sections = collect([trans('quickadmin.qa_please_select_general')]);
        $sectionsPlanning = collect([trans('quickadmin.qa_please_select_general')]);

        return view('admin.residential_complexes.create',
            compact('developers', 'count_of_room_per_flats', 'room_types', 'cities', 'districts', 'street_names',
                'classes', 'stage_of_constructions', 'heatings', 'technology_buildings', 'other_options', 'icons',
                'recomended_residental_complex_ids', 'banks', 'quarterly', 'sections', 'sectionsPlanning'));
    }

    /**
     * Store a newly created ResidentialComplex in storage.
     *
     * @param  StoreResidentialComplexesRequest $request
     * @return Response
     */
    public function store(StoreResidentialComplexesRequest $request)
    {
        if (!Gate::allows('residential_complex_create')) {
            return abort(401);
        }

        $request = $this->saveFiles($request, [ImageSize::PRESENTATION => true]);
        $residential_complex = ResidentialComplex::create($request->all());
        $residential_complex->count_of_room_per_flat()
            ->sync(array_filter((array)$request->input('count_of_room_per_flat')));
        $residential_complex->room_type()->sync(array_filter((array)$request->input('room_type')));
        $residential_complex->class()->sync(array_filter((array)$request->input('class')));
        $residential_complex->heating()->sync(array_filter((array)$request->input('heating')));
        $residential_complex->technology_building()->sync(array_filter((array)$request->input('technology_building')));
        $residential_complex->other_option()->sync(array_filter((array)$request->input('other_option')));
        $residential_complex->icon()->sync(array_filter((array)$request->input('icon')));
        $residential_complex->recomended_residental_complex_id()
            ->sync(array_filter((array)$request->input('recomended_residental_complex_id')));
        $residential_complex->bank()->sync(array_filter((array)$request->input('bank')));

        foreach ($request->input('residential_complex_characters', []) as $data) {
            $residential_complex->residential_complex_characters()->create($data);
        }

        foreach ($request->input('prices', []) as $data) {
            $residential_complex->prices()->create($data);
        }

        foreach ($request->input('planning_prices', []) as $data) {
            $residential_complex->planning_prices()->create($data);
        }

        foreach ($request->input('terms_of_payments', []) as $data) {
            $residential_complex->term_of_paymentes()->create($data);
        }

        foreach ($request->input('residential_complex_seos', []) as $data) {
            $residential_complex->residential_complex_seos()->create($data);
        }

        foreach ($request->input('photo_id', []) as $index => $id) {
            $model = config('medialibrary.media_model');
            $file = $model::find($id);
            $file->model_id = $residential_complex->id;
            $file->save();
        }
        foreach ($request->input('landscape_photo_id', []) as $index => $id) {
            $model = config('medialibrary.media_model');
            $file = $model::find($id);
            $file->model_id = $residential_complex->id;
            $file->save();
        }

        $this->residentialComplexService->setDistance($residential_complex, $request);

        return redirect()->route('admin.residential_complexes.index');
    }

    /**
     * Show the form for editing ResidentialComplex.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        if (!Gate::allows('residential_complex_edit')) {
            return abort(401);
        }

        $residential_complex = ResidentialComplex::findOrFail($id);
        $developers = \App\Developer::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $count_of_room_per_flats = \App\RoomCount::get()->pluck('count', 'id');
        $room_types = \App\RoomType::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');;

        $cities = \App\City::query()->whereEnabled(true)->get()->pluck('name',
            'id')->prepend(trans('quickadmin.qa_please_select'), '');
        if ($residential_complex->city) {
            $districts = \App\District::where('city_id', $residential_complex->city->id)->get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        } else {
            $districts = ['' => trans('quickadmin.qa_please_select')];
        }

        $street_names = \App\StreetName::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $classes = \App\ClassHousing::get()->pluck('name', 'id');
        $stage_of_constructions = \App\StageOfConstruction::get()->pluck('name', 'id');
        $heatings = \App\Heating::get()->pluck('name', 'id');
        $technology_buildings = \App\TechnologyBuilding::get()->pluck('name', 'id');
        $other_options = \App\OtherOption::get()->pluck('name', 'id');
        $icons = \App\ResidentalComplexIcon::get()->pluck('name', 'id');
        $recomended_residental_complex_ids = \App\ResidentialComplex::get()->pluck('name', 'id');
        $banks = \App\Bank::get()->pluck('name', 'id');
        $quarterly = \App\Quarterly::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');

        $sections = \App\Section::query()
            ->where('residental_complex_id', $id)->get()
            ->where('is_pricing', 1)
            ->pluck('section_name', 'id')->prepend(trans('quickadmin.qa_please_select_general'), '');

        $sectionsPlanning = \App\Section::query()
            ->where('residental_complex_id', $id)->get()
            ->pluck('section_name', 'id')->prepend(trans('quickadmin.qa_please_select_general'), '');

        return view('admin.residential_complexes.edit',
            compact('residential_complex', 'developers', 'count_of_room_per_flats', 'room_types', 'cities', 'districts',
                'street_names', 'classes', 'stage_of_constructions', 'heatings', 'technology_buildings',
                'other_options', 'icons', 'recomended_residental_complex_ids', 'banks', 'quarterly', 'sections', 'sectionsPlanning'));
    }

    /**
     * Update ResidentialComplex in storage.
     *
     * @param  UpdateResidentialComplexesRequest $request
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateResidentialComplexesRequest $request, $id)
    {
        if (!Gate::allows('residential_complex_edit')) {
            return abort(401);
        }
        $request = $this->saveFiles($request, [ImageSize::PRESENTATION => true]);
        /** @var ResidentialComplex $residential_complex */
        $residential_complex = ResidentialComplex::findOrFail($id);
        $residential_complex->update($request->all());
        $residential_complex->count_of_room_per_flat()->sync(array_filter((array)$request->input('count_of_room_per_flat')));
        $residential_complex->room_type()->sync(array_filter((array)$request->input('room_type')));
        $residential_complex->class()->sync(array_filter((array)$request->input('class')));
        $residential_complex->heating()->sync(array_filter((array)$request->input('heating')));
        $residential_complex->technology_building()->sync(array_filter((array)$request->input('technology_building')));
        $residential_complex->other_option()->sync(array_filter((array)$request->input('other_option')));
        $residential_complex->icon()->sync(array_filter((array)$request->input('icon')));
        $residential_complex->recomended_residental_complex_id()->sync(array_filter((array)$request->input('recomended_residental_complex_id')));
        $residential_complex->bank()->sync(array_filter((array)$request->input('bank')));


        $planningPrices = $residential_complex->planning_prices;
        $currentPlanningPriceData = [];
        foreach ($request->input('planning_prices', []) as $index => $data) {
            if (is_integer($index)) {
                $residential_complex->planning_prices()->create($data);
            } else {
                $id = explode('-', $index)[1];
                $currentPlanningPriceData[$id] = $data;
            }
        }
        foreach ($planningPrices as $item) {
            if (isset($currentPlanningPriceData[$item->id])) {
                $item->update($currentPlanningPriceData[$item->id]);
            } else {
                $item->forceDelete();
            }
        }

        $prices = $residential_complex->prices;
        $currentPriceData = [];
        foreach ($request->input('prices', []) as $index => $data) {
            if (is_integer($index)) {
                $residential_complex->prices()->create($data);
            } else {
                $id = explode('-', $index)[1];
                $currentPriceData[$id] = $data;
            }
        }
        foreach ($prices as $item) {
            if (isset($currentPriceData[$item->id])) {
                $item->update($currentPriceData[$item->id]);
            } else {
                $item->forceDelete();
            }
        }

        $termsOfPayments = $residential_complex->term_of_paymentes;
        $currentTermsOfPaymentsData = [];
        foreach ($request->input('terms_of_payments', []) as $index => $data) {
            if (is_integer($index)) {
                $residential_complex->term_of_paymentes()->create($data);
            } else {
                $id = explode('-', $index)[1];
                $currentTermsOfPaymentsData[$id] = $data;
            }
        }
        foreach ($termsOfPayments as $item) {
            if (isset($currentTermsOfPaymentsData[$item->id])) {
                $item->update($currentTermsOfPaymentsData[$item->id]);
            } else {
                $item->forceDelete();
            }
        }

        $residentialComplexCharacters = $residential_complex->residential_complex_characters;
        $currentResidentialComplexCharacterData = [];
        foreach ($request->input('residential_complex_characters', []) as $index => $data) {
            if (is_integer($index)) {
                $residential_complex->residential_complex_characters()->create($data);
            } else {
                $id = explode('-', $index)[1];
                $currentResidentialComplexCharacterData[$id] = $data;
            }
        }
        foreach ($residentialComplexCharacters as $item) {
            if (isset($currentResidentialComplexCharacterData[$item->id])) {
                $item->update($currentResidentialComplexCharacterData[$item->id]);
            } else {
                $item->forceDelete();
            }
        }
        $residentialComplexSeos = $residential_complex->residential_complex_seos;
        $currentResidentialComplexSeoData = [];
        foreach ($request->input('residential_complex_seos', []) as $index => $data) {
            if (is_integer($index)) {
                $residential_complex->residential_complex_seos()->create($data);
            } else {
                $id = explode('-', $index)[1];
                $currentResidentialComplexSeoData[$id] = $data;
            }
        }
        foreach ($residentialComplexSeos as $item) {
            if (isset($currentResidentialComplexSeoData[$item->id])) {
                $item->update($currentResidentialComplexSeoData[$item->id]);
            } else {
                $item->forceDelete();
            }
        }
        $media = [];
        foreach ($request->input('photo_id', []) as $index => $id) {
            $model = config('medialibrary.media_model');
            $file = $model::find($id);
            $file->model_id = $residential_complex->id;
            $file->save();
            $media[] = $file->toArray();
        }
        $residential_complex->updateMedia($media, 'photo');
        $media = [];
        foreach ($request->input('landscape_photo_id', []) as $index => $id) {
            $model = config('medialibrary.media_model');
            $file = $model::find($id);
            $file->model_id = $residential_complex->id;
            $file->save();
            $media[] = $file->toArray();
        }
        $residential_complex->updateMedia($media, 'landscape_photo');
        $this->residentialComplexService->setDistance($residential_complex, $request);

        return redirect()->route('admin.residential_complexes.index');
    }

    /**
     * Display ResidentialComplex.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        if (!Gate::allows('residential_complex_view')) {
            return abort(401);
        }
        $developers = \App\Developer::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $count_of_room_per_flats = \App\RoomCount::get()->pluck('count', 'id');
        $room_types = \App\RoomType::get()->pluck('name', 'id');
        $cities = \App\City::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $districts = \App\District::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $street_names = \App\StreetName::get()->pluck('name', 'id')->prepend(trans('quickadmin.qa_please_select'), '');
        $classes = \App\ClassHousing::get()->pluck('name', 'id');
        $stage_of_constructions = \App\StageOfConstruction::get()->pluck('name', 'id');
        $heatings = \App\Heating::get()->pluck('name', 'id');
        $technology_buildings = \App\TechnologyBuilding::get()->pluck('name', 'id');
        $other_options = \App\OtherOption::get()->pluck('name', 'id');
        $icons = \App\ResidentalComplexIcon::get()->pluck('name', 'id');
        $recomended_residental_complex_ids = \App\ResidentialComplex::get()->pluck('name', 'id');
        $wishlist_user_residental_coms = \App\WishlistUserResidentalCom::where('residental_complex_id', $id)->get();
        $residential_complex_characters = \App\ResidentialComplexCharacter::where('residental_complex_id', $id)->get();
        $course_of_constructions = \App\CourseOfConstruction::where('residental_complex_id', $id)->get();
        $promotions = \App\Promotion::where('residental_complex_id', $id)->get();
        $customer_ratings = \App\CustomerRating::where('residental_complex_id', $id)->get();
        $secret_buyer_ratings = \App\SecretBuyerRating::where('residental_complex_id', $id)->get();
        $documents = \App\Document::where('residental_complex_id', $id)->get();
        $sections = \App\Section::where('residental_complex_id', $id)->get();
        $secret_buyer_ratings = \App\SecretBuyerRating::where('residental_complex_id', $id)->get();
        $residential_complexes = \App\ResidentialComplex::whereHas('recomended_residental_complex_id',
            function ($query) use ($id) {
                $query->where('id', $id);
            })->get();
        $residential_complex = ResidentialComplex::findOrFail($id);

        return view('admin.residential_complexes.show',
            compact('residential_complex', 'wishlist_user_residental_coms', 'residential_complex_characters',
                'course_of_constructions', 'promotions', 'customer_ratings', 'secret_buyer_ratings', 'documents',
                'sections', 'secret_buyer_ratings', 'residential_complexes'));
    }

    /**
     * Remove ResidentialComplex from storage.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if (!Gate::allows('residential_complex_delete')) {
            return abort(401);
        }
        $residential_complex = ResidentialComplex::findOrFail($id);
        $residential_complex->deletePreservingMedia();

        return redirect()->route('admin.residential_complexes.index');
    }

    /**
     * Delete all selected ResidentialComplex at once.
     *
     * @param Request $request
     */
    public function massDestroy(Request $request)
    {
        if (!Gate::allows('residential_complex_delete')) {
            return abort(401);
        }
        if ($request->input('ids')) {
            $entries = ResidentialComplex::whereIn('id', $request->input('ids'))->get();
            foreach ($entries as $entry) {
                $entry->deletePreservingMedia();
            }
        }
    }

    /**
     * Restore ResidentialComplex from storage.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function restore($id)
    {
        if (!Gate::allows('residential_complex_delete')) {
            return abort(401);
        }
        $residential_complex = ResidentialComplex::onlyTrashed()->findOrFail($id);
        $residential_complex->restore();

        return redirect()->route('admin.residential_complexes.index');
    }

    /**
     * Permanently delete ResidentialComplex from storage.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function perma_del($id)
    {
        if (!Gate::allows('residential_complex_delete')) {
            return abort(401);
        }
        $residential_complex = ResidentialComplex::onlyTrashed()->findOrFail($id);
        $residential_complex->forceDelete();

        return redirect()->route('admin.residential_complexes.index');
    }

    public function generatePrices(Request $request, $id, ResidentialComplexPriceGenerator $residentialComplexPriceGenerator)
    {
        $residentialComplex = ResidentialComplex::find($id);

        $parameters = [
            'show_residential_complex' => true,
            'residential_complex_slug' => $residentialComplex->code
        ];

        try {
            /** @var ResidentialComplex $residentialComplex */
            $residentialComplexResource = $this->residentialComplexRepository->priceGenerator($parameters);

            $resource = new ResidentialComplexPrice($residentialComplexResource->first(), $parameters);

            $response = $resource->response();
            $responseData = $response->getContent();
            $data = json_decode($responseData, true, 512, JSON_UNESCAPED_UNICODE);

            $fullData = $data['data'];

            $planningStatistic = $fullData['flats_statistic'];
            $prices = $fullData['pricing'];

            $residentialComplexPriceGenerator->compareGeneralPrice($planningStatistic, $prices, $residentialComplex);
            $residentialComplexPriceGenerator->compareSectionPrice($planningStatistic, $prices, $residentialComplex);
        } catch (\Exception $e) {

        } finally {
            return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
        }

        return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
    }

    public function generateGeneralPrices(Request $request, $id, ResidentialComplexPriceGenerator $residentialComplexPriceGenerator)
    {
        $residentialComplex = ResidentialComplex::find($id);

        $parameters = [
            'show_residential_complex' => true,
            'residential_complex_slug' => $residentialComplex->code
        ];

        try {
            /** @var ResidentialComplex $residentialComplex */
            $residentialComplexResource = $this->residentialComplexRepository->priceGenerator($parameters);

            $residentialComplexPriceGeneral = (new PriceRepository())->generalPrice($id);
            foreach ($residentialComplexPriceGeneral as $residentialComplexPriceGeneralItem) {
                $residentialComplexPriceGeneralItem->forceDelete();
//                $residentialComplexPriceGeneralItem->delete();
            }

            request()->headers->set('Currency', Currency::USD);
            $resource = new ResidentialComplexPrice($residentialComplexResource->first(), $parameters);

            $response = $resource->response();
            $responseData = $response->getContent();
            $data = json_decode($responseData, true, 512, JSON_UNESCAPED_UNICODE);
            $fullData = $data['data'];
            $prices = $fullData['pricing'];

            $filteredPrices = $residentialComplexPriceGenerator->generateGeneralPrice($prices);
            $residentialComplexPriceGenerator->createGeneralPrice($filteredPrices, $residentialComplex);

        } catch (\Exception $e) {
        } finally {
            return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
        }

        return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
    }

    public function generateGeneralPlanningPrices(Request $request, $id, ResidentialComplexPlanningPriceGenerator $residentialComplexPlanningPriceGenerator)
    {
        $residentialComplex = ResidentialComplex::find($id);

        $parameters = [
            'show_residential_complex' => true,
            'residential_complex_slug' => $residentialComplex->code
        ];

        try {
            /** @var ResidentialComplex $residentialComplex */
            $residentialComplexResource = $this->residentialComplexRepository->priceGenerator($parameters);

            $residentialComplexPriceGeneral = (new PlanningPriceRepository())->generalPrice($id);
            foreach ($residentialComplexPriceGeneral as $residentialComplexPriceGeneralItem) {
                $residentialComplexPriceGeneralItem->forceDelete();
//                $residentialComplexPriceGeneralItem->delete();
            }

            request()->headers->set('Currency', Currency::USD);
            $resource = new ResidentialComplexPlanningPrice($residentialComplexResource->first(), $parameters);

            $response = $resource->response();
            $responseData = $response->getContent();

            $data = json_decode($responseData, true, 512, JSON_UNESCAPED_UNICODE);

            $fullData = $data['data'];
            $prices = $fullData['pricing'];

            $filteredPrices = $residentialComplexPlanningPriceGenerator->generateGeneralPrice($prices);

            $residentialComplexPlanningPriceGenerator->createGeneralPrice($filteredPrices, $residentialComplex);

        } catch (\Exception $e) {

        } finally {
            return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
        }

        return redirect()->route('admin.residential_complexes.edit',['residential_complex' => $id]);
    }
}
