<?php

namespace App\Controller\Api;

use App\Enum\Role;
use App\Entity\Size;
use App\Entity\Restaurant;
use App\Entity\UserAddress;
use App\Request\Response200;
use App\Request\Response422;
use OpenApi\Annotations as OA;
use App\Entity\RestaurantCategory;
use App\Request\Response200Message;
use App\Controller\Api\ApiController;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
use Symfony\Component\HttpFoundation\Request;
use App\Request\UserAddress\RequestAddAddress;
use Symfony\Component\HttpFoundation\Response;
use App\Request\Restaurant\RequestShowRestaurant;
use FOS\RestBundle\Controller\Annotations as Rest;
use App\Request\RestaurantType\RequestListRestaurantType;

use Symfony\Component\Validator\Validator\ValidatorInterface;

class RestaurantTypeController extends ApiController implements Role
{
    /**
     * List restaurant type / category
     *
     * @Rest\Get("/api/public/type/restaurant", name="api_restaurant_type_list")
     * @OA\Tag(name="restaurant type")
     * @OA\Response(
     *     response=200,
     *     description="Ok response",
     *     @Model(type=Response200::class)
     * )
     * @OA\Response(
     *     response=422,
     *     description="Error response",
     *     @Model(type=Response422::class)
     * )
     * @OA\RequestBody(
     *       @OA\MediaType(
     *           mediaType="multipart/form-data",
     *           @OA\Schema(ref=@Model(type=RequestListRestaurantType::class))
     *      )
     * )
     *
     * @param ValidatorInterface $validator
     * @param Request $request
     * @return Response
     */
    public function list (Request $request, ValidatorInterface $validator): Response
    {
        if ($request->get('key') !== $_ENV['KEY_API_PUBLIC']) {
            $response = [
                'status' => Response::HTTP_UNAUTHORIZED,
                'error'  => false,
                'data'   => null
            ];
            return $this->sendResponse($response);
        }

        $errors = $validator->validate(
                new RequestListRestaurantType($request)
        );
        if (count($errors) > 0)
        {
            return $this->respondValidationError($errors);
        }

        $data = $this->getDoctrine()
            ->getRepository(RestaurantCategory::class)
            ->ListAllActive()
        ;

        $response = [
            'status' => $data ? Response::HTTP_OK : Response::HTTP_NOT_FOUND,
            'error'  => !is_array($data) ? true : false,
            'data'   => $data,
        ];
        return $this->sendResponse($response);
    }

    /**
     * Add address
     *
     * @Rest\Post("/api/address", name="api_address_add")
     * @Security(name="Bearer")
     * @OA\Tag(name="address")
     * @OA\Response(
     *     response=200,
     *     description="Ok response",
     *     @Model(type=Response200Message::class)
     * )
     * @OA\Response(
     *     response=422,
     *     description="Error response",
     *     @Model(type=Response422::class)
     * )
     * @OA\RequestBody(
     *       @OA\MediaType(
     *           mediaType="multipart/form-data",
     *           @OA\Schema(ref=@Model(type=RequestAddAddress::class))
     *      )
     * )
     *
     * @param Request $request
     * @param ValidatorInterface $validator
     *
     * @return Response
     */
    public function add(Request $request, ValidatorInterface $validator): Response
    {
        $errors = $validator->validate(
                new RequestAddAddress($request)
        );
        if (count($errors) > 0)
        {
            return $this->respondValidationError($errors);
        }

        $entity = new UserAddress();
        $entity
            ->setName($request->get('name'))
            ->setPostalCode($request->get('postalCode'))
            ->setApartment($request->get('apartment'))
            ->setHouseNumber($request->get('houseNumber'))
            ->setStreet($request->get('street'))
            ->setLatitude($request->get('latitude'))
            ->setLongitude($request->get('longitude'))
            ->setUser($this->getUser())
        ;

        $this->em->persist($entity);
        $this->em->flush();

        return $this->respondWithSuccess(sprintf($this->trans('general.successfullRegistration'), $entity->getId()));
    }

    /**
     * Show Restaurant detail
     *
     * @Rest\Get("/api/public/restaurant/{id}", name="api_restaurant_show")
     * @OA\Tag(name="restaurant")
     * @OA\Response(
     *     response=200,
     *     description="Ok response",
     *     @Model(type=Response200::class)
     * )
     * @OA\Response(
     *     response=422,
     *     description="Error response",
     *     @Model(type=Response422::class)
     * )
     *
     * @param idResurant $id
     * @param Request $request
     * @param ValidatorInterface $validator
     *
     * @return Response
     */
    public function showRestaurant($id, Request $request, ValidatorInterface $validator): Response
    {
        if ($request->get('key') !== $_ENV['KEY_API_PUBLIC']) {
            $response = [
                'status' => Response::HTTP_UNAUTHORIZED,
                'error'  => false,
                'data'   => null
            ];
            return $this->sendResponse($response);
        }

        $errors = $validator->validate(
                new RequestShowRestaurant($request)
        );
        if (count($errors) > 0)
        {
            return $this->respondValidationError($errors);
        }

        $data = $this->getDoctrine()
            ->getRepository(Restaurant::class)
            ->showRestaurantApi($id)
        ;

        foreach ($data as &$valor) {
            if ((bool)$valor['haveSize']) {
                $sizeData = $this->getDoctrine()
                    ->getRepository(Size::class)
                    ->getSize($valor['id'])
                ;
                $valor['size'] = $sizeData;
            } else {
                $valor['size'] = [];
            }
        }

        /*
        foreach ($data as &$valor) {
            if ((bool)$valor['haveExtra']) {
                $sizeData = $this->getDoctrine()
                    ->getRepository(Extra::class)
                    ->getExtra($valor['id'])
                ;
                $valor['extra'] = $sizeData;
            } else {
                $valor['extra'] = [];
            }
        }
        */
        $dataRestaurant = $this->getDoctrine()
            ->getRepository(Restaurant::class)
            ->find($id)
        ;

        $response = [
            'status' => $data ? Response::HTTP_OK : Response::HTTP_NOT_FOUND,
            'error'  => !is_array($data) ? true : false,
            'data'   => [
                'restaurant'    => [
                    'id'    => $dataRestaurant->getId(),
                    'name'  => $dataRestaurant->getName(),
                    'image' => $dataRestaurant->getImage(),
                ],
                'menu'          => $data
            ],
        ];
        return $this->sendResponse($response);
    }

}
