<?php

namespace App\Controller\Campaign;

use App\Entity\Campaign\Hours;
use App\Form\Campaign\HoursType;
use App\Service\Campaign\HoursService;
use App\Service\CampaignService;
use App\Service\DataGrid\DataGrid;
use Doctrine\ORM\EntityNotFoundException;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View\View;
use Limenius\Liform\Liform;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class HoursController extends FOSRestController
{
    private $service;

    public function __construct(HoursService $service)
    {
        $this->service = $service;
    }

    /**
     * Retrieves a collection of Hours resource.
     *
     * @Rest\Get("/campaign/hours")
     * @Rest\View(serializerGroups={"grid"})
     *
     * @param Request         $request
     * @param CampaignService $campaignService
     *
     * @return View
     */
    public function getGridAction(Request $request, CampaignService $campaignService): View
    {
        $dataGrid = new DataGrid();

        try {
            $campaign = $campaignService->getCampaign($request->get('campaign'));
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }
        $date = $request->get('startOfTheMonth') ?? date('Y-m-d');

        $dataGrid->setData($this->service->getHours($campaign, $date));

        return View::create($dataGrid, Response::HTTP_OK);
    }

    /**
     * Retrieves an Hours resource.
     *
     * @Rest\Get("/campaign/hours/{id}", requirements={"id"="\d+"}))
     *
     * @param int $id
     *
     * @return View
     */
    public function getAction(int $id): View
    {
        try {
            $hours = $this->service->get($id);

            return View::create($hours, Response::HTTP_OK);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }
    }

    /**
     * Creates an Hours resource.
     *
     * @Rest\Post("/campaign/hours")
     *
     * @param Request $request
     *
     * @return View
     */
    public function postAction(Request $request): View
    {
        $form = $this->createForm(HoursType::class, null, ['csrf_protection' => false]);
        $form->submit($request->request->all());

        if ($form->isSubmitted() && $form->isValid()) {
            $hours = $this->service->save($form->getData());

            return View::create($hours, Response::HTTP_OK);
        }

        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Replaces Hours resource.
     *
     * @Rest\Put("/campaign/hours/{id}")
     *
     * @param Request $request
     * @param int     $id
     *
     * @return View
     */
    public function putAction(Request $request, int $id): View
    {
        try {
            $hours = $this->service->get($id);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(HoursType::class, $hours, ['csrf_protection' => false]);
        $form->submit($request->request->all());

        if ($form->isSubmitted() && $form->isValid()) {
            $hours = $this->service->save($form->getData());

            return View::create($hours, Response::HTTP_OK);
        }

        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Updates Hours resource.
     *
     * @Rest\Patch("/campaign/hours/{id}")
     *
     * @param Request $request
     * @param int     $id
     *
     * @return View
     */
    public function patchAction(Request $request, int $id): View
    {
        try {
            $hours = $this->service->get($id);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_NOT_FOUND, 'message' => $e->getMessage()], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(HoursType::class, $hours, ['csrf_protection' => false]);
        $form->submit($request->request->all(), false);

        if ($form->isSubmitted() && $form->isValid()) {
            $hours = $this->service->save($form->getData());

            return View::create($hours, Response::HTTP_OK);
        }

        return View::create($form, Response::HTTP_BAD_REQUEST);
    }

    /**
     * Removes the Hours resource.
     *
     * @Rest\Delete("/campaign/hours/{id}")
     *
     * @param int $id
     *
     * @return View
     */
    public function deleteAction(int $id): View
    {
        try {
            $hours = $this->service->get($id);
        } catch (EntityNotFoundException $e) {
            return View::create(['code' => Response::HTTP_BAD_REQUEST, 'message' => $e->getMessage()], Response::HTTP_BAD_REQUEST);
        }

        $this->service->delete($hours);

        return View::create([], Response::HTTP_NO_CONTENT);
    }

    /**
     * Return serialized form to create resource.
     *
     * @Rest\Get("/campaign/hours/schema")
     *
     * @param Liform $liform
     *
     * @return View
     */
    public function getSchemaAction(Liform $liform): View
    {
        $hours = new Hours();

        $form = $this->createForm(HoursType::class, $hours);

        $form = $liform->transform($form);

        return View::create($form, Response::HTTP_OK);
    }
}
