<?php

namespace App\Http\Controllers\Api;

use App\Filter;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\ValidationTrait;
use App\Http\Requests\Admin\StoreWishlistUserResidentalComsRequest;
use App\Http\Requests\Api\DeleteSubscribedItemsRequest;
use App\Http\Requests\Api\StoreFiltersRequest;
use App\Http\Requests\Api\SubscribeToDeveloperRequest;
use App\Http\Requests\Api\UpdateSubscribedToDeveloperRequest;
use App\Http\Requests\Api\UpdateSubscribedToRCRequest;
use App\Http\Requests\Api\UserSubscribedItemsRequest;
use App\Http\Resources\DeveloperCollection;
use App\Http\Resources\ResidentialComplexCollection;
use App\Http\Resources\UserWithlist\UserFilter;
use App\Repository\DeveloperRepository;
use App\Repository\ResidentialComplexRepository;
use App\Repository\WishListRepository;
use App\Services\WishListService;
use App\User;
use App\WishlistUserDeveloper;
use App\WishlistUserResidentalCom;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class UserWishlistController extends Controller
{
    const WISH_LIST_OFFSET_COUNT = 2;
    use ValidationTrait;
    /** @var WishListRepository */
    private $withListRepository;
    /** @var WishListService */
    private $wishListService;
    /** @var DeveloperRepository */
    public $developerRepository;
    /** @var ResidentialComplexRepository */
    public $residentialComplexesRepository;

    public function __construct(
        WishListRepository $wishListRepository,
        WishListService $wishListService,
        DeveloperRepository $developerRepository,
        ResidentialComplexRepository $residentialComplexRepository
    ) {
        $this->withListRepository = $wishListRepository;
        $this->wishListService = $wishListService;
        $this->developerRepository = $developerRepository;
        $this->residentialComplexesRepository = $residentialComplexRepository;
    }

    public function subscribeUserResidentialComplex(StoreWishlistUserResidentalComsRequest $request)
    {
        $user = Auth::user();
        try {
            $this->wishListService->subscribeUserResidentialComplex($request, $user);
        } catch (BadRequestHttpException $e) {
            return $this->getErrorResponse($e->getMessage());
        }

        return new JsonResponse(['data' => "Successful updated"]);
    }

    public function subscribeUserToDeveloper(SubscribeToDeveloperRequest $request)
    {
        $user = Auth::user();
        try {
            $this->wishListService->subscribeToDeveloper($request, $user);
        } catch (BadRequestHttpException $e) {
            return $this->getErrorResponse($e->getMessage());
        }

        return new JsonResponse(['data' => "Successful updated"]);
    }

    public function updateSubscribedUserResidentialComplex(UpdateSubscribedToRCRequest $request)
    {
        $residentialComplexes = $request->input('residential_complexes');
        $user = Auth::user();
        foreach ($residentialComplexes as $residentialComplex) {
            WishlistUserResidentalCom::updateOrCreate([
                'user_id' => $user->id,
                'residental_complex_id' => $residentialComplex
            ]);
        }

        return new JsonResponse(['data' => "data successfully updated"]);
    }

    public function updateSubscribedUserToDeveloper(UpdateSubscribedToDeveloperRequest $request)
    {
        $developers = $request->input('developers');
        $user = Auth::user();
        foreach ($developers as $developer) {
            WishlistUserDeveloper::updateOrCreate(['user_id' => $user->id, 'developer_id' => $developer]);
        }

        return new JsonResponse(['data' => "Data successfully updated"]);
    }

    public function listSubscribedUserResidentialComplex(UpdateSubscribedToRCRequest $request)
    {
        $user = auth('api')->user();
        $residentialComplexes = $request->input('residential_complexes');
        $page = $request->input('page');
        if ($user) {
            $residentialComplexes = WishlistUserResidentalCom::query()
                ->where('user_id', $user->id)->get()->map(function ($residentialComplex) {
                    return $residentialComplex->residental_complex_id;
                });
            $listOfResidentialComplexes = $this->residentialComplexesRepository->listResidentialComplex([
                'wishList_user' => $user->id,
                'wishList_page' => $page
            ], false);
        } else {
            $listOfResidentialComplexes = $this->residentialComplexesRepository->listResidentialComplex([
                'residential_complex_ids' => $residentialComplexes,
                'wishList_page' => $page
            ]);
        }

        return [
            'data' => new ResidentialComplexCollection($listOfResidentialComplexes),
            'count' => count($residentialComplexes)
        ];
    }

    public function listSubscribedUserToDeveloper(UpdateSubscribedToDeveloperRequest $request)
    {
        $user = auth('api')->user();
        $developers = $request->input('developers');
        $page = $request->input('page');
        if ($user) {
            $developers = WishlistUserDeveloper::query()->where('user_id', $user->id)->get()->map(function ($developer
            ) {
                return $developer->developer_id;
            });
            $listOfDevelopers = $this->developerRepository->find([
                'wishList_user' => $user->id,
                'wishList_page' => $page
            ]);
        } else {
            $listOfDevelopers = $this->developerRepository->find([
                'developer_ids' => $developers,
                'wishList_page' => $page
            ]);
        }

        return [
            'data' => new DeveloperCollection($listOfDevelopers, ['statistic' => true, 'residential_complex' => true]),
            'count' => count($developers)
        ];
    }

    public function storeUserFilter(StoreFiltersRequest $request)
    {
        $parameters = $request->input("parameters");
        $user = Auth::user();
        foreach ($parameters as $parameter) {
            $filter = Filter::create([
                'parameters' => $parameter,
                'user_id' => $user->id
            ]);
        }

        return new JsonResponse(['data' => "Parameters stored successfully"]);
    }

    public function showUserFilter(Request $request)
    {
        $page = $request->input('page');
        /** @var User $user */
        $user = Auth::user();
        $filters = Filter::query()->where('user_id',
                $user->id)//            ->when($page, function ($query) use ($page) {
//                $query->skip($page * self::WISH_LIST_OFFSET_COUNT)->
//                take(self::WISH_LIST_OFFSET_COUNT);
//            })
            ->get();

        return ["data" => UserFilter::collection($filters)];
    }

    public function showUserSubscribedItemIds(UserSubscribedItemsRequest $request)
    {
        $user = Auth::user();
        $item = $request->input('item');
        if ($item == "residential_complex") {
            $residentialComplexes = WishlistUserResidentalCom::query()
                ->where('user_id', $user->id)->get()->map(function ($residentialComplex) {
                    return $residentialComplex->residental_complex_id;
                });

            return new JsonResponse(['data' => $residentialComplexes]);
        } else {
            $developerIds = WishlistUserDeveloper::query()->where('user_id', $user->id)->get()->map(function ($developer
            ) {
                return $developer->developer_id;
            });

            return new JsonResponse(['data' => $developerIds]);
        }
    }

    public function deleteUserFilter($id)
    {
        /** @var User $user */
        $user = Auth::user();
        if (!$filter = Filter::query()->where('user_id', $user->id)->where('id', $id)->first()) {
            return $this->getErrorResponse('user filter was not found');
        }
        $filter->forceDelete();

        return new JsonResponse(['filter was deleted']);
    }

    public function deleteSubscribedItems(DeleteSubscribedItemsRequest $request)
    {
        $user = Auth::user();
        $item = $request->input('item');
        if ($item == "residential_complex") {
            $residentialComplexes = WishlistUserResidentalCom::query()->where('user_id', $user->id)->get();
            foreach ($residentialComplexes as $residentialComplex) {
                $residentialComplex->forceDelete();
            }

            return new JsonResponse(['data' => 'deleted successfully']);
        } elseif ($item == "developer") {
            $userDevelopers = WishlistUserDeveloper::query()->where('user_id', $user->id)->get();
            foreach ($userDevelopers as $userDeveloper) {
                $userDeveloper->forceDelete();
            }

            return new JsonResponse(['data' => 'deleted successfully']);
        } elseif ($item == "filter") {
            $userFilters = Filter::query()->where('user_id', $user->id)->get();
            foreach ($userFilters as $userFilter) {
                $userFilter->forceDelete();
            }

            return new JsonResponse(['data' => 'deleted successfully']);
        }

        return new JsonResponse(["Bad request"], 400);
    }
}
